password-strength.ts43 lines · main
1import { DEFAULT_MINIMUM_PASSWORD_STRENGTH, PASSWORD_STRENGTH } from '@/lib/constants'
2
3// This is the same as the ZXCVBNScore type from zxcvbn
4// but we need to define it here because we don't to import zxcvbn everywhere
5export type PasswordStrengthScore = 0 | 1 | 2 | 3 | 4
6
7export async function passwordStrength(value: string) {
8 // [Alaister]: Lazy load zxcvbn to avoid bundling it with the main app (it's pretty chunky)
9 const zxcvbn = await import('zxcvbn').then((module) => module.default)
10
11 let message: string = ''
12 let warning: string = ''
13 let strength: PasswordStrengthScore = 0
14
15 if (value && value !== '') {
16 if (value.length > 99) {
17 message = `${PASSWORD_STRENGTH[0]} Maximum length of password exceeded`
18 warning = `Password should be less than 100 characters`
19 } else {
20 const result = zxcvbn(value)
21 const resultScore = result?.score ?? 0
22
23 const score = (PASSWORD_STRENGTH as any)[resultScore]
24 const suggestions = result.feedback?.suggestions?.join(' ') ?? ''
25
26 message = `${score} ${suggestions}`
27 strength = resultScore
28
29 // warning message for anything below 4 strength :string
30 if (resultScore < DEFAULT_MINIMUM_PASSWORD_STRENGTH) {
31 warning = `${
32 result?.feedback?.warning ? result?.feedback?.warning + '.' : ''
33 } You need a stronger password.`
34 }
35 }
36 }
37
38 return {
39 message,
40 warning,
41 strength,
42 }
43}