@gauts/auth 0.6.2 → 0.6.3

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.
package/README.md CHANGED
@@ -101,7 +101,6 @@ import type { AuthAccountOf } from "@gauts/auth";
101
101
  import type { HonoAuthEnv } from "@gauts/auth/hono";
102
102
 
103
103
  import { auth } from "./auth.js";
104
- import { DUMMY_PASSWORD_HASH } from "./password.js";
105
104
 
106
105
  type Account = AuthAccountOf<typeof auth>;
107
106
 
@@ -117,7 +116,7 @@ app.post("/auth/login", async (c) => {
117
116
 
118
117
  const passwordValid = await auth.password.verify({
119
118
  password: body.password,
120
- storedHash: account?.passwordHash ?? DUMMY_PASSWORD_HASH,
119
+ storedHash: account?.passwordHash,
121
120
  });
122
121
 
123
122
  if (!account || !passwordValid) {
@@ -150,7 +149,7 @@ app.get("/account", auth.requireSession, (c) => {
150
149
  });
151
150
  ```
152
151
 
153
- Precompute `DUMMY_PASSWORD_HASH` once with the same algorithm and cost as the application. This ensures unknown accounts perform equivalent password verification work. Keep the response identical for unknown accounts and incorrect passwords.
152
+ When `storedHash` is missing, the package performs password work with the configured algorithm and always returns `false`. Applications do not need a dummy hash. Keep the response identical for unknown accounts and incorrect passwords.
154
153
 
155
154
  ### 3. Enable the optional cache
156
155
 
@@ -228,6 +227,8 @@ password: {
228
227
 
229
228
  The package does not detect algorithms, migrate hashes, rehash passwords, or fall back to another algorithm.
230
229
 
230
+ `auth.password.verify()` accepts a missing `storedHash` so account lookup and password verification can follow one path. A missing or incompatible hash performs password work with the configured algorithm and returns `false`; it is never accepted or passed to another algorithm.
231
+
231
232
  ### Session
232
233
 
233
234
  All time values are seconds.
@@ -4,7 +4,7 @@ export type PasswordService = {
4
4
  hash(password: string): Promise<string>;
5
5
  verify(input: {
6
6
  password: string;
7
- storedHash: string;
7
+ storedHash?: string | null | undefined;
8
8
  }): Promise<boolean>;
9
9
  };
10
10
  export declare const createPassword: (config: ResolvedPasswordConfig) => PasswordService;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7E,CAAC;AAqEF,eAAO,MAAM,cAAc,GAAI,QAAQ,sBAAsB,KAAG,eAE/D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAG3D,MAAM,MAAM,eAAe,GAAG;IAC1B,SAAS,EAAE,UAAU,GAAG,QAAQ,CAAC;IACjC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACjG,CAAC;AA+EF,eAAO,MAAM,cAAc,GAAI,QAAQ,sBAAsB,KAAG,eAE/D,CAAC"}
@@ -11,40 +11,48 @@ const requirePassword = ({ password, maxBytes }) => {
11
11
  });
12
12
  }
13
13
  };
14
- const createArgon2id = (config) => ({
15
- algorithm: "argon2id",
16
- hash: async (password) => {
17
- requirePassword({ maxBytes: config.maxBytes, password });
18
- return argon2.hash(password, {
19
- hashLength: config.hashLength,
20
- memoryCost: config.memoryCost,
21
- parallelism: config.parallelism,
22
- timeCost: config.timeCost,
23
- type: argon2.argon2id,
24
- });
25
- },
26
- verify: async ({ password, storedHash }) => {
27
- requirePassword({ maxBytes: config.maxBytes, password });
28
- if (!storedHash.startsWith("$argon2id$")) {
29
- return false;
30
- }
31
- return argon2.verify(storedHash, password);
32
- },
33
- });
34
- const createBcrypt = (config) => ({
35
- algorithm: "bcrypt",
36
- hash: async (password) => {
37
- requirePassword({ maxBytes: config.maxBytes, password });
38
- return hashBcrypt(password, config.rounds);
39
- },
40
- verify: async ({ password, storedHash }) => {
41
- requirePassword({ maxBytes: config.verifyMaxBytes, password });
42
- if (!BCRYPT_PATTERN.test(storedHash)) {
43
- return false;
44
- }
45
- return compareBcrypt(password, storedHash);
46
- },
47
- });
14
+ const createArgon2id = (config) => {
15
+ const hashValue = (password) => argon2.hash(password, {
16
+ hashLength: config.hashLength,
17
+ memoryCost: config.memoryCost,
18
+ parallelism: config.parallelism,
19
+ timeCost: config.timeCost,
20
+ type: argon2.argon2id,
21
+ });
22
+ return {
23
+ algorithm: "argon2id",
24
+ hash: async (password) => {
25
+ requirePassword({ maxBytes: config.maxBytes, password });
26
+ return hashValue(password);
27
+ },
28
+ verify: async ({ password, storedHash }) => {
29
+ requirePassword({ maxBytes: config.maxBytes, password });
30
+ if (!storedHash?.startsWith("$argon2id$")) {
31
+ await hashValue(password);
32
+ return false;
33
+ }
34
+ return argon2.verify(storedHash, password);
35
+ },
36
+ };
37
+ };
38
+ const createBcrypt = (config) => {
39
+ const hashValue = (password) => hashBcrypt(password, config.rounds);
40
+ return {
41
+ algorithm: "bcrypt",
42
+ hash: async (password) => {
43
+ requirePassword({ maxBytes: config.maxBytes, password });
44
+ return hashValue(password);
45
+ },
46
+ verify: async ({ password, storedHash }) => {
47
+ requirePassword({ maxBytes: config.verifyMaxBytes, password });
48
+ if (!storedHash || !BCRYPT_PATTERN.test(storedHash)) {
49
+ await hashValue(password);
50
+ return false;
51
+ }
52
+ return compareBcrypt(password, storedHash);
53
+ },
54
+ };
55
+ };
48
56
  export const createPassword = (config) => {
49
57
  return config.algorithm === "bcrypt" ? createBcrypt(config) : createArgon2id(config);
50
58
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAa3C,MAAM,cAAc,GAAG,sCAAsC,CAAC;AAE9D,MAAM,eAAe,GAAG,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAwB,EAAE,EAAE;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAElD,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;QAChC,MAAM,WAAW,CAAC;YACd,IAAI,EAAE,wBAAwB;YAC9B,OAAO,EAAE,uCAAuC,MAAM,CAAC,QAAQ,CAAC,SAAS;SAC5E,CAAC,CAAC;IACP,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CACnB,MAAkE,EACnD,EAAE,CAAC,CAAC;IACnB,SAAS,EAAE,UAAU;IAErB,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACrB,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEzD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,QAAQ;SACxB,CAAC,CAAC;IACP,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;QACvC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEzD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CACjB,MAAgE,EACjD,EAAE,CAAC,CAAC;IACnB,SAAS,EAAE,QAAQ;IAEnB,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACrB,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACzD,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;QACvC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE/D,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,OAAO,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAA8B,EAAmB,EAAE;IAC9E,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AACzF,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/password/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gauts/auth",
3
- "version": "0.6.2",
3
+ "version": "0.6.3",
4
4
  "description": "Framework-agnostic password and server-side session authentication for Node.js.",
5
5
  "license": "MIT",
6
6
  "author": "GVALFER",