@gauts/auth 0.1.2 → 0.2.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 (47) hide show
  1. package/README.md +105 -62
  2. package/SECURITY.md +1 -3
  3. package/dist/adapters/hono/index.d.ts +12 -6
  4. package/dist/adapters/hono/index.d.ts.map +1 -1
  5. package/dist/adapters/hono/index.js +72 -17
  6. package/dist/adapters/hono/index.js.map +1 -1
  7. package/dist/adapters/redis/index.d.ts +5 -1
  8. package/dist/adapters/redis/index.d.ts.map +1 -1
  9. package/dist/adapters/redis/index.js +16 -7
  10. package/dist/adapters/redis/index.js.map +1 -1
  11. package/dist/auth.d.ts +3 -3
  12. package/dist/auth.d.ts.map +1 -1
  13. package/dist/auth.js +21 -15
  14. package/dist/auth.js.map +1 -1
  15. package/dist/client/index.d.ts +8 -6
  16. package/dist/client/index.d.ts.map +1 -1
  17. package/dist/client/index.js +4 -11
  18. package/dist/client/index.js.map +1 -1
  19. package/dist/config.d.ts +12 -4
  20. package/dist/config.d.ts.map +1 -1
  21. package/dist/config.js +119 -18
  22. package/dist/config.js.map +1 -1
  23. package/dist/errors.d.ts +7 -2
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +1 -1
  26. package/dist/errors.js.map +1 -1
  27. package/dist/index.d.ts +4 -5
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/password/index.d.ts +4 -1
  32. package/dist/password/index.d.ts.map +1 -1
  33. package/dist/password/index.js +16 -9
  34. package/dist/password/index.js.map +1 -1
  35. package/dist/session/schema.d.ts.map +1 -1
  36. package/dist/session/schema.js +19 -10
  37. package/dist/session/schema.js.map +1 -1
  38. package/dist/session/service.d.ts +3 -3
  39. package/dist/session/service.d.ts.map +1 -1
  40. package/dist/session/service.js +94 -45
  41. package/dist/session/service.js.map +1 -1
  42. package/dist/session/token.d.ts.map +1 -1
  43. package/dist/session/token.js +6 -2
  44. package/dist/session/token.js.map +1 -1
  45. package/dist/session/types.d.ts +49 -23
  46. package/dist/session/types.d.ts.map +1 -1
  47. package/package.json +1 -1
package/README.md CHANGED
@@ -4,16 +4,14 @@ Reusable password and opaque server-side session authentication for Node.js appl
4
4
 
5
5
  `@gauts/auth` validates sessions through Redis and records session history through an application-owned database adapter. It does not create endpoints, database models, users, or application authorization rules.
6
6
 
7
- The package is under active development and has not been published yet.
8
-
9
7
  ## Design
10
8
 
11
9
  - Argon2id by default, with explicit bcrypt support.
12
10
  - One stable 256-bit opaque browser token per session.
13
- - SHA-256 token hashes in Redis and the audit database.
11
+ - SHA-256 token hashes in Redis and the session records database.
14
12
  - Redis-authoritative authentication with no database fallback.
15
13
  - Sliding inactivity expiration without an absolute lifetime.
16
- - Exact canonical IP and complete User-Agent session binding.
14
+ - Configurable client validation, using the complete User-Agent by default.
17
15
  - Framework integrations through explicit package exports.
18
16
 
19
17
  ## Installation
@@ -22,21 +20,23 @@ The package is under active development and has not been published yet.
22
20
  npm install @gauts/auth redis hono
23
21
  ```
24
22
 
25
- The package is not on npm yet. During local development, use the tarball produced by `npm pack`.
26
-
27
23
  ## Setup
28
24
 
29
25
  ```ts
30
- import { createAuth, type SessionAudit } from "@gauts/auth";
26
+ import { createAuth, type SessionRecords } from "@gauts/auth";
31
27
  import { createHonoAdapter } from "@gauts/auth/hono";
