File size: 1,502 Bytes
eeb3436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const { AppError } = require("./appError");

const PASSWORD_POLICY = Object.freeze({
  minLength: 12,
  requireLowercase: true,
  requireUppercase: true,
  requireNumber: true,
  requireSymbol: true,
});

function validatePassword(password) {
  const failures = [];

  if (typeof password !== "string" || password.length === 0) {
    failures.push("Password is required.");
    return failures;
  }

  if (password.length < PASSWORD_POLICY.minLength) {
    failures.push(`Password must be at least ${PASSWORD_POLICY.minLength} characters.`);
  }

  if (PASSWORD_POLICY.requireLowercase && !/[a-z]/.test(password)) {
    failures.push("Password must include at least one lowercase letter.");
  }

  if (PASSWORD_POLICY.requireUppercase && !/[A-Z]/.test(password)) {
    failures.push("Password must include at least one uppercase letter.");
  }

  if (PASSWORD_POLICY.requireNumber && !/[0-9]/.test(password)) {
    failures.push("Password must include at least one number.");
  }

  if (PASSWORD_POLICY.requireSymbol && !/[^A-Za-z0-9]/.test(password)) {
    failures.push("Password must include at least one symbol.");
  }

  return failures;
}

function assertPasswordPolicy(password) {
  const failures = validatePassword(password);
  if (failures.length > 0) {
    throw new AppError(failures.join(" "), 400, {
      code: "PASSWORD_POLICY_VIOLATION",
      policy: PASSWORD_POLICY,
      failures,
    });
  }
}

module.exports = {
  PASSWORD_POLICY,
  validatePassword,
  assertPasswordPolicy,
};