mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
committed by
Tim Abbott
parent
4362c8d3c9
commit
16188400f7
@@ -145,8 +145,8 @@ Form is validated both client-side using jquery-validation (see signup.js) and s
|
||||
<div class="input-box password-div">
|
||||
<input id="id_password" class="required" type="password" name="password" autocomplete="new-password"
|
||||
value="{% if form.password.value() %}{{ form.password.value() }}{% endif %}"
|
||||
maxlength="{{ MAX_PASSWORD_LENGTH }}"
|
||||
data-min-length="{{password_min_length}}"
|
||||
data-max-length="{{ password_max_length }}"
|
||||
data-min-guesses="{{password_min_guesses}}" required />
|
||||
<label for="id_password" class="inline-block">{{ _('Password') }}</label>
|
||||
<i class="fa fa-eye-slash password_visibility_toggle" role="button" tabindex="0"></i>
|
||||
|
@@ -31,7 +31,7 @@
|
||||
<label for="id_new_password1" class="">{{ _('Password') }}</label>
|
||||
<input id="id_new_password1" class="required" type="password" name="new_password1" autocomplete="new-password"
|
||||
value="{% if form.new_password1.value() %}{{ form.new_password1.value() }}{% endif %}"
|
||||
maxlength="100"
|
||||
data-max-length="{{ password_max_length }}"
|
||||
data-min-length="{{password_min_length}}"
|
||||
data-min-guesses="{{password_min_guesses}}" autofocus required />
|
||||
<i class="fa fa-eye-slash password_visibility_toggle" role="button" tabindex="0"></i>
|
||||
|
@@ -25,10 +25,14 @@ export function password_quality(
|
||||
$password_field: JQuery,
|
||||
): boolean {
|
||||
const min_length = Number($password_field.attr("data-min-length"));
|
||||
const max_length = Number($password_field.attr("data-max-length"));
|
||||
const min_guesses = Number($password_field.attr("data-min-guesses"));
|
||||
|
||||
const result = zxcvbn(password);
|
||||
const acceptable = password.length >= min_length && result.guesses >= min_guesses;
|
||||
const acceptable =
|
||||
password.length >= min_length &&
|
||||
password.length <= max_length &&
|
||||
result.guesses >= min_guesses;
|
||||
|
||||
if ($bar !== undefined) {
|
||||
const t = result.crackTimesSeconds.offlineSlowHashing1e4PerSecond;
|
||||
@@ -52,12 +56,20 @@ export function password_quality(
|
||||
|
||||
export function password_warning(password: string, $password_field: JQuery): string {
|
||||
const min_length = Number($password_field.attr("data-min-length"));
|
||||
const max_length = Number($password_field.attr("data-max-length"));
|
||||
|
||||
if (password.length < min_length) {
|
||||
return $t(
|
||||
{defaultMessage: "Password should be at least {length} characters long"},
|
||||
{length: min_length},
|
||||
);
|
||||
} else if (password.length > max_length) {
|
||||
return $t(
|
||||
{
|
||||
defaultMessage: "Maximum password length: {max} characters.",
|
||||
},
|
||||
{max: max_length},
|
||||
);
|
||||
}
|
||||
return zxcvbn(password).feedback.warning ?? $t({defaultMessage: "Password is too weak"});
|
||||
}
|
||||
|
@@ -478,6 +478,19 @@ export function set_up(): void {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
const max_length = realm.password_max_length;
|
||||
if (new_password && new_password.toString().length > max_length) {
|
||||
ui_report.error(
|
||||
$t_html(
|
||||
{defaultMessage: "Maximum password length: {max_length} characters"},
|
||||
{max_length},
|
||||
),
|
||||
undefined,
|
||||
$("#dialog_error"),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<label for="new_password" class="modal-field-label">{{t "New password" }}</label>
|
||||
<div class="password-input-row">
|
||||
<input type="password" autocomplete="new-password" name="new_password" id="new_password" class="inline-block modal_password_input" value=""
|
||||
data-min-length="{{password_min_length}}" data-min-guesses="{{password_min_guesses}}" />
|
||||
data-min-length="{{password_min_length}}" data-min-guesses="{{password_min_guesses}}" data-max-length="{{ password_max_length }}" />
|
||||
<i class="fa fa-eye-slash password_visibility_toggle tippy-zulip-tooltip" role="button" tabindex="0"></i>
|
||||
</div>
|
||||
<div class="progress inline-block" id="pw_strength">
|
||||
|
@@ -7,7 +7,7 @@ const {run_test} = require("./lib/test.cjs");
|
||||
|
||||
const {password_quality, password_warning} = zrequire("password_quality");
|
||||
|
||||
function password_field(min_length, min_guesses) {
|
||||
function password_field(min_length, max_length, min_guesses) {
|
||||
const self = {};
|
||||
|
||||
self.attr = (name) => {
|
||||
@@ -16,6 +16,8 @@ function password_field(min_length, min_guesses) {
|
||||
return min_length;
|
||||
case "data-min-guesses":
|
||||
return min_guesses;
|
||||
case "data-max-length":
|
||||
return max_length;
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error(`Unknown attribute ${name}`);
|
||||
@@ -60,7 +62,7 @@ run_test("basics w/progress bar", () => {
|
||||
assert.equal(warning, "translated: Password should be at least 10 characters long");
|
||||
|
||||
password = "foo";
|
||||
accepted = password_quality(password, $bar, password_field(2, 200));
|
||||
accepted = password_quality(password, $bar, password_field(2, 200, 10));
|
||||
assert.ok(accepted);
|
||||
assert.equal($bar.w, "10.390277164940581%");
|
||||
assert.equal($bar.added_class, "bar-success");
|
||||
@@ -73,4 +75,12 @@ run_test("basics w/progress bar", () => {
|
||||
assert.equal($bar.added_class, "bar-danger");
|
||||
warning = password_warning(password, password_field(6));
|
||||
assert.equal(warning, 'Repeated characters like "aaa" are easy to guess.');
|
||||
|
||||
// Test a password that's longer than the configured limit.
|
||||
password = "hfHeo34FksdBChjeruShJ@sidfgusd";
|
||||
accepted = password_quality(password, $bar, password_field(6, 20, 1e20));
|
||||
assert.ok(!accepted);
|
||||
assert.equal($bar.added_class, "bar-danger");
|
||||
warning = password_warning(password, password_field(6, 20, 1e20));
|
||||
assert.equal(warning, `translated: Maximum password length: 20 characters.`);
|
||||
});
|
||||
|
Reference in New Issue
Block a user