@soulcraft/sdk 2.6.1 → 3.0.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 (59) hide show
  1. package/dist/modules/auth/backchannel.d.ts +13 -39
  2. package/dist/modules/auth/backchannel.d.ts.map +1 -1
  3. package/dist/modules/auth/backchannel.js +12 -144
  4. package/dist/modules/auth/backchannel.js.map +1 -1
  5. package/dist/modules/auth/middleware.d.ts +45 -157
  6. package/dist/modules/auth/middleware.d.ts.map +1 -1
  7. package/dist/modules/auth/middleware.js +40 -322
  8. package/dist/modules/auth/middleware.js.map +1 -1
  9. package/dist/modules/auth/products.d.ts +1 -1
  10. package/dist/modules/auth/products.js +1 -1
  11. package/dist/modules/auth/request-backchannel.d.ts +94 -0
  12. package/dist/modules/auth/request-backchannel.d.ts.map +1 -0
  13. package/dist/modules/auth/request-backchannel.js +206 -0
  14. package/dist/modules/auth/request-backchannel.js.map +1 -0
  15. package/dist/modules/auth/request-middleware.d.ts +438 -0
  16. package/dist/modules/auth/request-middleware.d.ts.map +1 -0
  17. package/dist/modules/auth/request-middleware.js +650 -0
  18. package/dist/modules/auth/request-middleware.js.map +1 -0
  19. package/dist/modules/auth/service-token.d.ts +8 -7
  20. package/dist/modules/auth/service-token.d.ts.map +1 -1
  21. package/dist/modules/auth/service-token.js +8 -7
  22. package/dist/modules/auth/service-token.js.map +1 -1
  23. package/dist/modules/auth/sveltekit.d.ts +1 -1
  24. package/dist/modules/auth/sveltekit.d.ts.map +1 -1
  25. package/dist/modules/auth/sveltekit.js +1 -1
  26. package/dist/modules/auth/sveltekit.js.map +1 -1
  27. package/dist/namespaces.d.ts +1 -1
  28. package/dist/server/handlers/export.js +1 -1
  29. package/dist/server/handlers/export.js.map +1 -1
  30. package/dist/server/handlers/workspace.d.ts +1 -1
  31. package/dist/server/handlers/workspace.d.ts.map +1 -1
  32. package/dist/server/handlers/workspace.js +3 -4
  33. package/dist/server/handlers/workspace.js.map +1 -1
  34. package/dist/server/index.d.ts +5 -12
  35. package/dist/server/index.d.ts.map +1 -1
  36. package/dist/server/index.js +4 -9
  37. package/dist/server/index.js.map +1 -1
  38. package/dist/server/instance-pool.d.ts.map +1 -1
  39. package/dist/server/instance-pool.js +1 -0
  40. package/dist/server/instance-pool.js.map +1 -1
  41. package/dist/server/namespace-router.d.ts +1 -1
  42. package/dist/server/namespace-router.js +1 -1
  43. package/dist/server/rpc-handler.d.ts +2 -9
  44. package/dist/server/rpc-handler.d.ts.map +1 -1
  45. package/dist/server/rpc-handler.js +2 -9
  46. package/dist/server/rpc-handler.js.map +1 -1
  47. package/docs/ADR-001-sdk-design.md +3 -3
  48. package/docs/ADR-004-product-registry.md +1 -1
  49. package/docs/ADR-005-hall-integration.md +1 -1
  50. package/docs/ADR-006-rpc-cache.md +2 -2
  51. package/docs/IMPLEMENTATION-PLAN.md +7 -7
  52. package/docs/KIT-APP-GUIDE.md +100 -99
  53. package/docs/USAGE.md +30 -40
  54. package/docs/kit-sdk-guide.md +59 -60
  55. package/package.json +2 -7
  56. package/dist/server/hono-router.d.ts +0 -70
  57. package/dist/server/hono-router.d.ts.map +0 -1
  58. package/dist/server/hono-router.js +0 -167
  59. package/dist/server/hono-router.js.map +0 -1
