Files
worklenz/worklenz-backend/src/shared/password-strength-check.ts

79 lines
1.8 KiB
TypeScript

import {IPasswordValidityResult} from "../interfaces/password-validity-result";
export class PasswordStrengthChecker {
private static readonly defaultOptions = [
{
value: 0,
text: "Too weak",
minDiversity: 0,
minLength: 0
},
{
value: 1,
text: "Weak",
minDiversity: 2,
minLength: 6
},
{
value: 2,
text: "Strong",
minDiversity: 4,
minLength: 8
},
{
value: 3,
text: "Excellent",
minDiversity: 4,
minLength: 10
}
];
private static readonly defaultAllowedSymbols = "!\"#\$%&'\(\)\*\+,-\./:;<=>\?@\[\\\\\\]\^_`\{|\}~";
public static validate(password: string, options = this.defaultOptions, allowedSymbols = this.defaultAllowedSymbols): IPasswordValidityResult {
const passwordCopy = password || "";
options[0].minDiversity = 0;
options[0].minLength = 0;
const rules = [
{
regex: "[a-z]",
message: "lowercase"
},
{
regex: "[A-Z]",
message: "uppercase"
},
{
regex: "[0-9]",
message: "number"
},
];
if (allowedSymbols) {
rules.push({
regex: `[${allowedSymbols}]`,
message: "symbol"
});
}
const strength: any = {};
strength.contains = rules
.filter(rule => new RegExp(`${rule.regex}`).test(passwordCopy))
.map(rule => rule.message);
strength.length = passwordCopy.length;
const fulfilledOptions = options
.filter(option => strength.contains.length >= option.minDiversity)
.filter(option => strength.length >= option.minLength)
.sort((o1, o2) => o2.value - o1.value)
.map(option => ({value: option.value, text: option.text}));
Object.assign(strength, fulfilledOptions[0]);
return strength;
}
}