32
28
  import { createRedisStore } from "@gauts/auth/redis";
33
29
 
34
- const audit: SessionAudit = {
30
+ const records: SessionRecords = {
35
31
  create: (session) => db.sessions.create(session),
36
- findActive: (subjectId, now) => db.sessions.findActive(subjectId, now),
37
- findForRevoke: (subjectId, sessionId) => db.sessions.findForRevoke(subjectId, sessionId),
38
- revoke: (sessionIds, revokedAt) => db.sessions.revoke(sessionIds, revokedAt),
39
- touch: (sessionId, expiresAt, updatedAt) => db.sessions.touch(sessionId, expiresAt, updatedAt),
32
+ find: ({ accountId, sessionId }) =>
33
+ db.sessions.find({ accountId, sessionId }),
34
+ findActive: ({ accountId, now }) =>
35
+ db.sessions.findActive({ accountId, now }),
36
+ revoke: ({ revokedAt, sessionIds }) =>
37
+ db.sessions.revoke({ revokedAt, sessionIds }),
38
+ updateExpiry: ({ expiresAt, sessionId, updatedAt }) =>
39
+ db.sessions.updateExpiry({ expiresAt, sessionId, updatedAt }),
40
40
  };
41
41
 
42
42
  type AccountSession = {
@@ -45,33 +45,56 @@ type AccountSession = {
45
45
  };
46
46
 
47
47
  const auth = createAuth<AccountSession>({
48
- redis: createRedisStore(redis, { prefix: "my-app:auth" }),
49
- audit,
48
+ redis: createRedisStore({ client: redis, config: { prefix: "my-app:auth" } }),
49
+ records,
50
50
  session: {
51
51
  ttl: 60 * 60 * 24 * 7,
52
- touchAfter: 60 * 60 * 24,
52
+ renewInterval: 60 * 60 * 24,
53
53
  max: 10,
54
+ validation: ["userAgent"],
54
55
  },
55
56
  });
56
57
 
57
58
  const hono = createHonoAdapter({
58
59
  auth,
59
- getClient: (c) => ({
60
- ip: getTrustedClientIp(c),
61
- userAgent: c.req.header("user-agent") ?? null,
62
- }),
60
+ getIp: (c) => getTrustedClientIp(c),
63
61
  });
64
62
  ```
65
63
 
66
64
  The application must obtain the client IP according to its own trusted-proxy configuration. The package canonicalizes the supplied IPv4 or IPv6 value but never decides which forwarding headers are trusted.
67
65
 
66
+ ## Client information
67
+
68
+ The application supplies `getIp` because only its deployment knows which proxies and forwarding
69
+ headers are trusted. The Hono adapter reads User-Agent and platform directly from the request.
70
+
71
+ The resulting client information has this shape:
72
+
73
+ ```ts
74
+ type SessionClientInput = {
75
+ ip?: string | null;
76
+ userAgent?: string | null;
77
+ platform?: string | null;
78
+ };
79
+ ```
80
+
81
+ - `validation` selects which client fields are compared on authenticated requests.
82
+ - `userAgent` is compared by default.
83
+ - `ip` and `platform` are always stored as session metadata, even when they are not compared.
84
+ - IPv4, IPv4-mapped IPv6, and IPv6 values are canonicalized by the package.
85
+ - Platform is unquoted, trimmed, and limited to 255 characters.
86
+ - User-Agent is stored and compared in full without truncation.
87
+
88
+ `getIp` runs during session creation and on every authenticated request. It should only resolve the
89
+ trusted request IP and must not perform unrelated account or database work.
90
+
68
91
  ## Passwords
69
92
 
70
93
  Argon2id is the default:
71
94
 
72
95
  ```ts
73
96
  const hash = await auth.password.hash(password);
74
- const valid = await auth.password.verify(password, hash);
97
+ const valid = await auth.password.verify({ password, storedHash: hash });
75
98
  ```
76
99
 
77
100
  Applications whose database contains bcrypt hashes select bcrypt explicitly:
@@ -81,11 +104,21 @@ const auth = createAuth({
81
104
  password: {
82
105
  algorithm: "bcrypt",
83
106
  },
84
- redis: createRedisStore(redis),
85
- audit,
107
+ redis: createRedisStore({ client: redis }),
108
+ records,
86
109
  });
87
110
  ```
88
111
 
112
+ New bcrypt hashes reject passwords above 72 bytes. Applications with historical hashes created from longer bcrypt input can opt into a larger verification-only boundary without permitting new truncated hashes:
113
+
114
+ ```ts
115
+ password: {
116
+ algorithm: "bcrypt",
117
+ maxBytes: 72,
118
+ verifyMaxBytes: 1024,
119
+ }
120
+ ```
121
+
89
122
  The configured algorithm is used for both hashing and verification. The package does not detect, convert, migrate, or fall back to another algorithm.
90
123
 
91
124
  ## Login
@@ -97,22 +130,26 @@ app.post("/auth/login", async (c) => {
97
130
  const { email, password } = await c.req.json();
98
131
  const account = await findAccount(email);
99
132
 
100
- if (!account || !(await auth.password.verify(password, account.passwordHash))) {
133
+ if (
134
+ !account ||
135
+ !(await auth.password.verify({
136
+ password,
137
+ storedHash: account.passwordHash,
138
+ }))
139
+ ) {
101
140
  return c.json({ error: "Invalid credentials." }, 401);
102
141
  }
103
142
 
104
- const created = await auth.session.create({
105
- subjectId: account.id,
143
+ const session = await hono.createSession({
144
+ accountId: account.id,
145
+ context: c,
106
146
  data: {
107
147
  email: account.email,
108
148
  role: account.role,
109
149
  },
110
- client: await getClient(c),
111
150
  });
112
151
 
113
- hono.setSession(c, created);
114
-
115
- return c.json({ account: created.session.data });
152
+ return c.json({ account: session.data });
116
153
  });
117
154
  ```
118
155
 
@@ -122,14 +159,14 @@ Applications must apply their own login rate limiting and account-enumeration pr
122
159
 
123
160
  ```ts
124
161
  app.get("/account", hono.requireSession, async (c) => {
125
- const session = c.get("authSession");
126
- const account = await findAccountById(session.subjectId);
162
+ const session = c.get("session");
163
+ const account = await findAccountById(session.accountId);
127
164
 
128
165
  return c.json({ account });
129
166
  });
130
167
  ```
131
168
 
132
- The middleware reads the cookie, resolves Redis, compares IP and User-Agent, renews expiry when due, and places the typed session in the Hono context. It does not load application data from the database.
169
+ The middleware reads the cookie, resolves Redis, compares the configured client fields, renews expiry when due, and places the typed session in the Hono context. It does not load application data from the database.
133
170
 
134
171
  Applications that need to populate additional Hono context variables can resolve through the same adapter without duplicating its cookie behavior:
135
172
 
@@ -146,54 +183,54 @@ const requireAccount = async (c, next) => {
146
183
 
147
184
  ```ts
148
185
  app.post("/auth/logout", async (c) => {
149
- const token = hono.getToken(c);
150
-
151
- if (token) {
152
- await auth.session.revokeToken(token);
153
- }
154
-
155
- hono.clearSession(c);
186
+ await hono.revokeSession(c);
156
187
  return c.body(null, 204);
157
188
  });
158
189
  ```
159
190
 
191
+ The adapter clears the cookie only after backend revocation succeeds. Infrastructure errors are
192
+ propagated so the application can return its own service-error response.
193
+
160
194
  ## Active sessions
161
195
 
162
196
  ```ts
163
197
  const sessions = await auth.session.list(accountId);
164
198
 
165
199
  await auth.session.revoke({
166
- subjectId: accountId,
200
+ accountId,
167
201
  sessionId,
168
202
  });
169
203
 
170
- await auth.session.revokeSubject(accountId);
204
+ await auth.session.revokeAccount(accountId);
171
205
  ```
172
206
 
173
- The audit database supplies session history. Redis is checked in a batch before a session is reported as active. Token hashes are never returned by `list`.
207
+ The records database supplies session history. Redis is checked in a batch before a session is reported as active. Token hashes are never returned by `list`.
174
208
 
175
209
  ## Synchronizing session data
176
210
 
177
211
  When cached session claims change:
178
212
 
179
213
  ```ts
180
- await auth.session.sync(accountId, {
181
- email: account.email,
182
- role: account.role,
214
+ await auth.session.sync({
215
+ accountId,
216
+ data: {
217
+ email: account.email,
218
+ role: account.role,
219
+ },
183
220
  });
184
221
  ```
185
222
 
186
223
  Synchronization preserves the existing token and Redis TTL.
187
224
 
188
- ## Session audit contract
225
+ ## Session records contract
189
226
 
190
- Each consuming application maps `SessionAudit` to its database. The durable record contains:
227
+ Each consuming application maps `SessionRecords` to its database. The durable record contains:
191
228
 
192
229
  - Session ID.
193
- - Subject ID and relation owned by the application.
230
+ - Account ID and relation owned by the application.
194
231
  - SHA-256 token hash.
195
232
  - Canonical IP.
196
- - Country and platform metadata.
233
+ - Platform metadata.
197
234
  - Complete User-Agent.
198
235
  - Creation, current expiry, update, and revocation timestamps.
199
236
 
@@ -206,8 +243,9 @@ Defaults:
206
243
  ```ts
207
244
  session: {
208
245
  ttl: 7 * 24 * 60 * 60,
209
- touchAfter: 24 * 60 * 60,
246
+ renewInterval: 24 * 60 * 60,
210
247
  max: 10,
248
+ validation: ["userAgent"],
211
249
  }
212
250
  ```
213
251
 
@@ -215,24 +253,31 @@ session: {
215
253
  - Active sessions renew at most once every 24 hours.
216
254
  - Renewal keeps the same browser token.
217
255
  - There is no absolute session lifetime.
256
+ - Every successful `resolve` call counts as activity and renews the session when due.
218
257
 
219
- Consumers that validate sessions without being able to update the browser cookie, such as an established WebSocket connection, must disable renewal for that check:
258
+ ## Client validation
259
+
260
+ The default compares only the complete User-Agent:
220
261
 
221
262
  ```ts
222
- await auth.session.resolve({
223
- client,
224
- renew: false,
225
- token,
226
- });
263
+ session: {
264
+ validation: ["userAgent"],
265
+ }
227
266
  ```
228
267
 
229
- HTTP requests can then renew Redis, the audit record, and the cookie together.
268
+ Applications can choose any combination of `ip`, `userAgent`, and `platform`:
269
+
270
+ ```ts
271
+ session: {
272
+ validation: ["ip", "userAgent", "platform"],
273
+ }
274
+ ```
230
275
 
231
- ## Client mismatch
276
+ An empty array disables client-field comparison and validates only the session token. Unknown or duplicate fields are rejected during startup.
232
277
 
233
- If the canonical IP or complete User-Agent differs, the package deletes the Redis session first and marks its audit record as revoked. Clearing the response cookie is client cleanup; Redis deletion is what removes access.
278
+ If a configured field differs, the package deletes the Redis session first and marks its database record as revoked. Clearing the response cookie is client cleanup; Redis deletion is what removes access.
234
279
 
235
- Strict IP binding can log out legitimate users whose public IP changes. It is defense in depth and does not replace TLS, secure cookies, CSRF protection, XSS prevention, or re-authentication for sensitive actions.
280
+ Exact IP validation is opt-in because VPN, mobile, and other networks can change a legitimate user's public IP. Platform validation is also opt-in because the client-hint header may be absent. Client-field validation is defense in depth and does not replace TLS, secure cookies, CSRF protection, XSS prevention, or re-authentication for sensitive actions.
236
281
 
237
282
  ## Package exports
238
283
 
@@ -241,5 +286,3 @@ Strict IP binding can log out legitimate users whose public IP changes. It is de
241
286
  @gauts/auth/redis createRedisStore
242
287
  @gauts/auth/hono createHonoAdapter
243
288
  ```
244
-
245
- See [`PLAN.md`](./PLAN.md) for the implementation phases and complete security decisions.
package/SECURITY.md CHANGED
@@ -1,5 +1,3 @@
1
1
  # Security Policy
2
2
 
3
- `@gauts/auth` is not published yet and currently has no supported release.
4
-
5
- Do not open a public issue for a suspected vulnerability. Contact the package owner privately with a minimal reproduction and impact description.
3
+ {}
@@ -1,9 +1,8 @@
1
1
  import type { Context, Env, MiddlewareHandler } from "hono";
2
2
  import type { Auth } from "../../auth.js";
3
- import type { SessionClientInput } from "../../client/index.js";
4
- import type { CreatedSession, Session } from "../../session/types.js";
3
+ import type { Session } from "../../session/types.js";
5
4
  export type HonoAuthVariables<TData extends object> = {
6
- authSession: Session<TData>;
5
+ session: Session<TData>;
7
6
  };
8
7
  export type HonoAuthEnv<TData extends object> = Env & {
9
8
  Variables: HonoAuthVariables<TData>;
@@ -18,14 +17,21 @@ export type HonoCookieConfig = {
18
17
  export type HonoAdapterConfig<TData extends object> = {
19
18
  auth: Auth<TData>;
20
19
  cookie?: HonoCookieConfig;
21
- getClient: (c: Context) => Promise<SessionClientInput> | SessionClientInput;
20
+ getIp: (c: Context) => Promise<string | null | undefined> | string | null | undefined;
21
+ };
22
+ type CreateSessionInput<TData extends object> = {
23
+ accountId: string;
24
+ context: Context;
25
+ data: TData;
22
26
  };
23
27
  export type HonoAdapter<TData extends object> = {
24
28
  clearSession(c: Context): void;
29
+ createSession(input: CreateSessionInput<TData>): Promise<Session<TData>>;
25
30
  getToken(c: Context): string | null;
26
31
  requireSession: MiddlewareHandler<HonoAuthEnv<TData>>;
27
32
  resolveSession(c: Context): Promise<Session<TData>>;
28
- setSession(c: Context, created: CreatedSession<TData>): void;
33
+ revokeSession(c: Context): Promise<string[]>;
29
34
  };
30
- export declare const createHonoAdapter: <TData extends object>({ auth, cookie, getClient, }: HonoAdapterConfig<TData>) => HonoAdapter<TData>;
35
+ export declare const createHonoAdapter: <TData extends object>({ auth, cookie, getIp, }: HonoAdapterConfig<TData>) => HonoAdapter<TData>;
36
+ export {};
31
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/hono/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,MAAM,IAAI;IACpD,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,MAAM,IAAI,GAAG,GAAG;IACpD,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,MAAM,IAAI;IACpD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;CAC7E,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,MAAM,IAAI;IAC9C,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACpD,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;CAC9D,CAAC;AA6CF,eAAO,MAAM,iBAAiB,GAAI,KAAK,SAAS,MAAM,EAAE,8BAIrD,iBAAiB,CAAC,KAAK,CAAC,KAAG,WAAW,CAAC,KAAK,CAoE9C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/hono/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE5D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAG1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,MAAM,IAAI;IACpD,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,MAAM,IAAI,GAAG,GAAG;IACpD,SAAS,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,MAAM,IAAI;IACpD,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,EAAE,CACL,CAAC,EAAE,OAAO,KACP,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrE,CAAC;AAEF,KAAK,kBAAkB,CAAC,KAAK,SAAS,MAAM,IAAI;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,KAAK,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,KAAK,SAAS,MAAM,IAAI;IAC9C,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACzE,QAAQ,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,EAAE,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACpD,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC9C,CAAC;AA4DF,eAAO,MAAM,iBAAiB,GAAI,KAAK,SAAS,MAAM,EAAE,0BAIrD,iBAAiB,CAAC,KAAK,CAAC,KAAG,WAAW,CAAC,KAAK,CAkI9C,CAAC"}
@@ -7,19 +7,35 @@ const resolveCookie = (config = {}) => {
7
7
  const sameSite = config.sameSite ?? "Lax";
8
8
  const secure = config.secure ?? true;
9
9
  if (!COOKIE_NAME_PATTERN.test(name)) {
10
- throw createError("AUTH_CONFIG_INVALID", "Session cookie name is invalid.");
10
+ throw createError({
11
+ code: "AUTH_CONFIG_INVALID",
12
+ message: "Session cookie name is invalid.",
13
+ });
11
14
  }
12
15
  if (!path.startsWith("/")) {
13
- throw createError("AUTH_CONFIG_INVALID", "Session cookie path must start with /.");
16
+ throw createError({
17
+ code: "AUTH_CONFIG_INVALID",
18
+ message: "Session cookie path must start with /.",
19
+ });
14
20
  }
15
- if (name.startsWith("__Host-") && (!secure || path !== "/" || config.domain)) {
16
- throw createError("AUTH_CONFIG_INVALID", "__Host- cookies require secure=true, path=/, and no domain.");
21
+ if (name.startsWith("__Host-") &&
22
+ (!secure || path !== "/" || config.domain)) {
23
+ throw createError({
24
+ code: "AUTH_CONFIG_INVALID",
25
+ message: "__Host- cookies require secure=true, path=/, and no domain.",
26
+ });
17
27
  }
18
28
  if (name.startsWith("__Secure-") && !secure) {
19
- throw createError("AUTH_CONFIG_INVALID", "__Secure- cookies require secure=true.");
29
+ throw createError({
30
+ code: "AUTH_CONFIG_INVALID",
31
+ message: "__Secure- cookies require secure=true.",
32
+ });
20
33
  }
21
34
  if (sameSite === "None" && !secure) {
22
- throw createError("AUTH_CONFIG_INVALID", "SameSite=None cookies require secure=true.");
35
+ throw createError({
36
+ code: "AUTH_CONFIG_INVALID",
37
+ message: "SameSite=None cookies require secure=true.",
38
+ });
23
39
  }
24
40
  return {
25
41
  name,
@@ -32,14 +48,25 @@ const resolveCookie = (config = {}) => {
32
48
  },
33
49
  };
34
50
  };
35
- export const createHonoAdapter = ({ auth, cookie, getClient, }) => {
51
+ export const createHonoAdapter = ({ auth, cookie, getIp, }) => {
52
+ if (typeof getIp !== "function") {
53
+ throw createError({
54
+ code: "AUTH_CONFIG_INVALID",
55
+ message: "Hono getIp must be a function.",
56
+ });
57
+ }
36
58
  const resolved = resolveCookie(cookie);
59
+ const getSessionClient = async (c) => ({
60
+ ip: (await getIp(c)) ?? null,
61
+ platform: c.req.header("sec-ch-ua-platform") ?? null,
62
+ userAgent: c.req.header("user-agent") ?? null,
63
+ });
37
64
  const getToken = (c) => {
38
65
  const token = getCookie(c, resolved.name)?.trim();
39
66
  return token?.length ? token : null;
40
67
  };
41
- const setToken = (c, token, expiresAt) => {
42
- setCookie(c, resolved.name, token, {
68
+ const setToken = ({ context, expiresAt, token, }) => {
69
+ setCookie(context, resolved.name, token, {
43
70
  ...resolved.options,
44
71
  expires: expiresAt,
45
72
  });
@@ -47,15 +74,31 @@ export const createHonoAdapter = ({ auth, cookie, getClient, }) => {
47
74
  const clearSession = (c) => {
48
75
  deleteCookie(c, resolved.name, resolved.options);
49
76
  };
77
+ const createSession = async ({ accountId, context, data, }) => {
78
+ const created = await auth.session.create({
79
+ accountId,
80
+ client: await getSessionClient(context),
81
+ data,
82
+ });
83
+ setToken({
84
+ context,
85
+ expiresAt: created.session.expiresAt,
86
+ token: created.token,
87
+ });
88
+ return created.session;
89
+ };
50
90
  const resolveSession = async (c) => {
51
91
  const token = getToken(c);
52
92
  if (!token) {
53
- throw createError("SESSION_INVALID", "Authentication required.");
93
+ throw createError({
94
+ code: "SESSION_INVALID",
95
+ message: "Authentication required.",
96
+ });
54
97
  }
55
98
  let resolvedSession;
56
99
  try {
57
100
  resolvedSession = await auth.session.resolve({
58
- client: await getClient(c),
101
+ client: await getSessionClient(c),
59
102
  token,
60
103
  });
61
104
  }
@@ -67,25 +110,37 @@ export const createHonoAdapter = ({ auth, cookie, getClient, }) => {
67
110
  }
68
111
  if (!resolvedSession) {
69
112
  clearSession(c);
70
- throw createError("SESSION_INVALID", "Authentication required.");
113
+ throw createError({
114
+ code: "SESSION_INVALID",
115
+ message: "Authentication required.",
116
+ });
71
117
  }
72
118
  if (resolvedSession.renewed) {
73
- setToken(c, token, resolvedSession.session.expiresAt);
119
+ setToken({
120
+ context: c,
121
+ expiresAt: resolvedSession.session.expiresAt,
122
+ token,
123
+ });
74
124
  }
75
125
  return resolvedSession.session;
76
126
  };
77
127
  const requireSession = async (c, next) => {
78
- c.set("authSession", await resolveSession(c));
128
+ c.set("session", await resolveSession(c));
79
129
  await next();
80
130
  };
131
+ const revokeSession = async (c) => {
132
+ const token = getToken(c);
133
+ const revoked = token ? await auth.session.revokeToken(token) : [];
134
+ clearSession(c);
135
+ return revoked;
136
+ };
81
137
  return {
82
138
  clearSession,
139
+ createSession,
83
140
  getToken,
84
141
  requireSession,
85
142
  resolveSession,
86
- setSession: (c, created) => {
87
- setToken(c, created.token, created.session.expiresAt);
88
- },
143
+ revokeSession,
89
144
  };
90
145
  };
91
146
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/hono/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/hono/index.ts"],"names":[],"mappings":"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"}
@@ -3,5 +3,9 @@ import type { RedisSessionStore } from "../../session/types.js";
3
3
  export type RedisStoreConfig = {
4
4
  prefix?: string;
5
5
  };
6
- export declare const createRedisStore: (client: RedisClientType, config?: RedisStoreConfig) => RedisSessionStore;
6
+ export type RedisStoreInput = {
7
+ client: RedisClientType;
8
+ config?: RedisStoreConfig;
9
+ };
10
+ export declare const createRedisStore: ({ client, config, }: RedisStoreInput) => RedisSessionStore;
7
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAG7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAaF,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,eAAe,EACvB,SAAQ,gBAAqB,KAC5B,iBAsDF,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/redis/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAgBF,eAAO,MAAM,gBAAgB,GAAI,qBAG9B,eAAe,KAAG,iBA8DpB,CAAC"}
@@ -3,16 +3,22 @@ const getPrefix = (input) => {
3
3
  const candidate = input?.trim();
4
4
  const prefix = candidate?.length ? candidate : "gauts:auth";
5
5
  if (prefix.length > 128 || !/^[A-Za-z0-9:_-]+$/.test(prefix)) {
6
- throw createError("AUTH_CONFIG_INVALID", "Redis key prefix is invalid.");
6
+ throw createError({
7
+ code: "AUTH_CONFIG_INVALID",
8
+ message: "Redis key prefix is invalid.",
9
+ });
7
10
  }
8
11
  return prefix.replace(/:+$/g, "");
9
12
  };
10
- export const createRedisStore = (client, config = {}) => {
13
+ export const createRedisStore = ({ client, config = {}, }) => {
11
14
  const prefix = getPrefix(config.prefix);
12
15
  const getKey = (tokenHash) => `${prefix}:session:${tokenHash}`;
13
16
  return {
14
- create: async (tokenHash, value, ttl) => {
15
- const result = await client.set(getKey(tokenHash), value, { EX: ttl, NX: true });
17
+ create: async ({ tokenHash, ttl, value }) => {
18
+ const result = await client.set(getKey(tokenHash), value, {
19
+ EX: ttl,
20
+ NX: true,
21
+ });
16
22
  if (result !== "OK") {
17
23
  throw new Error("Redis session key already exists.");
18
24
  }
@@ -25,11 +31,14 @@ export const createRedisStore = (client, config = {}) => {
25
31
  ? []
26
32
  : client.mGet(tokenHashes.map((tokenHash) => getKey(tokenHash)));
27
33
  },
28
- update: async (tokenHash, value, ttl) => {
29
- const result = await client.set(getKey(tokenHash), value, { EX: ttl, XX: true });
34
+ update: async ({ tokenHash, ttl, value }) => {
35
+ const result = await client.set(getKey(tokenHash), value, {
36
+ EX: ttl,
37
+ XX: true,
38
+ });
30
39
  return result === "OK";
31
40
  },
32
- keep: async (tokenHash, value) => {
41
+ keep: async ({ tokenHash, value }) => {
33
42
  const result = await client.set(getKey(tokenHash), value, {
34
43
  KEEPTTL: true,
35
44
  XX: true,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/redis/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/redis/index.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import type { PasswordConfig, SessionConfig } from "./config.js";
2
2
  import { type PasswordService } from "./password/index.js";
3
- import type { RedisSessionStore, SessionAudit, SessionService } from "./session/types.js";
3
+ import type { RedisSessionStore, SessionRecords, SessionService } from "./session/types.js";
4
4
  export type AuthConfig = {
5
5
  password?: PasswordConfig;
6
6
  session?: SessionConfig;
7
7
  };
8
8
  export type AuthDeps = AuthConfig & {
9
- audit: SessionAudit;
9
+ records: SessionRecords;
10
10
  redis: RedisSessionStore;
11
11
  };
12
12
  export type Auth<TData extends object> = {
13
13
  password: PasswordService;
14
14
  session: SessionService<TData>;
15
15
  };
16
- export declare const createAuth: <TData extends object = Record<string, unknown>>({ audit, password, redis, session, }: AuthDeps) => Auth<TData>;
16
+ export declare const createAuth: <TData extends object = Record<string, unknown>>({ password, records, redis, session, }: AuthDeps) => Auth<TData>;
17
17
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE1F,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG;IAClC,KAAK,EAAE,YAAY,CAAC;IACpB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,MAAM,IAAI;IACvC,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;CAChC,CAAC;AAcF,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,sCAKxE,QAAQ,KAAG,IAAI,CAAC,KAAK,CAoBvB,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,EACf,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,iBAAiB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,MAAM,IAAI;IACvC,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;CAChC,CAAC;AA8BF,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,wCAKxE,QAAQ,KAAG,IAAI,CAAC,KAAK,CAoBvB,CAAC"}