mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			64 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import {zxcvbn, zxcvbnOptions} from "@zxcvbn-ts/core";
 | 
						|
import zxcvbnCommonPackage from "@zxcvbn-ts/language-common";
 | 
						|
import zxcvbnEnPackage from "@zxcvbn-ts/language-en";
 | 
						|
 | 
						|
import {$t} from "./i18n";
 | 
						|
 | 
						|
zxcvbnOptions.setOptions({
 | 
						|
    translations: zxcvbnEnPackage.translations,
 | 
						|
    dictionary: {
 | 
						|
        ...zxcvbnCommonPackage.dictionary,
 | 
						|
        ...zxcvbnEnPackage.dictionary,
 | 
						|
    },
 | 
						|
});
 | 
						|
 | 
						|
// Note: this module is loaded asynchronously from the app with
 | 
						|
// import() to keep zxcvbn out of the initial page load.  Do not
 | 
						|
// import it synchronously from the app.
 | 
						|
 | 
						|
// Return a boolean indicating whether the password is acceptable.
 | 
						|
// Also updates a Bootstrap progress bar control (a jQuery object)
 | 
						|
// if provided.
 | 
						|
export function password_quality(
 | 
						|
    password: string,
 | 
						|
    $bar: JQuery | undefined,
 | 
						|
    $password_field: JQuery,
 | 
						|
): boolean {
 | 
						|
    const min_length = $password_field.data("minLength");
 | 
						|
    const min_guesses = $password_field.data("minGuesses");
 | 
						|
 | 
						|
    const result = zxcvbn(password);
 | 
						|
    const acceptable = password.length >= min_length && result.guesses >= min_guesses;
 | 
						|
 | 
						|
    if ($bar !== undefined) {
 | 
						|
        const t = result.crackTimesSeconds.offlineSlowHashing1e4PerSecond;
 | 
						|
        let bar_progress = Math.min(1, Math.log(1 + t) / 22);
 | 
						|
 | 
						|
        // Even if zxcvbn loves your short password, the bar should be
 | 
						|
        // filled at most 1/3 of the way, because we won't accept it.
 | 
						|
        if (!acceptable) {
 | 
						|
            bar_progress = Math.min(bar_progress, 0.33);
 | 
						|
        }
 | 
						|
 | 
						|
        // The bar bottoms out at 10% so there's always something
 | 
						|
        // for the user to see.
 | 
						|
        $bar.width(`${90 * bar_progress + 10}%`)
 | 
						|
            .removeClass("bar-success bar-danger")
 | 
						|
            .addClass(acceptable ? "bar-success" : "bar-danger");
 | 
						|
    }
 | 
						|
 | 
						|
    return acceptable;
 | 
						|
}
 | 
						|
 | 
						|
export function password_warning(password: string, $password_field: JQuery): string {
 | 
						|
    const min_length = $password_field.data("minLength");
 | 
						|
 | 
						|
    if (password.length < min_length) {
 | 
						|
        return $t(
 | 
						|
            {defaultMessage: "Password should be at least {length} characters long"},
 | 
						|
            {length: min_length},
 | 
						|
        );
 | 
						|
    }
 | 
						|
    return zxcvbn(password).feedback.warning || $t({defaultMessage: "Password is too weak"});
 | 
						|
}
 |