password-strength.ts 1.4 KB

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