79 lines
1.8 KiB
TypeScript
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;
|
|
}
|
|
}
|