ldx-widgets
Version:
widgets
203 lines (190 loc) • 6.54 kB
JavaScript
(function() {
var ENTER, MAX_PASSWORD_LENGTH, MIN_PASSWORD_LENGTH, PasswordInput, REMOVED_REQUIREMENTS, React, TextInput, _, div, h4, li, owasp, ref, span, ul;
React = require('react');
_ = require('lodash');
owasp = require('owasp-password-strength-test');
TextInput = React.createFactory(require('./text_input'));
ENTER = require('../constants/keyboard').ENTER;
ref = React.DOM, div = ref.div, li = ref.li, h4 = ref.h4, ul = ref.ul, span = ref.span;
MIN_PASSWORD_LENGTH = 6;
MAX_PASSWORD_LENGTH = 15;
REMOVED_REQUIREMENTS = [2, 6];
PasswordInput = React.createClass({
displayName: 'PasswordInput',
propTypes: {
onChange: React.PropTypes.func
},
getInitialState: function() {
var test;
owasp.config({
minLength: MIN_PASSWORD_LENGTH,
maxLength: MAX_PASSWORD_LENGTH,
isPassphrase: false
});
test = owasp.test('');
return {
passwordTest: test,
passwordRequirements: this.buildTestRequirements(test),
currentPassword: null,
confirmPassword: null
};
},
getDefaultProps: function() {
return {
onChange: function() {}
};
},
isValid: function() {
var confirm, current;
current = this.refs.input.getValue();
if (this.refs.inputConfirm != null) {
confirm = this.refs.inputConfirm.getValue();
}
return (confirm != null ? confirm.length : void 0) && confirm === current && this.state.passwordTest.failedTests.length === 0;
},
render: function() {
var confirmPassword, currentPassword, focusOnMount, inputProps, isNewUser, passingTest, passwordErrors, passwordFailures, passwordRequirements, passwordTest, passwordsMatch, ref1, ref2, resetPass;
ref1 = this.props, isNewUser = ref1.isNewUser, resetPass = ref1.resetPass, focusOnMount = ref1.focusOnMount;
ref2 = this.state, passwordTest = ref2.passwordTest, currentPassword = ref2.currentPassword, confirmPassword = ref2.confirmPassword, passwordRequirements = ref2.passwordRequirements;
passwordsMatch = currentPassword === confirmPassword;
passwordFailures = passwordTest.failedTests;
passwordErrors = passwordTest.errors;
passingTest = (passwordFailures != null ? passwordFailures.length : void 0) === 0;
if (passwordFailures && passwordFailures.length === 0) {
passingTest = true;
}
inputProps = {
placeholder: t('Password'),
ref: 'input',
key: 'input',
type: 'password'
};
inputProps = _.assign(inputProps, this.props);
inputProps.onChange = this.testCurrentPassword;
return div({
className: 'password-form'
}, [
TextInput(inputProps), (!isNewUser || resetPass) && passingTest ? TextInput({
key: 'inputConfirm',
ref: 'inputConfirm',
type: 'password',
autoComplete: this.props.autoComplete,
tabIndex: this.props.tabIndex,
placeholder: t('Confirm Password'),
onChange: this.testConfirmPassword,
wrapperClass: 'confirm',
value: confirmPassword,
onKeyUp: this.handleKeyUp
}) : void 0, div({
key: 'requirements',
className: 'requirements'
}, [
h4({
key: 'pass-req-header',
className: 'header'
}, (t('Password requirements')) + ":"), ul({
key: 'pass-reqs',
className: 'password-reqs'
}, passwordRequirements), passingTest ? div({
key: 'pass-match'
}, [
span({
key: 'match-icon',
className: "icon-status " + (passwordsMatch ? 'success' : 'error')
}, null), span({
key: 'match-text',
className: 'req-text'
}, t('Passwords match'))
]) : void 0
])
]);
},
componentDidMount: function() {
if (this.props.focusOnMount) {
return this.refs.input.focus();
}
},
getValue: function() {
if (this.refs.inputConfirm == null) {
return '';
} else {
return this.refs.inputConfirm.getValue();
}
},
handleKeyUp: function(e) {
var base;
if (e.keyCode !== ENTER) {
return;
}
if (this.isValid()) {
return typeof (base = this.props).handleKeyUp === "function" ? base.handleKeyUp() : void 0;
}
},
buildTestRequirements: function(test) {
var errors, failedTestErrors, failedTests, i, index, key, len, passwordRequirements, req, status, val;
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 = test.failedTests, errors = test.errors;
for (i = 0, len = REMOVED_REQUIREMENTS.length; i < len; i++) {
req = REMOVED_REQUIREMENTS[i];
index = failedTests != null ? failedTests.indexOf(req) : void 0;
if (index > -1) {
failedTests.splice(index, 1);
}
if (index > -1) {
errors.splice(index, 1);
}
}
for (key in failedTestErrors) {
val = failedTestErrors[key];
status = failedTests.indexOf(+key) > -1 ? 'error' : '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: function(e) {
var test, value;
value = this.refs.input.getValue();
test = owasp.test(value);
return this.setState({
passwordTest: test,
currentPassword: value,
passwordRequirements: this.buildTestRequirements(test)
});
},
testConfirmPassword: function(e) {
var value;
value = this.refs.inputConfirm.getValue();
return this.setState({
confirmPassword: value
}, function() {
return this.props.onChange();
});
}
});
module.exports = PasswordInput;
}).call(this);