@@ -1,12 +1,11 @@
1
1
  /**
2
2
  * @module modules/auth/middleware
3
- * @description Hono auth middleware factories, remote session verification, and
4
- * dev/guest session utilities for Soulcraft product backends.
3
+ * @description Session verification factories and shared auth types for Soulcraft
4
+ * product backends.
5
5
  *
6
6
  * ## Session verification strategies
7
7
  *
8
- * All products share the same `createAuthMiddleware` factory, but each product
9
- * selects the right session verifier for its deployment context:
8
+ * All products select the right session verifier for their deployment context:
10
9
  *
11
10
  * ```
12
11
  * Production (all products):
@@ -14,57 +13,45 @@
14
13
  *
15
14
  * Development (all products):
16
15
  * createDevSessionVerifier({ role: 'owner' }) // auto-login, no OAuth needed
17
- *
18
- * Workshop standalone (legacy / local OAuth):
19
- * createAuthMiddleware(betterAuthInstance) // BetterAuthLike overload
20
16
  * ```
21
17
  *
22
- * ## Dev and guest endpoint factories
18
+ * ## Dev and guest cookie verifiers
19
+ *
20
+ * - `createDevCookieVerifier` — reads the dev session cookie issued by
21
+ * `createRequestDevLoginHandler` (from `request-middleware.ts`).
22
+ * - `createGuestCookieVerifier` — reads the guest session cookie issued by
23
+ * `createRequestGuestSessionHandler` (from `request-middleware.ts`).
24
+ *
25
+ * ## Framework-agnostic middleware
23
26
  *
24
- * - `createDevLoginHandler` mounts a `/api/dev/login` endpoint for role-switching
25
- * during development. Issues a signed dev session cookie. No-ops in production.
26
- * - `createGuestSessionHandler` mounts a `/api/guest/session` endpoint so Venue
27
- * visitors can obtain a guest session (platformRole `'guest'`) for anonymous
28
- * browse and booking flows, before they create an account.
27
+ * Use `createRequestAuthMiddleware` from `request-middleware.ts` for the
28
+ * framework-agnostic middleware that works with any Web Standard Request/Response
29
+ * server (SvelteKit, Bun, Deno, Cloudflare Workers, etc.).
29
30
  *
30
31
  * @example Production setup (Venue / Academy)
31
32
  * ```typescript
32
- * import { createAuthMiddleware, createRemoteSessionVerifier } from '@soulcraft/sdk/server'
33
+ * import {
34
+ * createRequestAuthMiddleware,
35
+ * createRemoteSessionVerifier,
36
+ * getUser,
37
+ * } from '@soulcraft/sdk/server'
33
38
  *
34
39
  * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
35
- * const { requireAuth, optionalAuth } = createAuthMiddleware(verifySession)
40
+ * const { requireAuth } = createRequestAuthMiddleware(verifySession)
36
41
  *
37
- * app.get('/api/bookings', requireAuth, async (c) => {
38
- * const user = c.get('user')! // SoulcraftSessionUser
39
- * })
42
+ * // SvelteKit hooks:
43
+ * export const handle = async ({ event, resolve }) => {
44
+ * const response = await requireAuth(event.request, () => resolve(event))
45
+ * event.locals.user = getUser(event.request)
46
+ * return response
47
+ * }
40
48
  * ```
41
49
  */
42
50
  import { LRUCache } from 'lru-cache';
43
51
  import { computeEmailHash } from './config.js';
44
52
  // ─────────────────────────────────────────────────────────────────────────────
45
- // Types
46
- // ─────────────────────────────────────────────────────────────────────────────
47
- /** The Hono context variable key where the resolved user is stored. */
48
- export const AUTH_USER_KEY = 'user';
49
- // ─────────────────────────────────────────────────────────────────────────────
50
53
  // Shared internal helpers
51
54
  // ─────────────────────────────────────────────────────────────────────────────
52
- /** Resolve a raw user record from a better-auth session into a `SoulcraftSessionUser`. */
53
- function _resolveUser(raw) {
54
- const email = String(raw['email'] ?? '');
55
- const emailHash = raw['emailHash']
56
- ? String(raw['emailHash'])
57
- : computeEmailHash(email);
58
- return {
59
- id: String(raw['id'] ?? ''),
60
- email,
61
- name: String(raw['name'] ?? ''),
62
- image: raw['image'] ?? null,
63
- platformRole: raw['platformRole'] ?? 'creator',
64
- emailHash,
65
- ...(raw['handle'] ? { handle: String(raw['handle']) } : {}),
66
- };
67
- }
68
55
  /** Parse a simple `name=value` cookie from a raw cookie header string. */
