@soulcraft/sdk 2.8.0 → 3.0.1

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 (52) hide show
  1. package/dist/modules/auth/products.d.ts +1 -1
  2. package/dist/modules/auth/products.js +1 -1
  3. package/dist/modules/auth/request-backchannel.d.ts +39 -6
  4. package/dist/modules/auth/request-backchannel.d.ts.map +1 -1
  5. package/dist/modules/auth/request-backchannel.js +15 -5
  6. package/dist/modules/auth/request-backchannel.js.map +1 -1
  7. package/dist/modules/auth/request-middleware.d.ts +267 -24
  8. package/dist/modules/auth/request-middleware.d.ts.map +1 -1
  9. package/dist/modules/auth/request-middleware.js +264 -23
  10. package/dist/modules/auth/request-middleware.js.map +1 -1
  11. package/dist/modules/auth/service-token.d.ts +8 -7
  12. package/dist/modules/auth/service-token.d.ts.map +1 -1
  13. package/dist/modules/auth/service-token.js +8 -7
  14. package/dist/modules/auth/service-token.js.map +1 -1
  15. package/dist/modules/auth/sveltekit.d.ts +1 -1
  16. package/dist/modules/auth/sveltekit.d.ts.map +1 -1
  17. package/dist/modules/auth/sveltekit.js +1 -1
  18. package/dist/modules/auth/sveltekit.js.map +1 -1
  19. package/dist/namespaces.d.ts +1 -1
  20. package/dist/server/handlers/export.js +1 -1
  21. package/dist/server/handlers/export.js.map +1 -1
  22. package/dist/server/handlers/workspace.d.ts +1 -1
  23. package/dist/server/handlers/workspace.d.ts.map +1 -1
  24. package/dist/server/handlers/workspace.js +3 -4
  25. package/dist/server/handlers/workspace.js.map +1 -1
  26. package/dist/server/index.d.ts +5 -14
  27. package/dist/server/index.d.ts.map +1 -1
  28. package/dist/server/index.js +3 -11
  29. package/dist/server/index.js.map +1 -1
  30. package/dist/server/namespace-router.d.ts +1 -1
  31. package/dist/server/namespace-router.js +1 -1
  32. package/dist/server/rpc-handler.d.ts +27 -20
  33. package/dist/server/rpc-handler.d.ts.map +1 -1
  34. package/dist/server/rpc-handler.js +20 -20
  35. package/dist/server/rpc-handler.js.map +1 -1
  36. package/docs/ADR-001-sdk-design.md +3 -3
  37. package/docs/ADR-004-product-registry.md +1 -1
  38. package/docs/ADR-005-hall-integration.md +1 -1
  39. package/docs/ADR-006-rpc-cache.md +2 -2
  40. package/docs/IMPLEMENTATION-PLAN.md +7 -7
  41. package/docs/KIT-APP-GUIDE.md +100 -99
  42. package/docs/USAGE.md +30 -40
  43. package/docs/kit-sdk-guide.md +59 -60
  44. package/package.json +1 -1
  45. package/dist/modules/auth/backchannel.d.ts +0 -98
  46. package/dist/modules/auth/backchannel.d.ts.map +0 -1
  47. package/dist/modules/auth/backchannel.js +0 -171
  48. package/dist/modules/auth/backchannel.js.map +0 -1
  49. package/dist/modules/auth/middleware.d.ts +0 -412
  50. package/dist/modules/auth/middleware.d.ts.map +0 -1
  51. package/dist/modules/auth/middleware.js +0 -586
  52. package/dist/modules/auth/middleware.js.map +0 -1
