@carecard/auth-util 3.24.0 → 3.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/pwdUtilAuth.js +10 -0
  2. package/package.json +3 -3
@@ -15,6 +15,7 @@ const MINIMUM_PEPPER_BYTES = 32;
15
15
  const PASSWORD_HASH_PATTERN =
16
16
  /^\$argon2id\$v=19\$m=19456,t=2,p=1\$([A-Za-z0-9+/]{22})\$([A-Za-z0-9+/]{43})$/;
17
17
 
18
+ // Pattern: Configuration Guard - converts only a sufficiently strong string pepper to bytes.
18
19
  function createPepperBuffer(pepper) {
19
20
  if (typeof pepper !== 'string') {
20
21
  throw new TypeError('Password pepper must be a string.');
@@ -26,6 +27,7 @@ function createPepperBuffer(pepper) {
26
27
  return pepperBuffer;
27
28
  }
28
29
 
30
+ // Pattern: Canonicalization - converts well-formed NFC password text to stable UTF-8 bytes.
29
31
  function createPasswordBuffer(password) {
30
32
  if (typeof password !== 'string' || !password.isWellFormed()) {
31
33
  throw new TypeError('Password must be a well-formed Unicode string.');
@@ -33,10 +35,12 @@ function createPasswordBuffer(password) {
33
35
  return Buffer.from(password.normalize('NFC'), 'utf8');
34
36
  }
35
37
 
38
+ // Pattern: Serializer Helper - emits canonical unpadded PHC Base64 text.
36
39
  function encodePhcBase64(value) {
37
40
  return value.toString('base64').replace(/=+$/, '');
38
41
  }
39
42
 
43
+ // Pattern: Parser Guard - accepts only canonical PHC Base64 with the required byte length.
40
44
  function decodePhcBase64(value, expectedLength) {
41
45
  const decodedValue = Buffer.from(value, 'base64');
42
46
  if (decodedValue.length !== expectedLength || encodePhcBase64(decodedValue) !== value) {
@@ -45,6 +49,7 @@ function decodePhcBase64(value, expectedLength) {
45
49
  return decodedValue;
46
50
  }
47
51
 
52
+ // Pattern: Strict Parser - accepts only the exact CareCard Argon2id storage contract.
48
53
  function parsePasswordHash(savedHash) {
49
54
  if (typeof savedHash !== 'string') {
50
55
  return null;
@@ -58,6 +63,7 @@ function parsePasswordHash(savedHash) {
58
63
  return salt && tag ? { salt, tag } : null;
59
64
  }
60
65
 
66
+ // Pattern: Parameter Object - centralizes the fixed Argon2id security profile.
61
67
  function createArgon2Parameters(passwordBuffer, salt, pepperBuffer) {
62
68
  return {
63
69
  message: passwordBuffer,
@@ -70,16 +76,19 @@ function createArgon2Parameters(passwordBuffer, salt, pepperBuffer) {
70
76
  };
71
77
  }
72
78
 
79
+ // Pattern: Cryptographic Adapter - derives one tag through Node's asynchronous Argon2 boundary.
73
80
  async function derivePasswordTag(password, salt, pepperBuffer) {
74
81
  const parameters = createArgon2Parameters(createPasswordBuffer(password), salt, pepperBuffer);
75
82
  return deriveArgon2Tag(ARGON2_ALGORITHM, parameters);
76
83
  }
77
84
 
85
+ // Pattern: Serializer - records the fixed parameters, salt, and tag in strict PHC form.
78
86
  function serializePasswordHash(salt, tag) {
79
87
  const parameters = `m=${ARGON2_MEMORY_KIB},t=${ARGON2_PASSES},p=${ARGON2_PARALLELISM}`;
80
88
  return `$${ARGON2_ALGORITHM}$v=${ARGON2_VERSION}$${parameters}$${encodePhcBase64(salt)}$${encodePhcBase64(tag)}`;
81
89
  }
82
90
 
91
+ // Pattern: Credential Factory - creates an independently salted Argon2id password hash.
83
92
  async function createPasswordHash(password, pepper) {
84
93
  const pepperBuffer = createPepperBuffer(pepper);
85
94
  const salt = randomBytes(PASSWORD_SALT_BYTES);
@@ -87,6 +96,7 @@ async function createPasswordHash(password, pepper) {
87
96
  return serializePasswordHash(salt, tag);
88
97
  }
89
98
 
99
+ // Pattern: Constant-Time Verification - derives and compares a strict Argon2id credential tag.
90
100
  async function verifyPassword(password, savedHash, pepper) {
91
101
  const pepperBuffer = createPepperBuffer(pepper);
92
102
  if (typeof password !== 'string' || !password.isWellFormed()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carecard/auth-util",
3
- "version": "3.24.0",
3
+ "version": "3.25.0",
4
4
  "repository": "https://github.com/CareCard-ca/pkg-auth-util.git",
5
5
  "description": "Auth utility functions",
6
6
  "main": "index.js",
@@ -50,8 +50,8 @@
50
50
  "typescript": "6.0.3"
51
51
  },
52
52
  "dependencies": {
53
- "@carecard/common-util": "3.24.0",
54
- "@carecard/validate": "3.24.0",
53
+ "@carecard/common-util": "3.25.0",
54
+ "@carecard/validate": "3.25.0",
55
55
  "@types/express": "5.0.6"
56
56
  },
57
57
  "overrides": {