69
56
  function _parseCookie(cookieHeader, name) {
70
57
  for (const part of cookieHeader.split(';')) {
@@ -74,10 +61,6 @@ function _parseCookie(cookieHeader, name) {
74
61
  }
75
62
  return undefined;
76
63
  }
77
- /** Encode a dev/guest session payload as a compact JSON+base64url string (unsigned). */
78
- function _encodeSessionCookie(session) {
79
- return Buffer.from(JSON.stringify(session)).toString('base64url');
80
- }
81
64
  /** Decode a session payload encoded by `_encodeSessionCookie`. Returns null on any error. */
82
65
  function _decodeSessionCookie(value) {
83
66
  try {
@@ -93,108 +76,6 @@ function _decodeSessionCookie(value) {
93
76
  }
94
77
  }
95
78
  // ─────────────────────────────────────────────────────────────────────────────
96
- // createAuthMiddleware
97
- // ─────────────────────────────────────────────────────────────────────────────
98
- /**
99
- * Creates Hono auth middleware from a `SessionVerifier` function or a `BetterAuthLike`
100
- * instance.
101
- *
102
- * **Preferred form (all products in OIDC-client mode):**
103
- * Pass a `SessionVerifier` returned by `createRemoteSessionVerifier` or
104
- * `createDevSessionVerifier`. The middleware reads the request cookie header and
105
- * passes it to the verifier.
106
- *
107
- * **Legacy form (Workshop standalone mode):**
108
- * Pass a `better-auth` instance directly. The middleware calls `auth.api.getSession`.
109
- * In non-production environments and when `devAutoLogin` is enabled, a synthetic dev
110
- * user is injected on failed lookups so local dev works without OAuth.
111
- *
112
- * Both forms return identical `{ requireAuth, optionalAuth }` middleware.
113
- *
114
- * @param authOrVerifier - A `better-auth` instance or a `SessionVerifier` function.
115
- * @param options - Optional middleware configuration (only applies to `BetterAuthLike` form).
116
- * @returns Middleware pair: `{ requireAuth, optionalAuth }`.
117
- *
118
- * @example Verifier form (Venue / Academy / Workshop in OIDC mode)
119
- * ```typescript
120
- * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
121
- * const { requireAuth } = createAuthMiddleware(verifySession)
122
- * ```
123
- *
124
- * @example BetterAuth form (Workshop dev standalone)
125
- * ```typescript
126
- * import { auth } from './better-auth.js'
127
- * const { requireAuth } = createAuthMiddleware(auth)
128
- * ```
129
- */
130
- export function createAuthMiddleware(authOrVerifier, options = {}) {
131
- const isVerifier = typeof authOrVerifier === 'function';
132
- if (isVerifier) {
133
- const verify = authOrVerifier;
134
- const requireAuth = async (c, next) => {
135
- const cookieHeader = c.req.header('cookie') ?? '';
136
- const session = await verify(cookieHeader);
137
- if (!session)
138
- return c.json({ error: 'Authentication required' }, 401);
139
- c.set(AUTH_USER_KEY, session.user);
140
- await next();
141
- return;
142
- };
143
- const optionalAuth = async (c, next) => {
144
- const cookieHeader = c.req.header('cookie') ?? '';
145
- const session = await verify(cookieHeader);
146
- c.set(AUTH_USER_KEY, session?.user ?? null);
147
- await next();
148
- };
149
- return { requireAuth, optionalAuth };
150
- }
151
- // BetterAuthLike form (Workshop standalone)
152
- const auth = authOrVerifier;
153
- const devAutoLogin = options.devAutoLogin ?? true;
154
- const isDev = process.env['NODE_ENV'] !== 'production';
155
- const DEV_USER = {
156
- id: 'dev-user-001',
157
- email: 'dev@localhost',
158
- name: 'Dev User',
159
- image: null,
160
- emailHash: computeEmailHash('dev@localhost'),
161
- platformRole: 'creator',
162
- handle: 'dev',
163
- };
164
- const requireAuth = async (c, next) => {
165
- if (isDev && devAutoLogin) {
166
- if (!c.get(AUTH_USER_KEY))
167
- c.set(AUTH_USER_KEY, DEV_USER);
168
- await next();
169
- return;
170
- }
171
- const session = await auth.api.getSession({ headers: c.req.raw.headers });
172
- if (!session?.user) {
173
- return c.json({ error: 'Authentication required' }, 401);
174
- }
175
- c.set(AUTH_USER_KEY, _resolveUser(session.user));
176
- await next();
177
- return;
178
- };
179
- const optionalAuth = async (c, next) => {
180
- if (isDev && devAutoLogin) {
181
- if (!c.get(AUTH_USER_KEY))
182
- c.set(AUTH_USER_KEY, DEV_USER);
183
- await next();
184
- return;
185
- }
186
- const session = await auth.api.getSession({ headers: c.req.raw.headers });
187
- if (session?.user) {
188
- c.set(AUTH_USER_KEY, _resolveUser(session.user));
189
- }
190
- else {
191
- c.set(AUTH_USER_KEY, null);
192
- }
193
- await next();
194
- };
195
- return { requireAuth, optionalAuth };
196
- }
197
- // ─────────────────────────────────────────────────────────────────────────────
198
79
  // createRemoteSessionVerifier
199
80
  // ─────────────────────────────────────────────────────────────────────────────
200
81
  /**
@@ -208,10 +89,10 @@ export function createAuthMiddleware(authOrVerifier, options = {}) {
208
89
  * The verifier sends the cookie header to the IdP's `/api/auth/get-session` endpoint
209
90
  * and returns the resolved `SoulcraftSession` or `null` if the session is invalid.
210
91
  *
211
- * Pass the returned function directly to `createAuthMiddleware`:
92
+ * Pass the returned function to `createRequestAuthMiddleware`:
212
93
  * ```typescript
213
94
  * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
214
- * const { requireAuth } = createAuthMiddleware(verifySession)
95
+ * const { requireAuth } = createRequestAuthMiddleware(verifySession)
215
96
  * ```
216
97
  *
217
98
  * @param options - IdP URL, cache TTL, and max cache size.
@@ -224,8 +105,8 @@ export function createAuthMiddleware(authOrVerifier, options = {}) {
224
105
  * cacheTtlMs: 30_000,
225
106
  * })
226
107
  *
227
- * const session = await verifySession(c.req.header('cookie') ?? '')
228
- * if (!session) return c.json({ error: 'Unauthorized' }, 401)
108
+ * const session = await verifySession(request.headers.get('cookie') ?? '')
109
+ * if (!session) return new Response('Unauthorized', { status: 401 })
229
110
  * ```
230
111
  */
231
112
  export function createRemoteSessionVerifier(options) {
@@ -306,7 +187,7 @@ export function createRemoteSessionVerifier(options) {
306
187
  * ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
307
188
  * : createDevSessionVerifier({ role: 'owner' })
308
189
  *
309
- * const { requireAuth } = createAuthMiddleware(verifySession)
190
+ * const { requireAuth } = createRequestAuthMiddleware(verifySession)
310
191
  * ```
311
192
  *
312
193
  * **Never use in production.** The verifier performs no validation whatsoever.
@@ -349,90 +230,12 @@ export function createDevSessionVerifier(options = {}) {
349
230
  };
350
231
  }
351
232
  // ─────────────────────────────────────────────────────────────────────────────
352
- // createDevLoginHandler
353
- // ─────────────────────────────────────────────────────────────────────────────
354
- /**
355
- * Creates a Hono request handler for a dev login endpoint.
356
- *
357
- * Mount at `/api/dev/login` to get a role-switching endpoint for local
358
- * development. Accepts `?role=<platformRole>` and optional `?email=` / `?name=`
359
- * query params. Issues a signed base64url session cookie that `createAuthMiddleware`
360
- * (when used with a `SessionVerifier` that reads dev cookies) can resolve.
361
- *
362
- * **Guards against production use:** the handler returns HTTP 404 when
363
- * `NODE_ENV === 'production'` — it is safe to leave mounted in all environments.
364
- *
365
- * @param options - Allowed roles, cookie name, and max-age.
366
- * @returns A Hono-compatible request handler `(c: Context) => Response`.
367
- *
368
- * @example
369
- * ```typescript
370
- * import { createDevLoginHandler } from '@soulcraft/sdk/server'
371
- *
372
- * // In your Hono server setup:
373
- * app.get('/api/dev/login', createDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] }))
374
- *
375
- * // Usage: GET /api/dev/login?role=staff → sets cookie + redirects to /
376
- * ```
377
- */
378
- export function createDevLoginHandler(options = {}) {
379
- const DEFAULT_ROLES = [
380
- 'creator', 'viewer', 'customer', 'staff', 'manager', 'owner', 'learner', 'instructor',
381
- ];
382
- const allowedRoles = options.allowedRoles ?? DEFAULT_ROLES;
383
- const cookieName = options.cookieName ?? 'soulcraft_dev_session';
384
- const maxAgeSeconds = options.maxAgeSeconds ?? 86_400;
385
- return function devLoginHandler(c) {
386
- if (process.env['NODE_ENV'] === 'production') {
387
- return c.json({ error: 'Not found' }, 404);
388
- }
389
- const role = c.req.query('role');
390
- if (!role || !allowedRoles.includes(role)) {
391
- return c.json({
392
- error: `Invalid role. Allowed: ${allowedRoles.join(', ')}`,
393
- allowedRoles,
394
- }, 400);
395
- }
396
- const email = c.req.query('email') ?? `dev-${role}@soulcraft.com`;
397
- const name = c.req.query('name') ?? `Dev ${role.charAt(0).toUpperCase() + role.slice(1)}`;
398
- const redirect = c.req.query('redirect') ?? '/';
399
- const session = {
400
- user: {
401
- id: `dev-user-${role}`,
402
- email,
403
- name,
404
- image: null,
405
- platformRole: role,
406
- emailHash: computeEmailHash(email),
407
- },
408
- sessionId: `dev-session-${Date.now()}`,
409
- expiresAt: Date.now() + maxAgeSeconds * 1000,
410
- };
411
- const cookieValue = _encodeSessionCookie(session);
412
- const cookieHeader = [
413
- `${cookieName}=${cookieValue}`,
414
- `Path=/`,
415
- `HttpOnly`,
416
- `SameSite=Lax`,
417
- `Max-Age=${maxAgeSeconds}`,
418
- ].join('; ');
419
- const response = new Response(null, {
420
- status: 302,
421
- headers: {
422
- Location: redirect,
423
- 'Set-Cookie': cookieHeader,
424
- },
425
- });
426
- return response;
427
- };
428
- }
429
- // ─────────────────────────────────────────────────────────────────────────────
430
233
  // createDevCookieVerifier
431
234
  // ─────────────────────────────────────────────────────────────────────────────
432
235
  /**
433
- * Creates a session verifier that reads the cookie issued by `createDevLoginHandler`.
236
+ * Creates a session verifier that reads the cookie issued by `createRequestDevLoginHandler`.
434
237
  *
435
- * Use this together with `createDevLoginHandler` when you want dev role-switching
238
+ * Use this together with `createRequestDevLoginHandler` when you want dev role-switching
436
239
  * (e.g. clicking "Login as Staff" in a dev UI) rather than a fixed synthetic user.
437
240
  *
438
241
  * The verifier decodes the base64url cookie value and returns the embedded session.
@@ -445,12 +248,12 @@ export function createDevLoginHandler(options = {}) {
445
248
  * const verifySession = createDevSessionVerifier({ role: 'owner' })
446
249
  *
447
250
  * // Option B: Role-switching dev login UI
448
- * app.get('/api/dev/login', createDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] }))
251
+ * const loginHandler = createRequestDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] })
449
252
  * const verifySession = createDevCookieVerifier()
450
253
  * ```
451
254
  *
452
- * @param cookieName - Must match the `cookieName` passed to `createDevLoginHandler`. Default: `'soulcraft_dev_session'`.
453
- * @returns A `SessionVerifier` compatible with `createAuthMiddleware`.
255
+ * @param cookieName - Must match the `cookieName` passed to `createRequestDevLoginHandler`. Default: `'soulcraft_dev_session'`.
256
+ * @returns A `SessionVerifier` compatible with `createRequestAuthMiddleware`.
454
257
  */
455
258
  export function createDevCookieVerifier(cookieName = 'soulcraft_dev_session') {
456
259
  return async function verifyDevCookie(cookieHeader) {
@@ -461,95 +264,10 @@ export function createDevCookieVerifier(cookieName = 'soulcraft_dev_session') {
461
264
  };
462
265
  }
463
266
  // ─────────────────────────────────────────────────────────────────────────────
464
- // createGuestSessionHandler
465
- // ─────────────────────────────────────────────────────────────────────────────
466
- /**
467
- * Creates a Hono request handler that issues a guest session cookie.
468
- *
469
- * Venue visitors can browse and initiate bookings without creating an account.
470
- * This handler mounts at e.g. `/api/guest/session` and issues a session cookie
471
- * with `platformRole: 'guest'` and a unique guest ID on each call (if no valid
472
- * guest session already exists).
473
- *
474
- * The guest session cookie can be verified using `createGuestCookieVerifier`,
475
- * which returns a `SessionVerifier` compatible with `createAuthMiddleware`.
476
- *
477
- * @param options - Cookie name, max-age, and optional `onGuestCreated` callback.
478
- * @returns A Hono-compatible request handler.
479
- *
480
- * @example
481
- * ```typescript
482
- * import { createGuestSessionHandler, createGuestCookieVerifier, createAuthMiddleware } from '@soulcraft/sdk/server'
483
- *
484
- * // Issue guest sessions
485
- * app.post('/api/guest/session', createGuestSessionHandler({
486
- * onGuestCreated: async (guestId) => {
487
- * await db.guests.insert({ id: guestId, createdAt: new Date() })
488
- * },
489
- * }))
490
- *
491
- * // Verify guest sessions in optional auth (guests can browse)
492
- * const verifyGuest = createGuestCookieVerifier()
493
- * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
494
- *
495
- * // Compose: check real session first, fall back to guest
496
- * const { optionalAuth } = createAuthMiddleware(async (cookie) =>
497
- * await verifySession(cookie) ?? await verifyGuest(cookie)
498
- * )
499
- * ```
500
- */
501
- export function createGuestSessionHandler(options = {}) {
502
- const cookieName = options.cookieName ?? 'soulcraft_guest_session';
503
- const maxAgeSeconds = options.maxAgeSeconds ?? 3_600;
504
- const onGuestCreated = options.onGuestCreated;
505
- return async function guestSessionHandler(c) {
506
- // Return existing guest session if still valid
507
- const cookieHeader = c.req.header('cookie') ?? '';
508
- const existingValue = _parseCookie(cookieHeader, cookieName);
509
- if (existingValue) {
510
- const existing = _decodeSessionCookie(existingValue);
511
- if (existing)
512
- return c.json({ guestId: existing.user.id, existing: true });
513
- }
514
- // Create a new guest session
515
- const guestId = `guest-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
516
- const email = `${guestId}@guest.soulcraft.com`;
517
- const session = {
518
- user: {
519
- id: guestId,
520
- email,
521
- name: 'Guest',
522
- image: null,
523
- platformRole: 'guest',
524
- emailHash: computeEmailHash(email),
525
- },
526
- sessionId: `guest-session-${Date.now()}`,
527
- expiresAt: Date.now() + maxAgeSeconds * 1000,
528
- };
529
- if (onGuestCreated)
530
- await onGuestCreated(guestId);
531
- const cookieValue = _encodeSessionCookie(session);
532
- const cookieHeader2 = [
533
- `${cookieName}=${cookieValue}`,
534
- `Path=/`,
535
- `HttpOnly`,
536
- `SameSite=Lax`,
537
- `Max-Age=${maxAgeSeconds}`,
538
- ].join('; ');
539
- return new Response(JSON.stringify({ guestId, existing: false }), {
540
- status: 200,
541
- headers: {
542
- 'Content-Type': 'application/json',
543
- 'Set-Cookie': cookieHeader2,
544
- },
545
- });
546
- };
547
- }
548
- // ─────────────────────────────────────────────────────────────────────────────
549
267
  // createGuestCookieVerifier
550
268
  // ─────────────────────────────────────────────────────────────────────────────
551
269
  /**
552
- * Creates a session verifier that reads the cookie issued by `createGuestSessionHandler`.
270
+ * Creates a session verifier that reads the cookie issued by `createRequestGuestSessionHandler`.
553
271
  *
554
272
  * Returns the guest `SoulcraftSession` or `null` if no valid guest cookie is present.
555
273
  * Compose with `createRemoteSessionVerifier` to allow both authenticated and guest access:
@@ -558,13 +276,13 @@ export function createGuestSessionHandler(options = {}) {
558
276
  * const verifyReal = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
559
277
  * const verifyGuest = createGuestCookieVerifier()
560
278
  *
561
- * const { optionalAuth } = createAuthMiddleware(async (cookie) =>
279
+ * const { optionalAuth } = createRequestAuthMiddleware(async (cookie) =>
562
280
  * await verifyReal(cookie) ?? await verifyGuest(cookie)
563
281
  * )
564
282
  * ```
565
283
  *
566
- * @param cookieName - Must match the `cookieName` passed to `createGuestSessionHandler`. Default: `'soulcraft_guest_session'`.
567
- * @returns A `SessionVerifier` compatible with `createAuthMiddleware`.
284
+ * @param cookieName - Must match the `cookieName` passed to `createRequestGuestSessionHandler`. Default: `'soulcraft_guest_session'`.
285
+ * @returns A `SessionVerifier` compatible with `createRequestAuthMiddleware`.
568
286
  */
569
287
  export function createGuestCookieVerifier(cookieName = 'soulcraft_guest_session') {
570
288
  return async function verifyGuestCookie(cookieHeader) {
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/modules/auth/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAI9C,gFAAgF;AAChF,QAAQ;AACR,gFAAgF;AAEhF,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAG,MAAe,CAAA;AAqI5C,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF,0FAA0F;AAC1F,SAAS,YAAY,CAAC,GAA4B;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC;QAChC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAE3B,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3B,KAAK;QACL,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,EAAG,GAAG,CAAC,OAAO,CAA+B,IAAI,IAAI;QAC1D,YAAY,EAAG,GAAG,CAAC,cAAc,CAA0C,IAAI,SAAS;QACxF,SAAS;QACT,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAA;AACH,CAAC;AAED,0EAA0E;AAC1E,SAAS,YAAY,CAAC,YAAoB,EAAE,IAAY;IACtD,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC3C,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IACtD,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,wFAAwF;AACxF,SAAS,oBAAoB,CAAC,OAAyB;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACnE,CAAC;AAED,6FAA6F;AAC7F,SAAS,oBAAoB,CAAC,KAAa;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAqB,CAAA;QAC7F,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,GAAG,CAAC,SAAS;YAAE,OAAO,IAAI,CAAA;QAC9D,IAAI,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,IAAI,CAAA;QAC3C,OAAO,GAAG,CAAA;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,uBAAuB;AACvB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,oBAAoB,CAClC,cAAgD,EAChD,UAAiC,EAAE;IAEnC,MAAM,UAAU,GAAG,OAAO,cAAc,KAAK,UAAU,CAAA;IAEvD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,cAAiC,CAAA;QAEhD,MAAM,WAAW,GAAkC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACnE,MAAM,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;YACjD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;YAC1C,IAAI,CAAC,OAAO;gBAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,CAAA;YACtE,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YAClC,MAAM,IAAI,EAAE,CAAA;YACZ,OAAM;QACR,CAAC,CAAA;QAED,MAAM,YAAY,GAAmC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACrE,MAAM,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;YACjD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAA;YAC1C,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,EAAE,IAAI,IAAI,IAAI,CAAC,CAAA;YAC3C,MAAM,IAAI,EAAE,CAAA;QACd,CAAC,CAAA;QAED,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAA;IACtC,CAAC;IAED,4CAA4C;IAC5C,MAAM,IAAI,GAAG,cAAgC,CAAA;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,IAAI,CAAA;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,CAAA;IAEtD,MAAM,QAAQ,GAAyB;QACrC,EAAE,EAAE,cAAc;QAClB,KAAK,EAAE,eAAe;QACtB,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,IAAI;QACX,SAAS,EAAE,gBAAgB,CAAC,eAAe,CAAC;QAC5C,YAAY,EAAE,SAAS;QACvB,MAAM,EAAE,KAAK;KACd,CAAA;IAED,MAAM,WAAW,GAAkC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACnE,IAAI,KAAK,IAAI,YAAY,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;gBAAE,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;YACzD,MAAM,IAAI,EAAE,CAAA;YACZ,OAAM;QACR,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACzE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;YACnB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC1D,CAAC;QAED,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;QAChD,MAAM,IAAI,EAAE,CAAA;QACZ,OAAM;IACR,CAAC,CAAA;IAED,MAAM,YAAY,GAAmC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACrE,IAAI,KAAK,IAAI,YAAY,EAAE,CAAC;YAC1B,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;gBAAE,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAA;YACzD,MAAM,IAAI,EAAE,CAAA;YACZ,OAAM;QACR,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;QACzE,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;YAClB,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAA;QAC5B,CAAC;QACD,MAAM,IAAI,EAAE,CAAA;IACd,CAAC,CAAA;IAED,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,CAAA;AACtC,CAAC;AAED,gFAAgF;AAChF,8BAA8B;AAC9B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,2BAA2B,CACzC,OAAqC;IAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,IAAI,MAAM,CAAA;IAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAA;IACxC,MAAM,UAAU,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAA;IAE9E,MAAM,KAAK,GAAG,IAAI,QAAQ,CAA2B;QACnD,GAAG,EAAE,QAAQ;QACb,GAAG,EAAE,QAAQ;KACd,CAAC,CAAA;IAEF,OAAO,KAAK,UAAU,mBAAmB,CACvC,YAAoB;QAEpB,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAA;QAE9B,iEAAiE;QACjE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACtC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAA;QAEvC,IAAI,QAAkB,CAAA;QACtB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE;gBACjC,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE;gBACjC,WAAW,EAAE,SAAS;aACvB,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,OAAO,IAAI,CAAA;QAE7B,IAAI,IAA6B,CAAA;QACjC,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAA;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAA;QACb,CAAC;QAED,2EAA2E;QAC3E,6EAA6E;QAC7E,wEAAwE;QACxE,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QAElD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAwC,CAAA;QACnE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAwC,CAAA;QAEzE,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAA;QAExC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QAC5C,MAAM,OAAO,GAAqB;YAChC,IAAI,EAAE;gBACJ,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC/B,KAAK;gBACL,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACnC,KAAK,EAAG,OAAO,CAAC,OAAO,CAA+B,IAAI,IAAI;gBAC9D,YAAY,EAAG,OAAO,CAAC,cAAc,CAA0C,IAAI,SAAS;gBAC5F,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBACxF,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpE;YACD,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACzC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;SAChD,CAAA;QAED,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAChC,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,wBAAwB,CACtC,UAAqC,EAAE;IAEvC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAA;IACpC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,mBAAmB,CAAA;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,CAAA;IAEvC,MAAM,OAAO,GAAqB;QAChC,IAAI,EAAE;YACJ,EAAE,EAAE,cAAc;YAClB,KAAK;YACL,IAAI;YACJ,KAAK,EAAE,IAAI;YACX,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC;YAClC,MAAM,EAAE,KAAK;SACd;QACD,SAAS,EAAE,iBAAiB;QAC5B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;KACjD,CAAA;IAED,OAAO,KAAK,UAAU,gBAAgB;QACpC,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAkC,EAAE;IAEpC,MAAM,aAAa,GAA2C;QAC5D,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY;KACtF,CAAA;IACD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,aAAa,CAAA;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,uBAAuB,CAAA;IAChE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,MAAM,CAAA;IAErD,OAAO,SAAS,eAAe,CAAC,CAAU;QACxC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;YAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,CAAA;QAC5C,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAqD,CAAA;QACpF,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,KAAK,EAAE,0BAA0B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBAC1D,YAAY;aACb,EACD,GAAG,CACJ,CAAA;QACH,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,gBAAgB,CAAA;QACjE,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QACzF,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,GAAG,CAAA;QAE/C,MAAM,OAAO,GAAqB;YAChC,IAAI,EAAE;gBACJ,EAAE,EAAE,YAAY,IAAI,EAAE;gBACtB,KAAK;gBACL,IAAI;gBACJ,KAAK,EAAE,IAAI;gBACX,YAAY,EAAE,IAAI;gBAClB,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC;aACnC;YACD,SAAS,EAAE,eAAe,IAAI,CAAC,GAAG,EAAE,EAAE;YACtC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,IAAI;SAC7C,CAAA;QAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;QACjD,MAAM,YAAY,GAAG;YACnB,GAAG,UAAU,IAAI,WAAW,EAAE;YAC9B,QAAQ;YACR,UAAU;YACV,cAAc;YACd,WAAW,aAAa,EAAE;SAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEZ,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE;YAClC,MAAM,EAAE,GAAG;YACX,OAAO,EAAE;gBACP,QAAQ,EAAE,QAAQ;gBAClB,YAAY,EAAE,YAAY;aAC3B;SACF,CAAC,CAAA;QACF,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAU,GAAG,uBAAuB;IAEpC,OAAO,KAAK,UAAU,eAAe,CAAC,YAAoB;QACxD,MAAM,KAAK,GAAG,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QACpD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QACvB,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAAsC,EAAE;IAExC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,yBAAyB,CAAA;IAClE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,KAAK,CAAA;IACpD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;IAE7C,OAAO,KAAK,UAAU,mBAAmB,CAAC,CAAU;QAClD,+CAA+C;QAC/C,MAAM,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;QACjD,MAAM,aAAa,GAAG,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAC5D,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAA;YACpD,IAAI,QAAQ;gBAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAC5E,CAAC;QAED,6BAA6B;QAC7B,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;QAC5F,MAAM,KAAK,GAAG,GAAG,OAAO,sBAAsB,CAAA;QAE9C,MAAM,OAAO,GAAqB;YAChC,IAAI,EAAE;gBACJ,EAAE,EAAE,OAAO;gBACX,KAAK;gBACL,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,IAAI;gBACX,YAAY,EAAE,OAAO;gBACrB,SAAS,EAAE,gBAAgB,CAAC,KAAK,CAAC;aACnC;YACD,SAAS,EAAE,iBAAiB,IAAI,CAAC,GAAG,EAAE,EAAE;YACxC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,IAAI;SAC7C,CAAA;QAED,IAAI,cAAc;YAAE,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;QAEjD,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAA;QACjD,MAAM,aAAa,GAAG;YACpB,GAAG,UAAU,IAAI,WAAW,EAAE;YAC9B,QAAQ;YACR,UAAU;YACV,cAAc;YACd,WAAW,aAAa,EAAE;SAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEZ,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;YAChE,MAAM,EAAE,GAAG;YACX,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,YAAY,EAAE,aAAa;aAC5B;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAAU,GAAG,yBAAyB;IAEtC,OAAO,KAAK,UAAU,iBAAiB,CAAC,YAAoB;QAC1D,MAAM,KAAK,GAAG,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QACpD,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QACvB,OAAO,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/modules/auth/middleware.ts"],"names":[],"mappings":"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"}
@@ -168,7 +168,7 @@ export type SoulcraftProduct = keyof typeof SOULCRAFT_PRODUCTS;
168
168
  *
169
169
  * Used by the auth server for:
170
170
  * - `betterAuth({ trustedOrigins: deriveOrigins() })` — callback URL validation
171
- * - `cors({ origin: deriveOrigins() })` — CORS preflight on the Hono layer
171
+ * - CORS origin allowlist for preflight validation
172
172
  *
173
173
  * @returns Deduplicated list of origin strings (scheme + host, no trailing slash).
174
174
  *
@@ -114,7 +114,7 @@ export const SOULCRAFT_PRODUCTS = {
114
114
  *
115
115
  * Used by the auth server for:
116
116
  * - `betterAuth({ trustedOrigins: deriveOrigins() })` — callback URL validation
117
- * - `cors({ origin: deriveOrigins() })` — CORS preflight on the Hono layer
117
+ * - CORS origin allowlist for preflight validation
118
118
  *
119
119
  * @returns Deduplicated list of origin strings (scheme + host, no trailing slash).
120
120
  *
@@ -0,0 +1,94 @@
1
+ /**
2
+ * @module modules/auth/request-backchannel
3
+ * @description Framework-agnostic OIDC back-channel logout handler using Web Standard
4
+ * Request/Response.
5
+ *
6
+ * Implements the OpenID Connect Back-Channel Logout 1.0 specification. When a user
7
+ * signs out of the central IdP (`auth.soulcraft.com`), the IdP POSTs a signed
8
+ * `logout_token` (HS256 JWT) to every registered product's back-channel logout
9
+ * endpoint. This handler verifies the token and deletes all active sessions for
10
+ * the identified user, ensuring immediate logout across all products.
11
+ *
12
+ * ## Protocol
13
+ *
14
+ * 1. IdP POSTs `application/x-www-form-urlencoded` body with `logout_token` field
15
+ * 2. Handler verifies HS256 JWT signature using the OIDC client secret
16
+ * 3. Handler validates standard claims: `iss`, `aud`, `events` (must contain
17
+ * `http://schemas.openid.net/event/backchannel-logout`)
18
+ * 4. Handler deletes all better-auth sessions for the `sub` (user ID) claim
19
+ * 5. Returns 200 on success, 400 for malformed tokens, 401 for bad signatures
20
+ *
21
+ * ## Mounting
22
+ *
23
+ * ```typescript
24
+ * import { createRequestBackchannelLogoutHandler } from '@soulcraft/sdk/server'
25
+ *
26
+ * const handleLogout = createRequestBackchannelLogoutHandler({
27
+ * auth,
28
+ * clientSecret: process.env.SOULCRAFT_OIDC_CLIENT_SECRET!,
29
+ * idpUrl: process.env.SOULCRAFT_IDP_URL!,
30
+ * clientId: process.env.SOULCRAFT_OIDC_CLIENT_ID!,
31
+ * })
32
+ *
33
+ * // SvelteKit: export const POST = ({ request }) => handleLogout(request)
34
+ * // Bun: if (url.pathname === '/api/auth/backchannel-logout') return handleLogout(req)
35
+ * ```
36
+ */
37
+ /** Minimal better-auth API surface needed for session deletion. */
38
+ export interface BackchannelAuthLike {
39
+ api: {
40
+ revokeUserSessions(opts: {
41
+ body: {
42
+ userId: string;
43
+ };
44
+ headers?: Headers;
45
+ }): Promise<unknown>;
46
+ };
47
+ }
48
+ /**
49
+ * @description Configuration for `createRequestBackchannelLogoutHandler()`.
50
+ */
51
+ export interface BackchannelLogoutConfig {
52
+ /** The product's better-auth instance (used to delete sessions). */
53
+ auth: BackchannelAuthLike;
54
+ /** This product's OIDC client secret — used to verify the logout_token signature. */
55
+ clientSecret: string;
56
+ /** The central IdP base URL — used to validate the `iss` claim. */
57
+ idpUrl: string;
58
+ /** This product's OIDC client ID — used to validate the `aud` claim. */
59
+ clientId: string;
60
+ }
61
+ /**
62
+ * @description Creates a framework-agnostic request handler for the OIDC back-channel
63
+ * logout endpoint.
64
+ *
65
+ * The handler:
66
+ * 1. Parses the `logout_token` from the form-encoded or JSON body
67
+ * 2. Verifies the HS256 JWT signature using the OIDC client secret
68
+ * 3. Validates `iss` (must match idpUrl), `aud` (must match clientId),
69
+ * and `events` (must contain the back-channel logout event URI)
70
+ * 4. Calls `auth.api.revokeUserSessions({ body: { userId: sub } })` to
71
+ * immediately invalidate all sessions for the identified user
72
+ * 5. Returns 200 on success, 400 for malformed/missing token, 401 for
73
+ * invalid signature or failed claims validation
74
+ *
75
+ * @param config - Auth instance, client secret, IdP URL, and client ID.
76
+ * @returns An async request handler function `(req: Request) => Promise<Response>`.
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * import { createRequestBackchannelLogoutHandler } from '@soulcraft/sdk/server'
81
+ *
82
+ * const handleLogout = createRequestBackchannelLogoutHandler({
83
+ * auth,
84
+ * clientSecret: process.env.SOULCRAFT_OIDC_CLIENT_SECRET!,
85
+ * idpUrl: process.env.SOULCRAFT_IDP_URL!,
86
+ * clientId: process.env.SOULCRAFT_OIDC_CLIENT_ID!,
87
+ * })
88
+ *
89
+ * // SvelteKit +server.ts:
90
+ * export const POST = ({ request }) => handleLogout(request)
91
+ * ```
92
+ */
93
+ export declare function createRequestBackchannelLogoutHandler(config: BackchannelLogoutConfig): (req: Request) => Promise<Response>;
94
+ //# sourceMappingURL=request-backchannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-backchannel.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/request-backchannel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAMH,mEAAmE;AACnE,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE;QACH,kBAAkB,CAAC,IAAI,EAAE;YAAE,IAAI,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAC;YAAC,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAC5F,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,oEAAoE;IACpE,IAAI,EAAE,mBAAmB,CAAA;IACzB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAA;CACjB;AA0ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,uBAAuB,GAC9B,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CA4FrC"}