@@ -1,171 +0,0 @@
1
- /**
2
- * @module modules/auth/backchannel
3
- * @description OIDC back-channel logout handler factory for Soulcraft product backends.
4
- *
5
- * Implements the OpenID Connect Back-Channel Logout 1.0 specification. When a user
6
- * signs out of the central IdP (`auth.soulcraft.com`), the IdP POSTs a signed
7
- * `logout_token` (HS256 JWT) to every registered product's back-channel logout
8
- * endpoint. This handler verifies the token and deletes all active sessions for
9
- * the identified user, ensuring immediate logout across all products.
10
- *
11
- * ## Protocol
12
- *
13
- * 1. IdP POSTs `application/x-www-form-urlencoded` body with `logout_token` field
14
- * 2. Handler verifies HS256 JWT signature using the OIDC client secret
15
- * 3. Handler validates standard claims: `iss`, `aud`, `events` (must contain
16
- * `http://schemas.openid.net/event/backchannel-logout`)
17
- * 4. Handler deletes all better-auth sessions for the `sub` (user ID) claim
18
- * 5. Returns 200 on success, 400 for malformed tokens, 401 for bad signatures
19
- *
20
- * ## Mounting (Hono)
21
- *
22
- * ```typescript
23
- * import { createBackchannelLogoutHandler } from '@soulcraft/sdk/server'
24
- *
25
- * app.post('/api/auth/backchannel-logout', createBackchannelLogoutHandler({
26
- * auth,
27
- * clientSecret: process.env.SOULCRAFT_OIDC_CLIENT_SECRET!,
28
- * idpUrl: process.env.SOULCRAFT_IDP_URL!,
29
- * clientId: process.env.SOULCRAFT_OIDC_CLIENT_ID!,
30
- * }))
31
- * ```
32
- */
33
- // The OIDC back-channel logout events claim URI.
34
- const BACKCHANNEL_LOGOUT_EVENT = 'http://schemas.openid.net/event/backchannel-logout';
35
- // ─────────────────────────────────────────────────────────────────────────────
36
- // JWT verification helpers (Web Crypto API — no external deps)
37
- // ─────────────────────────────────────────────────────────────────────────────
38
- /**
39
- * Verify an HS256 JWT using the Web Crypto API.
40
- *
41
- * @param token - Raw JWT string (`header.payload.signature`).
42
- * @param secret - HMAC secret for signature verification.
43
- * @returns The decoded payload if the signature is valid, or null.
44
- */
45
- async function verifyHS256JWT(token, secret) {
46
- const parts = token.split('.');
47
- if (parts.length !== 3)
48
- return null;
49
- const [headerB64, payloadB64, sigB64] = parts;
50
- // Import the HMAC key
51
- let key;
52
- try {
53
- key = await crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
54
- }
55
- catch {
56
- return null;
57
- }
58
- // Verify signature over `header.payload`
59
- const signingInput = `${headerB64}.${payloadB64}`;
60
- let sigBytes;
61
- try {
62
- sigBytes = Uint8Array.from(atob(sigB64.replace(/-/g, '+').replace(/_/g, '/')), (c) => c.charCodeAt(0));
63
- }
64
- catch {
65
- return null;
66
- }
67
- const valid = await crypto.subtle.verify('HMAC', key, sigBytes.buffer, new TextEncoder().encode(signingInput));
68
- if (!valid)
69
- return null;
70
- // Decode payload
71
- try {
72
- const padded = payloadB64.replace(/-/g, '+').replace(/_/g, '/') +
73
- '=='.slice(0, (4 - (payloadB64.length % 4)) % 4);
74
- return JSON.parse(atob(padded));
75
- }
76
- catch {
77
- return null;
78
- }
79
- }
80
- // ─────────────────────────────────────────────────────────────────────────────
81
- // createBackchannelLogoutHandler
82
- // ─────────────────────────────────────────────────────────────────────────────
83
- /**
84
- * @description Creates a Hono route handler for the OIDC back-channel logout endpoint.
85
- *
86
- * Mount at `POST /api/auth/backchannel-logout`. The handler:
87
- * 1. Parses the `logout_token` from the form-encoded body
88
- * 2. Verifies the HS256 JWT signature using the OIDC client secret
89
- * 3. Validates `iss` (must match idpUrl), `aud` (must match clientId),
90
- * and `events` (must contain the back-channel logout event URI)
91
- * 4. Calls `auth.api.revokeUserSessions({ body: { userId: sub } })` to
92
- * immediately invalidate all sessions for the identified user
93
- * 5. Returns 200 on success, 400 for malformed/missing token, 401 for
94
- * invalid signature or failed claims validation
95
- *
96
- * @param config - Auth instance, client secret, IdP URL, and client ID.
97
- * @returns A Hono-compatible request handler function.
98
- *
99
- * @deprecated Use `createRequestBackchannelLogoutHandler` from `request-backchannel.ts` instead.
100
- * The Hono-specific handler will be removed in a future major version.
101
- *
102
- * @example
103
- * ```typescript
104
- * app.post('/api/auth/backchannel-logout', createBackchannelLogoutHandler({
105
- * auth,
106
- * clientSecret: process.env.SOULCRAFT_OIDC_CLIENT_SECRET!,
107
- * idpUrl: process.env.SOULCRAFT_IDP_URL!,
108
- * clientId: process.env.SOULCRAFT_OIDC_CLIENT_ID!,
109
- * }))
110
- * ```
111
- */
112
- export function createBackchannelLogoutHandler(config) {
113
- const idpOrigin = config.idpUrl.replace(/\/$/, '');
114
- return async function backchannelLogoutHandler(c) {
115
- // Parse the logout_token from the form-encoded body
116
- let logoutToken = null;
117
- try {
118
- const contentType = c.req.header('content-type') ?? '';
119
- if (contentType.includes('application/x-www-form-urlencoded')) {
120
- const body = await c.req.parseBody();
121
- logoutToken = body['logout_token'] ?? null;
122
- }
123
- else {
124
- // Also accept JSON body for easier testing
125
- const body = await c.req.json();
126
- logoutToken = body['logout_token'] ?? null;
127
- }
128
- }
129
- catch {
130
- return c.json({ error: 'Failed to parse request body' }, 400);
131
- }
132
- if (!logoutToken || typeof logoutToken !== 'string') {
133
- return c.json({ error: 'Missing logout_token' }, 400);
134
- }
135
- // Verify the JWT
136
- const payload = await verifyHS256JWT(logoutToken, config.clientSecret);
137
- if (!payload) {
138
- return c.json({ error: 'Invalid logout_token signature' }, 401);
139
- }
140
- // Validate issuer
141
- if (payload['iss'] !== idpOrigin) {
142
- return c.json({ error: 'Invalid issuer' }, 401);
143
- }
144
- // Validate audience — may be a string or array of strings
145
- const aud = payload['aud'];
146
- const audList = Array.isArray(aud) ? aud : [String(aud ?? '')];
147
- if (!audList.includes(config.clientId)) {
148
- return c.json({ error: 'Invalid audience' }, 401);
149
- }
150
- // Validate events claim
151
- const events = payload['events'];
152
- if (!events || !(BACKCHANNEL_LOGOUT_EVENT in events)) {
153
- return c.json({ error: 'Missing backchannel logout event' }, 400);
154
- }
155
- // Extract the subject user ID
156
- const sub = payload['sub'];
157
- if (!sub || typeof sub !== 'string') {
158
- return c.json({ error: 'Missing sub claim' }, 400);
159
- }
160
- // Revoke all sessions for this user
161
- try {
162
- await config.auth.api.revokeUserSessions({ body: { userId: sub } });
163
- }
164
- catch (err) {
165
- console.error(`[SDK/backchannel] Failed to revoke sessions for user ${sub}:`, err);
166
- return c.json({ error: 'Failed to revoke sessions' }, 500);
167
- }
168
- return c.json({ ok: true }, 200);
169
- };
170
- }
171
- //# sourceMappingURL=backchannel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"backchannel.js","sourceRoot":"","sources":["../../../src/modules/auth/backchannel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAsCH,iDAAiD;AACjD,MAAM,wBAAwB,GAAG,oDAAoD,CAAA;AAErF,gFAAgF;AAChF,+DAA+D;AAC/D,gFAAgF;AAEhF;;;;;;GAMG;AACH,KAAK,UAAU,cAAc,CAC3B,KAAa,EACb,MAAc;IAEd,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnC,MAAM,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,GAAG,KAAiC,CAAA;IAEzE,sBAAsB;IACtB,IAAI,GAAc,CAAA;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CACjC,KAAK,EACL,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAChC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EACjC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IAED,yCAAyC;IACzC,MAAM,YAAY,GAAG,GAAG,SAAS,IAAI,UAAU,EAAE,CAAA;IACjD,IAAI,QAAoB,CAAA;IACxB,IAAI,CAAC;QACH,QAAQ,GAAG,UAAU,CAAC,IAAI,CACxB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,EAClD,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CACvB,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CACtC,MAAM,EACN,GAAG,EACH,QAAQ,CAAC,MAAqB,EAC9B,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CACvC,CAAA;IAED,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAEvB,iBAAiB;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;YAC7D,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAA4B,CAAA;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,iCAAiC;AACjC,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,8BAA8B,CAC5C,MAA+B;IAE/B,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAElD,OAAO,KAAK,UAAU,wBAAwB,CAAC,CAAc;QAC3D,oDAAoD;QACpD,IAAI,WAAW,GAAkB,IAAI,CAAA;QACrC,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,CAAA;YACtD,IAAI,WAAW,CAAC,QAAQ,CAAC,mCAAmC,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAA;gBACpC,WAAW,GAAI,IAAI,CAAC,cAAc,CAAwB,IAAI,IAAI,CAAA;YACpE,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAA6B,CAAA;gBAC1D,WAAW,GAAI,IAAI,CAAC,cAAc,CAAwB,IAAI,IAAI,CAAA;YACpE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,CAAA;QAC/D,CAAC;QAED,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,GAAG,CAAC,CAAA;QACvD,CAAC;QAED,iBAAiB;QACjB,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,EAAE,GAAG,CAAC,CAAA;QACjE,CAAC;QAED,kBAAkB;QAClB,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE,CAAC;YACjC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,CAAA;QACjD,CAAC;QAED,0DAA0D;QAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;QAC1E,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAA;QACnD,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAwC,CAAA;QACvE,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,wBAAwB,IAAI,MAAM,CAAC,EAAE,CAAC;YACrD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,GAAG,CAAC,CAAA;QACnE,CAAC;QAED,8BAA8B;QAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;QAC1B,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,EAAE,GAAG,CAAC,CAAA;QACpD,CAAC;QAED,oCAAoC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;QACrE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wDAAwD,GAAG,GAAG,EAAE,GAAG,CAAC,CAAA;YAClF,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,GAAG,CAAC,CAAA;QAC5D,CAAC;QAED,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;IAClC,CAAC,CAAA;AACH,CAAC"}
@@ -1,412 +0,0 @@
1
- /**
2
- * @module modules/auth/middleware
3
- * @description Hono auth middleware factories, remote session verification, and
4
- * dev/guest session utilities for Soulcraft product backends.
5
- *
6
- * ## Session verification strategies
7
- *
8
- * All products share the same `createAuthMiddleware` factory, but each product
9
- * selects the right session verifier for its deployment context:
10
- *
11
- * ```
12
- * Production (all products):
13
- * createRemoteSessionVerifier({ idpUrl: 'https://auth.soulcraft.com' })
14
- *
15
- * Development (all products):
16
- * createDevSessionVerifier({ role: 'owner' }) // auto-login, no OAuth needed
17
- *
18
- * Workshop standalone (legacy / local OAuth):
19
- * createAuthMiddleware(betterAuthInstance) // BetterAuthLike overload
20
- * ```
21
- *
22
- * ## Dev and guest endpoint factories
23
- *
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.
29
- *
30
- * @example Production setup (Venue / Academy)
31
- * ```typescript
32
- * import { createAuthMiddleware, createRemoteSessionVerifier } from '@soulcraft/sdk/server'
33
- *
34
- * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
35
- * const { requireAuth, optionalAuth } = createAuthMiddleware(verifySession)
36
- *
37
- * app.get('/api/bookings', requireAuth, async (c) => {
38
- * const user = c.get('user')! // SoulcraftSessionUser
39
- * })
40
- * ```
41
- */
42
- import type { SoulcraftSessionUser, SoulcraftSession } from './types.js';
43
- /** Minimal Hono-compatible context shape used by the auth middleware. */
44
- interface HonoContext<T extends {
45
- Variables: Record<string, unknown>;
46
- } = {
47
- Variables: Record<string, unknown>;
48
- }> {
49
- req: {
50
- raw: Request;
51
- header(name: string): string | undefined;
52
- query(name: string): string | undefined;
53
- };
54
- get<K extends keyof T['Variables']>(key: K): T['Variables'][K];
55
- set<K extends keyof T['Variables']>(key: K, value: T['Variables'][K]): void;
56
- json(data: unknown, status?: number): Response;
57
- redirect(url: string, status?: number): Response;
58
- header(name: string, value: string): void;
59
- }
60
- /** Hono-compatible Next function. */
61
- type HonoNext = () => Promise<void>;
62
- /** The Hono context variable key where the resolved user is stored. */
63
- export declare const AUTH_USER_KEY: "user";
64
- /** Hono-compatible context type with the resolved Soulcraft user variable. */
65
- export type AuthContext = HonoContext<{
66
- Variables: {
67
- [AUTH_USER_KEY]: SoulcraftSessionUser | null;
68
- };
69
- }>;
70
- /** Minimal better-auth API surface the middleware depends on. */
71
- export interface BetterAuthLike {
72
- api: {
73
- getSession(opts: {
74
- headers: Headers;
75
- }): Promise<{
76
- user: Record<string, unknown>;
77
- session: {
78
- id: string;
79
- expiresAt: Date | string | number;
80
- };
81
- } | null>;
82
- };
83
- }
84
- /**
85
- * A session verifier function — the common abstraction for session resolution
86
- * across all products in non-standalone auth mode.
87
- *
88
- * Returned by `createRemoteSessionVerifier` and `createDevSessionVerifier`.
89
- * `createAuthMiddleware` accepts either a `BetterAuthLike` instance (Workshop
90
- * standalone mode) or a `SessionVerifier` function (all other products and modes).
91
- */
92
- export type SessionVerifier = (cookieHeader: string) => Promise<SoulcraftSession | null>;
93
- /**
94
- * Options for `createAuthMiddleware()`.
95
- */
96
- export interface AuthMiddlewareOptions {
97
- /**
98
- * If true, a synthetic dev user is injected in non-production environments
99
- * when a `BetterAuthLike` auth instance is provided and session lookup fails.
100
- * Not used when a `SessionVerifier` function is provided — use
101
- * `createDevSessionVerifier` instead for full dev auto-login in that mode.
102
- * @default true
103
- */
104
- devAutoLogin?: boolean;
105
- }
106
- /**
107
- * The object returned by `createAuthMiddleware()`.
108
- */
109
- export interface AuthMiddleware {
110
- /**
111
- * Require authentication. Resolves the session from request cookies. If the
112
- * session is valid, attaches the typed user to the Hono context under the
113
- * `'user'` key and calls `next()`. Returns HTTP 401 if unauthenticated.
114
- */
115
- requireAuth: (c: AuthContext, next: HonoNext) => Promise<void | Response>;
116
- /**
117
- * Optional authentication. Resolves the session if one exists, but does not
118
- * reject unauthenticated requests. User will be `null` for anonymous requests.
119
- */
120
- optionalAuth: (c: AuthContext, next: HonoNext) => Promise<void | Response>;
121
- }
122
- /**
123
- * Options for `createRemoteSessionVerifier()`.
124
- */
125
- export interface RemoteSessionVerifierOptions {
126
- /** The central IdP base URL, e.g. `"https://auth.soulcraft.com"`. */
127
- idpUrl: string;
128
- /** Session cache TTL in milliseconds. Default: 30 000 (30 seconds). */
129
- cacheTtlMs?: number;
130
- /** Maximum cached sessions. Default: 500. */
131
- cacheMax?: number;
132
- }
133
- /**
134
- * Options for `createDevSessionVerifier()`.
135
- */
136
- export interface DevSessionVerifierOptions {
137
- /**
138
- * The platform role to assign to the synthetic dev session.
139
- * @default 'owner'
140
- */
141
- role?: SoulcraftSessionUser['platformRole'];
142
- /**
143
- * Email address for the synthetic dev user.
144
- * @default 'dev@soulcraft.com'
145
- */
146
- email?: string;
147
- /**
148
- * Display name for the synthetic dev user.
149
- * @default 'Dev User'
150
- */
151
- name?: string;
152
- }
153
- /**
154
- * Options for `createDevLoginHandler()`.
155
- */
156
- export interface DevLoginHandlerOptions {
157
- /**
158
- * Allowed platform roles. The role must be in this list for the handler to
159
- * issue a session cookie. Defaults to all non-guest platform roles.
160
- * @default ['creator','viewer','customer','staff','manager','owner','learner','instructor']
161
- */
162
- allowedRoles?: SoulcraftSessionUser['platformRole'][];
163
- /**
164
- * Cookie name for the issued dev session.
165
- * @default 'soulcraft_dev_session'
166
- */
167
- cookieName?: string;
168
- /**
169
- * Session cookie max-age in seconds.
170
- * @default 86400 (24 hours)
171
- */
172
- maxAgeSeconds?: number;
173
- }
174
- /**
175
- * Options for `createGuestSessionHandler()`.
176
- */
177
- export interface GuestSessionHandlerOptions {
178
- /**
179
- * Cookie name for the issued guest session.
180
- * @default 'soulcraft_guest_session'
181
- */
182
- cookieName?: string;
183
- /**
184
- * Guest session max-age in seconds.
185
- * @default 3600 (1 hour)
186
- */
187
- maxAgeSeconds?: number;
188
- /**
189
- * An optional callback invoked when a new guest session is created.
190
- * Receives the generated guest ID. Useful for analytics or initializing
191
- * a guest cart/basket in the product's store.
192
- *
193
- * @param guestId - The newly generated unique guest ID.
194
- */
195
- onGuestCreated?: (guestId: string) => Promise<void> | void;
196
- }
197
- /**
198
- * Creates Hono auth middleware from a `SessionVerifier` function or a `BetterAuthLike`
199
- * instance.
200
- *
201
- * **Preferred form (all products in OIDC-client mode):**
202
- * Pass a `SessionVerifier` returned by `createRemoteSessionVerifier` or
203
- * `createDevSessionVerifier`. The middleware reads the request cookie header and
204
- * passes it to the verifier.
205
- *
206
- * **Legacy form (Workshop standalone mode):**
207
- * Pass a `better-auth` instance directly. The middleware calls `auth.api.getSession`.
208
- * In non-production environments and when `devAutoLogin` is enabled, a synthetic dev
209
- * user is injected on failed lookups so local dev works without OAuth.
210
- *
211
- * Both forms return identical `{ requireAuth, optionalAuth }` middleware.
212
- *
213
- * @param authOrVerifier - A `better-auth` instance or a `SessionVerifier` function.
214
- * @param options - Optional middleware configuration (only applies to `BetterAuthLike` form).
215
- * @returns Middleware pair: `{ requireAuth, optionalAuth }`.
216
- *
217
- * @example Verifier form (Venue / Academy / Workshop in OIDC mode)
218
- * ```typescript
219
- * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
220
- * const { requireAuth } = createAuthMiddleware(verifySession)
221
- * ```
222
- *
223
- * @deprecated Use `createRequestAuthMiddleware` from `request-middleware.ts` instead.
224
- * The Hono-specific middleware will be removed in a future major version.
225
- *
226
- * @example BetterAuth form (Workshop dev standalone)
227
- * ```typescript
228
- * import { auth } from './better-auth.js'
229
- * const { requireAuth } = createAuthMiddleware(auth)
230
- * ```
231
- */
232
- export declare function createAuthMiddleware(authOrVerifier: BetterAuthLike | SessionVerifier, options?: AuthMiddlewareOptions): AuthMiddleware;
233
- /**
234
- * Creates a cached remote session verifier that proxies session lookups to
235
- * the central IdP at `auth.soulcraft.com`.
236
- *
237
- * Used by products that operate as OIDC clients (Venue, Academy, and Workshop
238
- * in production). Caches successful lookups in an LRU cache to avoid per-request
239
- * HTTP round-trips to the IdP.
240
- *
241
- * The verifier sends the cookie header to the IdP's `/api/auth/get-session` endpoint
242
- * and returns the resolved `SoulcraftSession` or `null` if the session is invalid.
243
- *
244
- * Pass the returned function directly to `createAuthMiddleware`:
245
- * ```typescript
246
- * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
247
- * const { requireAuth } = createAuthMiddleware(verifySession)
248
- * ```
249
- *
250
- * @param options - IdP URL, cache TTL, and max cache size.
251
- * @returns A `SessionVerifier` — async function that accepts a cookie header string.
252
- *
253
- * @example
254
- * ```typescript
255
- * const verifySession = createRemoteSessionVerifier({
256
- * idpUrl: 'https://auth.soulcraft.com',
257
- * cacheTtlMs: 30_000,
258
- * })
259
- *
260
- * const session = await verifySession(c.req.header('cookie') ?? '')
261
- * if (!session) return c.json({ error: 'Unauthorized' }, 401)
262
- * ```
263
- */
264
- export declare function createRemoteSessionVerifier(options: RemoteSessionVerifierOptions): SessionVerifier;
265
- /**
266
- * Creates a session verifier that always resolves to a synthetic dev session.
267
- *
268
- * Intended for products that run as OIDC clients but need local development auth
269
- * without OAuth, network calls, SQLite, or real cookies. The returned verifier always
270
- * succeeds — any request resolves to the configured synthetic user.
271
- *
272
- * Designed as a drop-in replacement for `createRemoteSessionVerifier` in local dev:
273
- *
274
- * ```typescript
275
- * const verifySession = process.env.SOULCRAFT_IDP_URL
276
- * ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
277
- * : createDevSessionVerifier({ role: 'owner' })
278
- *
279
- * const { requireAuth } = createAuthMiddleware(verifySession)
280
- * ```
281
- *
282
- * **Never use in production.** The verifier performs no validation whatsoever.
283
- *
284
- * @param options - Optional synthetic user configuration.
285
- * @returns A `SessionVerifier` with the same signature as `createRemoteSessionVerifier`.
286
- *
287
- * @example
288
- * ```typescript
289
- * const verifySession = process.env.SOULCRAFT_IDP_URL
290
- * ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
291
- * : createDevSessionVerifier({ role: 'owner' })
292
- *
293
- * export const handle = async ({ event, resolve }) => {
294
- * const session = await verifySession(event.request.headers.get('cookie') ?? '')
295
- * event.locals.session = session
296
- * return resolve(event)
297
- * }
298
- * ```
299
- */
300
- export declare function createDevSessionVerifier(options?: DevSessionVerifierOptions): SessionVerifier;
301
- /**
302
- * Creates a Hono request handler for a dev login endpoint.
303
- *
304
- * Mount at `/api/dev/login` to get a role-switching endpoint for local
305
- * development. Accepts `?role=<platformRole>` and optional `?email=` / `?name=`
306
- * query params. Issues a signed base64url session cookie that `createAuthMiddleware`
307
- * (when used with a `SessionVerifier` that reads dev cookies) can resolve.
308
- *
309
- * **Guards against production use:** the handler returns HTTP 404 when
310
- * `NODE_ENV === 'production'` — it is safe to leave mounted in all environments.
311
- *
312
- * @param options - Allowed roles, cookie name, and max-age.
313
- * @returns A Hono-compatible request handler `(c: HonoContext) => Response`.
314
- *
315
- * @deprecated Use `createRequestDevLoginHandler` from `request-middleware.ts` instead.
316
- * The Hono-specific handler will be removed in a future major version.
317
- *
318
- * @example
319
- * ```typescript
320
- * import { createDevLoginHandler } from '@soulcraft/sdk/server'
321
- *
322
- * // In your Hono server setup:
323
- * app.get('/api/dev/login', createDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] }))
324
- *
325
- * // Usage: GET /api/dev/login?role=staff → sets cookie + redirects to /
326
- * ```
327
- */
328
- export declare function createDevLoginHandler(options?: DevLoginHandlerOptions): (c: HonoContext) => Response | Promise<Response>;
329
- /**
330
- * Creates a session verifier that reads the cookie issued by `createDevLoginHandler`.
331
- *
332
- * Use this together with `createDevLoginHandler` when you want dev role-switching
333
- * (e.g. clicking "Login as Staff" in a dev UI) rather than a fixed synthetic user.
334
- *
335
- * The verifier decodes the base64url cookie value and returns the embedded session.
336
- * Falls back to `null` (unauthenticated) if the cookie is absent or expired.
337
- *
338
- * ```typescript
339
- * // Only one of these in dev — pick what fits your workflow:
340
- *
341
- * // Option A: Fixed dev user, no login UI needed
342
- * const verifySession = createDevSessionVerifier({ role: 'owner' })
343
- *
344
- * // Option B: Role-switching dev login UI
345
- * app.get('/api/dev/login', createDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] }))
346
- * const verifySession = createDevCookieVerifier()
347
- * ```
348
- *
349
- * @param cookieName - Must match the `cookieName` passed to `createDevLoginHandler`. Default: `'soulcraft_dev_session'`.
350
- * @returns A `SessionVerifier` compatible with `createAuthMiddleware`.
351
- */
352
- export declare function createDevCookieVerifier(cookieName?: string): SessionVerifier;
353
- /**
354
- * Creates a Hono request handler that issues a guest session cookie.
355
- *
356
- * Venue visitors can browse and initiate bookings without creating an account.
357
- * This handler mounts at e.g. `/api/guest/session` and issues a session cookie
358
- * with `platformRole: 'guest'` and a unique guest ID on each call (if no valid
359
- * guest session already exists).
360
- *
361
- * The guest session cookie can be verified using `createGuestCookieVerifier`,
362
- * which returns a `SessionVerifier` compatible with `createAuthMiddleware`.
363
- *
364
- * @param options - Cookie name, max-age, and optional `onGuestCreated` callback.
365
- * @returns A Hono-compatible request handler.
366
- *
367
- * @deprecated Use `createRequestGuestSessionHandler` from `request-middleware.ts` instead.
368
- * The Hono-specific handler will be removed in a future major version.
369
- *
370
- * @example
371
- * ```typescript
372
- * import { createGuestSessionHandler, createGuestCookieVerifier, createAuthMiddleware } from '@soulcraft/sdk/server'
373
- *
374
- * // Issue guest sessions
375
- * app.post('/api/guest/session', createGuestSessionHandler({
376
- * onGuestCreated: async (guestId) => {
377
- * await db.guests.insert({ id: guestId, createdAt: new Date() })
378
- * },
379
- * }))
380
- *
381
- * // Verify guest sessions in optional auth (guests can browse)
382
- * const verifyGuest = createGuestCookieVerifier()
383
- * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
384
- *
385
- * // Compose: check real session first, fall back to guest
386
- * const { optionalAuth } = createAuthMiddleware(async (cookie) =>
387
- * await verifySession(cookie) ?? await verifyGuest(cookie)
388
- * )
389
- * ```
390
- */
391
- export declare function createGuestSessionHandler(options?: GuestSessionHandlerOptions): (c: HonoContext) => Promise<Response>;
392
- /**
393
- * Creates a session verifier that reads the cookie issued by `createGuestSessionHandler`.
394
- *
395
- * Returns the guest `SoulcraftSession` or `null` if no valid guest cookie is present.
396
- * Compose with `createRemoteSessionVerifier` to allow both authenticated and guest access:
397
- *
398
- * ```typescript
399
- * const verifyReal = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
400
- * const verifyGuest = createGuestCookieVerifier()
401
- *
402
- * const { optionalAuth } = createAuthMiddleware(async (cookie) =>
403
- * await verifyReal(cookie) ?? await verifyGuest(cookie)
404
- * )
405
- * ```
406
- *
407
- * @param cookieName - Must match the `cookieName` passed to `createGuestSessionHandler`. Default: `'soulcraft_guest_session'`.
408
- * @returns A `SessionVerifier` compatible with `createAuthMiddleware`.
409
- */
410
- export declare function createGuestCookieVerifier(cookieName?: string): SessionVerifier;
411
- export {};
412
- //# sourceMappingURL=middleware.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/middleware.ts"],"names":[],"mappings":"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"}