UNPKG

ldx-widgets

Version:

widgets

181 lines (145 loc) 4.68 kB
React = require 'react' _ = require 'lodash' owasp = require 'owasp-password-strength-test' TextInput = React.createFactory(require './text_input') {ENTER} = require '../constants/keyboard' {div, li, h4, ul, span} = React.DOM MIN_PASSWORD_LENGTH = 6 MAX_PASSWORD_LENGTH = 15 REMOVED_REQUIREMENTS = [2, 6] PasswordInput = React.createClass displayName: 'PasswordInput' propTypes: onChange: React.PropTypes.func getInitialState: -> owasp.config minLength: MIN_PASSWORD_LENGTH maxLength: MAX_PASSWORD_LENGTH isPassphrase: false test = owasp.test('') return { passwordTest: test passwordRequirements: @buildTestRequirements(test) currentPassword: null confirmPassword: null } getDefaultProps: -> onChange: -> isValid: -> current = @refs.input.getValue() confirm = @refs.inputConfirm.getValue() if @refs.inputConfirm? return confirm?.length and confirm is current and @state.passwordTest.failedTests.length is 0 render: -> {isNewUser, resetPass, focusOnMount} = @props {passwordTest, currentPassword, confirmPassword, passwordRequirements} = @state passwordsMatch = currentPassword is confirmPassword passwordFailures = passwordTest.failedTests passwordErrors = passwordTest.errors passingTest = passwordFailures?.length is 0 # remove certain tests for our purposes if passwordFailures and passwordFailures.length is 0 then passingTest = true inputProps = placeholder: t 'Password' ref: 'input' key: 'input' type: 'password' inputProps = _.assign(inputProps, @props) inputProps.onChange = @testCurrentPassword div { className: 'password-form' }, [ TextInput(inputProps) TextInput { key: 'inputConfirm' ref: 'inputConfirm' type: 'password' autoComplete: @props.autoComplete tabIndex: @props.tabIndex placeholder: t 'Confirm Password' onChange: @testConfirmPassword wrapperClass: 'confirm' value: confirmPassword onKeyUp: @handleKeyUp } if (not isNewUser or resetPass) and passingTest div { key: 'requirements' className: 'requirements' }, [ h4 { key: 'pass-req-header' className: 'header' }, "#{t('Password requirements')}:" ul { key: 'pass-reqs' className: 'password-reqs' }, passwordRequirements div({ key: 'pass-match' }, [ span { key: 'match-icon' className: "icon-status #{if passwordsMatch then 'success' else 'error'}" }, null span { key: 'match-text' className: 'req-text' }, t('Passwords match') ] ) if passingTest ] ] componentDidMount: -> if @props.focusOnMount then @refs.input.focus() getValue: -> unless @refs.inputConfirm? then '' else @refs.inputConfirm.getValue() handleKeyUp: (e) -> return unless e.keyCode is ENTER @props.handleKeyUp?() if @isValid() buildTestRequirements: (test) -> failedTestErrors = 0: t("At least __minLength__ characters", { minLength: MIN_PASSWORD_LENGTH }) 3: t("At least __count__ lowercase letter", { count: 1 }) 4: t("At least __count__ uppercase letter", { count: 1 }) 5: t("At least __count__ number", { count: 1 }) passwordRequirements = [] {failedTests, errors} = test # Remove specified requirements for req in REMOVED_REQUIREMENTS index = failedTests?.indexOf(req) if index > -1 then failedTests.splice(index, 1) if index > -1 then errors.splice(index, 1) # Display the remaining tests for key, val of failedTestErrors status = if failedTests.indexOf(+key) > -1 then 'error' else 'success' passwordRequirements.push( li { key: key className: 'req-item' }, [ span { key: 'status' className: "icon-status #{status}" }, null span { key: 'val' className: 'req-text' }, val ] ) return passwordRequirements testCurrentPassword: (e) -> value = @refs.input.getValue() test = owasp.test(value) @setState { passwordTest: test currentPassword: value passwordRequirements: @buildTestRequirements(test) } testConfirmPassword: (e) -> value = @refs.inputConfirm.getValue() @setState confirmPassword: value , -> @props.onChange() module.exports = PasswordInput