Merge pull request #4388 from AngelFQC/BT20083

Consider password requirements in progress bar when indicating strength
pull/4392/head
Nicolas Ducoulombier 3 years ago committed by GitHub
commit 090363241a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      bower.json
  2. 5
      main/admin/user_add.php
  3. 5
      main/admin/user_edit.php
  4. 2
      main/auth/inscription.php
  5. 6
      main/auth/reset.php
  6. 113
      main/inc/lib/api.lib.php
  7. 46
      main/inc/lib/javascript/password-checker/password-checker.js

@ -28,7 +28,6 @@
"cropper": "1.0.*",
"jquery.scrollbar": "0.2.*",
"jquery-file-upload": "*",
"pwstrength-bootstrap": "2.1.0",
"readmore-js": "2.1.0",
"qtip2": "*",
"js-cookie": "2.1.*",

@ -235,10 +235,7 @@ $group[] = $form->createElement(
$form->addGroup(
$group,
'password',
[
get_lang('Password'),
Security::getPasswordRequirementsToString(),
]
get_lang('Password')
);
$form->addPasswordRule('password', 'password');
$form->addGroupRule('password', get_lang('EnterPassword'), 'required', null, 1);

@ -240,10 +240,7 @@ $group[] = $form->createElement(
$form->addGroup(
$group,
'password',
[
null,
Security::getPasswordRequirementsToString(),
],
'',
null,
false
);

@ -203,7 +203,7 @@ if ($user_already_registered_show_terms === false &&
'password',
'pass1',
get_lang('Pass'),
['id' => 'pass1', 'size' => 20, 'autocomplete' => 'off']
['id' => 'pass1', 'size' => 20, 'autocomplete' => 'off', 'show_hide' => true]
);
$form->addElement(

@ -28,9 +28,9 @@ $form->addHidden('token', $token);
$form->addElement(
'password',
'pass1',
get_lang('Password'),
[
get_lang('Password'),
Security::getPasswordRequirementsToString(),
'show_hide' => true,
]
);
$form->addElement(
@ -94,6 +94,8 @@ if ($form->validate()) {
}
}
$htmlHeadXtra[] = api_get_password_checker_js('#username', '#reset_pass1');
$tpl = new Template(null);
$tpl->assign('content', $form->toHtml());
$tpl->display_one_col_template();

@ -8529,64 +8529,71 @@ function api_get_password_checker_js($usernameInputId, $passwordInputId)
return null;
}
$translations = [
'wordLength' => get_lang('PasswordIsTooShort'),
'wordNotEmail' => get_lang('YourPasswordCannotBeTheSameAsYourEmail'),
'wordSimilarToUsername' => get_lang('YourPasswordCannotContainYourUsername'),
'wordTwoCharacterClasses' => get_lang('WordTwoCharacterClasses'),
'wordRepetitions' => get_lang('TooManyRepetitions'),
'wordSequences' => get_lang('YourPasswordContainsSequences'),
'errorList' => get_lang('ErrorsFound'),
'veryWeak' => get_lang('PasswordVeryWeak'),
'weak' => get_lang('PasswordWeak'),
'normal' => get_lang('PasswordNormal'),
'medium' => get_lang('PasswordMedium'),
'strong' => get_lang('PasswordStrong'),
'veryStrong' => get_lang('PasswordVeryStrong'),
$minRequirements = Security::getPasswordRequirements()['min'];
$options = [
'rules' => [],
];
$js = api_get_asset('pwstrength-bootstrap/dist/pwstrength-bootstrap.min.js');
$js .= "<script>
var errorMessages = {
password_to_short : \"".get_lang('PasswordIsTooShort')."\",
same_as_username : \"".get_lang('YourPasswordCannotBeTheSameAsYourUsername')."\"
};
if ($minRequirements['length'] > 0) {
$options['rules'][] = [
'minChar' => $minRequirements['length'],
'pattern' => '.',
'helpText' => sprintf(
get_lang('NewPasswordRequirementMinXLength'),
$minRequirements['length']
),
];
}
$(function() {
var lang = ".json_encode($translations).";
var options = {
common: {
onLoad: function () {
//$('#messages').text('Start typing password');
if ($minRequirements['lowercase'] > 0) {
$options['rules'][] = [
'minChar' => $minRequirements['lowercase'],
'pattern' => '[a-z]',
'helpText' => sprintf(
get_lang('NewPasswordRequirementMinXLowercase'),
$minRequirements['lowercase']
),
];
}
var inputGroup = $('".$passwordInputId."').parents('.input-group');
if ($minRequirements['uppercase'] > 0) {
$options['rules'][] = [
'minChar' => $minRequirements['uppercase'],
'pattern' => '[A-Z]',
'helpText' => sprintf(
get_lang('NewPasswordRequirementMinXUppercase'),
$minRequirements['uppercase']
),
];
}
if (inputGroup.length > 0) {
inputGroup.find('.progress').insertAfter(inputGroup);
}
}
},
ui: {
showVerdictsInsideProgressBar: true
},
onKeyUp: function (evt) {
$(evt.target).pwstrength('outputErrorList');
},
errorMessages : errorMessages,
viewports: {
progress: '#password_progress',
verdict: '#password-verdict',
errors: '#password-errors'
},
usernameField: '$usernameInputId'
};
options.i18n = {
t: function (key) {
var result = lang[key];
return result === key ? '' : result; // This assumes you return the
}
};
$('".$passwordInputId."').pwstrength(options);
if ($minRequirements['numeric'] > 0) {
$options['rules'][] = [
'minChar' => $minRequirements['numeric'],
'pattern' => '[0-9]',
'helpText' => sprintf(
get_lang('NewPasswordRequirementMinXNumeric'),
$minRequirements['numeric']
),
];
}
if ($minRequirements['specials'] > 0) {
$options['rules'][] = [
'minChar' => $minRequirements['specials'],
'pattern' => '[!"#$%&\'()*+,\-./\\\:;<=>?@[\\]^_`{|}~]',
'helpText' => sprintf(
get_lang('NewPasswordRequirementMinXSpecials'),
$minRequirements['specials']
),
];
}
$js = api_get_js('password-checker/password-checker.js');
$js .= "<script>
$(function() {
$('".$passwordInputId."').passwordChecker(".json_encode($options).");
});
</script>";

@ -0,0 +1,46 @@
(function ($) {
$.fn.passwordChecker = function (options) {
options = $.extend({
rules: []
}, options);
this.each(function (i, el) {
var $el = $(el);
var $parent = $el.parent();
var $ulHelp = $('<ul class="help-block fa-ul"></ul>');
var helpTexts = [];
$(options.rules).each(function (j, rule) {
helpTexts.push(
$('<li>')
);
helpTexts[j].text(rule.helpText).appendTo($ulHelp).append('<span class="fa fa-fw fa-li ">');
});
$ulHelp.insertAfter($parent);
$el
.on('input', function () {
var tempPassword = this.value;
$(options.rules).each(function (j, rule) {
var match = tempPassword.match(
new RegExp(rule.pattern, 'g')
);
if (match && match.length >= rule.minChar) {
helpTexts[j].removeClass('text-danger').addClass('text-success')
.find('.fa-li').removeClass('fa-times').addClass('fa-check');
} else {
helpTexts[j].addClass('text-danger').removeClass('text-success')
.find('.fa-li').addClass('fa-times').removeClass('fa-check');
}
});
})
.trigger('input');
});
};
})(jQuery);
Loading…
Cancel
Save