github.com/resonatecoop/id@v1.1.0-43/frontend/src/components/password-meter/index.js (about)

     1  const html = require('choo/html')
     2  const Component = require('choo/component')
     3  const zxcvbnAsync = require('zxcvbn-async')
     4  
     5  // Password meter component class
     6  class PasswordMeter extends Component {
     7    /***
     8     * Create a password meter component
     9     * @param {string} id - The password meter component id (unique)
    10     * @param {number} state - The choo app state
    11     * @param {function} emit - Emit event on choo app
    12     */
    13    constructor (id, state, emit) {
    14      super(id)
    15  
    16      this.emit = emit
    17      this.state = state
    18  
    19      this.local = state.components[id] = {}
    20    }
    21  
    22    /***
    23     * Create password meter component element
    24     * @param {Object} props - The password meter component props
    25     * @param {String} props.password - The password
    26     * @returns {HTMLElement}
    27     */
    28    createElement (props) {
    29      this.local.password = props.password
    30  
    31      const score = this.getScore(this.local.password)
    32      const meter = [0, 1, 2, 3, 4] // zxcvbn score meter
    33  
    34      return html`
    35        <div class="flex flex-column">
    36          <div class="flex">
    37            ${this.local.password
    38              ? meter.map((n) => {
    39                const colors = [
    40                  'dark-red',
    41                  'red',
    42                  'orange',
    43                  'green',
    44                  'dark-green'
    45                ]
    46                const color = n <= score ? colors[score] : 'gray'
    47  
    48                return html`
    49                  <div style="height:3px" class="flex-auto w-100 bg-${color}"></div>
    50                `
    51              })
    52              : ''
    53            }
    54          </div>
    55        </div>
    56      `
    57    }
    58  
    59    /***
    60     * @description Get zxcvbn score for password
    61     * @param {String} password - The password
    62     * @returns {Number} The zxcvbn score
    63     */
    64    getScore (password) {
    65      if (!password) return 0
    66  
    67      const zxcvbn = zxcvbnAsync.load({
    68        sync: true,
    69        libUrl: 'https://cdn.jsdelivr.net/npm/zxcvbn@4.4.2/dist/zxcvbn.js',
    70        libIntegrity: 'sha256-9CxlH0BQastrZiSQ8zjdR6WVHTMSA5xKuP5QkEhPNRo='
    71      })
    72      const { score } = zxcvbn(this.local.password || '')
    73      return score
    74    }
    75  
    76    /***
    77     * Password meter component on update event handler
    78     * @param {Object} props - Password meter component props
    79     * @returns {Boolean} Should update
    80     */
    81    update (props) {
    82      return props.password !== this.local.password
    83    }
    84  }
    85  
    86  module.exports = PasswordMeter