@soulcraft/sdk 2.6.0 → 2.8.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.
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @module modules/auth/request-middleware
3
+ * @description Framework-agnostic auth middleware using Web Standard Request/Response.
4
+ *
5
+ * Drop-in replacements for the Hono-based middleware in `middleware.ts`. These
6
+ * functions use a `WeakMap<Request, SoulcraftSessionUser | null>` to attach the
7
+ * resolved user to the request object, instead of Hono's `c.set()` / `c.get()`.
8
+ *
9
+ * ## Middleware signature
10
+ *
11
+ * All middleware follows the universal pattern:
12
+ * ```
13
+ * (req: Request, next: () => Promise<Response>) => Promise<Response>
14
+ * ```
15
+ *
16
+ * Compatible with any server framework that exposes Web Standard `Request`/`Response`
17
+ * (SvelteKit, Bun.serve, Deno, Cloudflare Workers, etc.).
18
+ *
19
+ * ## User retrieval
20
+ *
21
+ * After middleware runs, retrieve the resolved user with `getUser(req)`:
22
+ * ```typescript
23
+ * const user = getUser(req) // SoulcraftSessionUser | null
24
+ * ```
25
+ *
26
+ * @example SvelteKit hooks
27
+ * ```typescript
28
+ * import { createRequestAuthMiddleware, getUser, createRemoteSessionVerifier } from '@soulcraft/sdk/server'
29
+ *
30
+ * const verifier = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
31
+ * const { requireAuth } = createRequestAuthMiddleware(verifier)
32
+ *
33
+ * export const handle = async ({ event, resolve }) => {
34
+ * const response = await requireAuth(event.request, () => resolve(event))
35
+ * event.locals.user = getUser(event.request)
36
+ * return response
37
+ * }
38
+ * ```
39
+ *
40
+ * @example Bun.serve
41
+ * ```typescript
42
+ * import { createRequestAuthMiddleware, getUser, createRemoteSessionVerifier } from '@soulcraft/sdk/server'
43
+ *
44
+ * const verifier = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
45
+ * const { optionalAuth } = createRequestAuthMiddleware(verifier)
46
+ *
47
+ * Bun.serve({
48
+ * fetch: (req) => optionalAuth(req, async () => {
49
+ * const user = getUser(req)
50
+ * return new Response(JSON.stringify({ user: user?.email ?? 'anonymous' }))
51
+ * }),
52
+ * })
53
+ * ```
54
+ */
55
+ import type { SoulcraftSessionUser } from './types.js';
56
+ import type { BetterAuthLike, SessionVerifier, AuthMiddlewareOptions, DevLoginHandlerOptions, GuestSessionHandlerOptions } from './middleware.js';
57
+ /**
58
+ * @description A framework-agnostic middleware function that processes a Web Standard
59
+ * Request and either calls the next handler or short-circuits with its own Response.
60
+ */
61
+ export type RequestMiddleware = (req: Request, next: () => Promise<Response>) => Promise<Response>;
62
+ /**
63
+ * @description The object returned by `createRequestAuthMiddleware()`.
64
+ * Provides `requireAuth` and `optionalAuth` middleware using pure Request/Response.
65
+ */
66
+ export interface RequestAuthMiddleware {
67
+ /**
68
+ * Require authentication. Resolves the session from request cookies. If the
69
+ * session is valid, attaches the typed user to the request via WeakMap and
70
+ * calls `next()`. Returns HTTP 401 JSON response if unauthenticated.
71
+ */
72
+ requireAuth: RequestMiddleware;
73
+ /**
74
+ * Optional authentication. Resolves the session if one exists, but does not
75
+ * reject unauthenticated requests. User will be `null` for anonymous requests.
76
+ */
77
+ optionalAuth: RequestMiddleware;
78
+ }
79
+ /**
80
+ * @description Retrieves the resolved Soulcraft user attached to a Request by
81
+ * the request auth middleware.
82
+ *
83
+ * Returns the `SoulcraftSessionUser` if the request was authenticated, `null` if
84
+ * the request passed through `optionalAuth` without a session, or `null` if no
85
+ * middleware has processed this request.
86
+ *
87
+ * @param req - The Web Standard Request that was processed by middleware.
88
+ * @returns The resolved user, or null if unauthenticated or not yet processed.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const response = await requireAuth(request, async () => {
93
+ * const user = getUser(request)!
94
+ * return new Response(`Hello ${user.name}`)
95
+ * })
96
+ * ```
97
+ */
98
+ export declare function getUser(req: Request): SoulcraftSessionUser | null;
99
+ /**
100
+ * @description Creates framework-agnostic auth middleware from a `SessionVerifier`
101
+ * function or a `BetterAuthLike` instance.
102
+ *
103
+ * This is the Web Standard equivalent of `createAuthMiddleware` — same session
104
+ * resolution logic, but uses `WeakMap<Request, User>` instead of Hono context
105
+ * variables. Retrieve the resolved user after middleware with `getUser(req)`.
106
+ *
107
+ * **Preferred form (all products in OIDC-client mode):**
108
+ * Pass a `SessionVerifier` returned by `createRemoteSessionVerifier` or
109
+ * `createDevSessionVerifier`. The middleware reads the request cookie header and
110
+ * passes it to the verifier.
111
+ *
112
+ * **Legacy form (Workshop standalone mode):**
113
+ * Pass a `better-auth` instance directly. The middleware calls `auth.api.getSession`.
114
+ * In non-production environments and when `devAutoLogin` is enabled, a synthetic dev
115
+ * user is injected on failed lookups so local dev works without OAuth.
116
+ *
117
+ * @param authOrVerifier - A `better-auth` instance or a `SessionVerifier` function.
118
+ * @param options - Optional middleware configuration (only applies to `BetterAuthLike` form).
119
+ * @returns Middleware pair: `{ requireAuth, optionalAuth }`.
120
+ *
121
+ * @example Verifier form (Venue / Academy / Workshop in OIDC mode)
122
+ * ```typescript
123
+ * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
124
+ * const { requireAuth } = createRequestAuthMiddleware(verifySession)
125
+ *
126
+ * // Use in any server:
127
+ * const response = await requireAuth(request, () => handler(request))
128
+ * const user = getUser(request)!
129
+ * ```
130
+ *
131
+ * @example BetterAuth form (Workshop dev standalone)
132
+ * ```typescript
133
+ * import { auth } from './better-auth.js'
134
+ * const { requireAuth } = createRequestAuthMiddleware(auth)
135
+ * ```
136
+ */
137
+ export declare function createRequestAuthMiddleware(authOrVerifier: BetterAuthLike | SessionVerifier, options?: AuthMiddlewareOptions): RequestAuthMiddleware;
138
+ /**
139
+ * @description Creates a framework-agnostic request handler for a dev login endpoint.
140
+ *
141
+ * Web Standard equivalent of `createDevLoginHandler`. Mount at `/api/dev/login`
142
+ * to get a role-switching endpoint for local development. Accepts `?role=<platformRole>`
143
+ * and optional `?email=` / `?name=` / `?redirect=` query params. Issues a base64url
144
+ * session cookie and returns an HTTP 302 redirect.
145
+ *
146
+ * **Guards against production use:** the handler returns HTTP 404 when
147
+ * `NODE_ENV === 'production'` — safe to leave mounted in all environments.
148
+ *
149
+ * @param options - Allowed roles, cookie name, and max-age.
150
+ * @returns A request handler function `(req: Request) => Response`.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * import { createRequestDevLoginHandler } from '@soulcraft/sdk/server'
155
+ *
156
+ * const devLogin = createRequestDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] })
157
+ *
158
+ * // SvelteKit: export const GET = ({ request }) => devLogin(request)
159
+ * // Bun: if (url.pathname === '/api/dev/login') return devLogin(req)
160
+ *
161
+ * // Usage: GET /api/dev/login?role=staff → sets cookie + redirects to /
162
+ * ```
163
+ */
164
+ export declare function createRequestDevLoginHandler(options?: DevLoginHandlerOptions): (req: Request) => Response;
165
+ /**
166
+ * @description Creates a framework-agnostic request handler that issues a guest
167
+ * session cookie.
168
+ *
169
+ * Web Standard equivalent of `createGuestSessionHandler`. Venue visitors can browse
170
+ * and initiate bookings without creating an account. Mount at e.g. `/api/guest/session`
171
+ * to issue a session cookie with `platformRole: 'guest'` and a unique guest ID on
172
+ * each call (if no valid guest session already exists).
173
+ *
174
+ * The guest session cookie can be verified using `createGuestCookieVerifier`,
175
+ * which returns a `SessionVerifier` compatible with `createRequestAuthMiddleware`.
176
+ *
177
+ * @param options - Cookie name, max-age, and optional `onGuestCreated` callback.
178
+ * @returns An async request handler function `(req: Request) => Promise<Response>`.
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * import { createRequestGuestSessionHandler, createGuestCookieVerifier } from '@soulcraft/sdk/server'
183
+ *
184
+ * const guestSession = createRequestGuestSessionHandler({
185
+ * onGuestCreated: async (guestId) => {
186
+ * await db.guests.insert({ id: guestId, createdAt: new Date() })
187
+ * },
188
+ * })
189
+ *
190
+ * // SvelteKit: export const POST = ({ request }) => guestSession(request)
191
+ * // Bun: if (url.pathname === '/api/guest/session') return guestSession(req)
192
+ * ```
193
+ */
194
+ export declare function createRequestGuestSessionHandler(options?: GuestSessionHandlerOptions): (req: Request) => Promise<Response>;
195
+ //# sourceMappingURL=request-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-middleware.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/request-middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAoB,MAAM,YAAY,CAAA;AACxE,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC3B,MAAM,iBAAiB,CAAA;AAMxB;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAElG;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,WAAW,EAAE,iBAAiB,CAAA;IAE9B;;;OAGG;IACH,YAAY,EAAE,iBAAiB,CAAA;CAChC;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI,CAEjE;AAsDD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,2BAA2B,CACzC,cAAc,EAAE,cAAc,GAAG,eAAe,EAChD,OAAO,GAAE,qBAA0B,GAClC,qBAAqB,CA8EvB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,GAAE,sBAA2B,GACnC,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,CAiE5B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,0BAA+B,GACvC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAuDrC"}
@@ -0,0 +1,409 @@
1
+ /**
2
+ * @module modules/auth/request-middleware
3
+ * @description Framework-agnostic auth middleware using Web Standard Request/Response.
4
+ *
5
+ * Drop-in replacements for the Hono-based middleware in `middleware.ts`. These
6
+ * functions use a `WeakMap<Request, SoulcraftSessionUser | null>` to attach the
7
+ * resolved user to the request object, instead of Hono's `c.set()` / `c.get()`.
8
+ *
9
+ * ## Middleware signature
10
+ *
11
+ * All middleware follows the universal pattern:
12
+ * ```
13
+ * (req: Request, next: () => Promise<Response>) => Promise<Response>
14
+ * ```
15
+ *
16
+ * Compatible with any server framework that exposes Web Standard `Request`/`Response`
17
+ * (SvelteKit, Bun.serve, Deno, Cloudflare Workers, etc.).
18
+ *
19
+ * ## User retrieval
20
+ *
21
+ * After middleware runs, retrieve the resolved user with `getUser(req)`:
22
+ * ```typescript
23
+ * const user = getUser(req) // SoulcraftSessionUser | null
24
+ * ```
25
+ *
26
+ * @example SvelteKit hooks
27
+ * ```typescript
28
+ * import { createRequestAuthMiddleware, getUser, createRemoteSessionVerifier } from '@soulcraft/sdk/server'
29
+ *
30
+ * const verifier = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
31
+ * const { requireAuth } = createRequestAuthMiddleware(verifier)
32
+ *
33
+ * export const handle = async ({ event, resolve }) => {
34
+ * const response = await requireAuth(event.request, () => resolve(event))
35
+ * event.locals.user = getUser(event.request)
36
+ * return response
37
+ * }
38
+ * ```
39
+ *
40
+ * @example Bun.serve
41
+ * ```typescript
42
+ * import { createRequestAuthMiddleware, getUser, createRemoteSessionVerifier } from '@soulcraft/sdk/server'
43
+ *
44
+ * const verifier = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
45
+ * const { optionalAuth } = createRequestAuthMiddleware(verifier)
46
+ *
47
+ * Bun.serve({
48
+ * fetch: (req) => optionalAuth(req, async () => {
49
+ * const user = getUser(req)
50
+ * return new Response(JSON.stringify({ user: user?.email ?? 'anonymous' }))
51
+ * }),
52
+ * })
53
+ * ```
54
+ */
55
+ import { computeEmailHash } from './config.js';
56
+ // ─────────────────────────────────────────────────────────────────────────────
57
+ // WeakMap user storage
58
+ // ─────────────────────────────────────────────────────────────────────────────
59
+ /** Internal WeakMap that associates a Request with its resolved user. */
60
+ const userMap = new WeakMap();
61
+ /**
62
+ * @description Retrieves the resolved Soulcraft user attached to a Request by
63
+ * the request auth middleware.
64
+ *
65
+ * Returns the `SoulcraftSessionUser` if the request was authenticated, `null` if
66
+ * the request passed through `optionalAuth` without a session, or `null` if no
67
+ * middleware has processed this request.
68
+ *
69
+ * @param req - The Web Standard Request that was processed by middleware.
70
+ * @returns The resolved user, or null if unauthenticated or not yet processed.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const response = await requireAuth(request, async () => {
75
+ * const user = getUser(request)!
76
+ * return new Response(`Hello ${user.name}`)
77
+ * })
78
+ * ```
79
+ */
80
+ export function getUser(req) {
81
+ return userMap.get(req) ?? null;
82
+ }
83
+ // ─────────────────────────────────────────────────────────────────────────────
84
+ // Shared internal helpers (duplicated from middleware.ts to avoid coupling)
85
+ // ─────────────────────────────────────────────────────────────────────────────
86
+ /** Resolve a raw user record from a better-auth session into a `SoulcraftSessionUser`. */
87
+ function _resolveUser(raw) {
88
+ const email = String(raw['email'] ?? '');
89
+ const emailHash = raw['emailHash']
90
+ ? String(raw['emailHash'])
91
+ : computeEmailHash(email);
92
+ return {
93
+ id: String(raw['id'] ?? ''),
94
+ email,
95
+ name: String(raw['name'] ?? ''),
96
+ image: raw['image'] ?? null,
97
+ platformRole: raw['platformRole'] ?? 'creator',
98
+ emailHash,
99
+ ...(raw['handle'] ? { handle: String(raw['handle']) } : {}),
100
+ };
101
+ }
102
+ /** Parse a simple `name=value` cookie from a raw cookie header string. */
103
+ function _parseCookie(cookieHeader, name) {
104
+ for (const part of cookieHeader.split(';')) {
105
+ const [k, ...rest] = part.trim().split('=');
106
+ if (k?.trim() === name)
107
+ return rest.join('=').trim();
108
+ }
109
+ return undefined;
110
+ }
111
+ /** Encode a dev/guest session payload as a compact JSON+base64url string (unsigned). */
112
+ function _encodeSessionCookie(session) {
113
+ return Buffer.from(JSON.stringify(session)).toString('base64url');
114
+ }
115
+ /** Decode a session payload encoded by `_encodeSessionCookie`. Returns null on any error. */
116
+ function _decodeSessionCookie(value) {
117
+ try {
118
+ const raw = JSON.parse(Buffer.from(value, 'base64url').toString('utf-8'));
119
+ if (!raw.user || !raw.sessionId || !raw.expiresAt)
120
+ return null;
121
+ if (raw.expiresAt < Date.now())
122
+ return null;
123
+ return raw;
124
+ }
125
+ catch {
126
+ return null;
127
+ }
128
+ }
129
+ // ─────────────────────────────────────────────────────────────────────────────
130
+ // createRequestAuthMiddleware
131
+ // ─────────────────────────────────────────────────────────────────────────────
132
+ /**
133
+ * @description Creates framework-agnostic auth middleware from a `SessionVerifier`
134
+ * function or a `BetterAuthLike` instance.
135
+ *
136
+ * This is the Web Standard equivalent of `createAuthMiddleware` — same session
137
+ * resolution logic, but uses `WeakMap<Request, User>` instead of Hono context
138
+ * variables. Retrieve the resolved user after middleware with `getUser(req)`.
139
+ *
140
+ * **Preferred form (all products in OIDC-client mode):**
141
+ * Pass a `SessionVerifier` returned by `createRemoteSessionVerifier` or
142
+ * `createDevSessionVerifier`. The middleware reads the request cookie header and
143
+ * passes it to the verifier.
144
+ *
145
+ * **Legacy form (Workshop standalone mode):**
146
+ * Pass a `better-auth` instance directly. The middleware calls `auth.api.getSession`.
147
+ * In non-production environments and when `devAutoLogin` is enabled, a synthetic dev
148
+ * user is injected on failed lookups so local dev works without OAuth.
149
+ *
150
+ * @param authOrVerifier - A `better-auth` instance or a `SessionVerifier` function.
151
+ * @param options - Optional middleware configuration (only applies to `BetterAuthLike` form).
152
+ * @returns Middleware pair: `{ requireAuth, optionalAuth }`.
153
+ *
154
+ * @example Verifier form (Venue / Academy / Workshop in OIDC mode)
155
+ * ```typescript
156
+ * const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
157
+ * const { requireAuth } = createRequestAuthMiddleware(verifySession)
158
+ *
159
+ * // Use in any server:
160
+ * const response = await requireAuth(request, () => handler(request))
161
+ * const user = getUser(request)!
162
+ * ```
163
+ *
164
+ * @example BetterAuth form (Workshop dev standalone)
165
+ * ```typescript
166
+ * import { auth } from './better-auth.js'
167
+ * const { requireAuth } = createRequestAuthMiddleware(auth)
168
+ * ```
169
+ */
170
+ export function createRequestAuthMiddleware(authOrVerifier, options = {}) {
171
+ const isVerifier = typeof authOrVerifier === 'function';
172
+ if (isVerifier) {
173
+ const verify = authOrVerifier;
174
+ const requireAuth = async (req, next) => {
175
+ const cookieHeader = req.headers.get('cookie') ?? '';
176
+ const session = await verify(cookieHeader);
177
+ if (!session) {
178
+ return new Response(JSON.stringify({ error: 'Authentication required' }), {
179
+ status: 401,
180
+ headers: { 'Content-Type': 'application/json' },
181
+ });
182
+ }
183
+ userMap.set(req, session.user);
184
+ return next();
185
+ };
186
+ const optionalAuth = async (req, next) => {
187
+ const cookieHeader = req.headers.get('cookie') ?? '';
188
+ const session = await verify(cookieHeader);
189
+ userMap.set(req, session?.user ?? null);
190
+ return next();
191
+ };
192
+ return { requireAuth, optionalAuth };
193
+ }
194
+ // BetterAuthLike form (Workshop standalone)
195
+ const auth = authOrVerifier;
196
+ const devAutoLogin = options.devAutoLogin ?? true;
197
+ const isDev = process.env['NODE_ENV'] !== 'production';
198
+ const DEV_USER = {
199
+ id: 'dev-user-001',
200
+ email: 'dev@localhost',
201
+ name: 'Dev User',
202
+ image: null,
203
+ emailHash: computeEmailHash('dev@localhost'),
204
+ platformRole: 'creator',
205
+ handle: 'dev',
206
+ };
207
+ const requireAuth = async (req, next) => {
208
+ if (isDev && devAutoLogin) {
209
+ if (!userMap.has(req))
210
+ userMap.set(req, DEV_USER);
211
+ return next();
212
+ }
213
+ const session = await auth.api.getSession({ headers: req.headers });
214
+ if (!session?.user) {
215
+ return new Response(JSON.stringify({ error: 'Authentication required' }), {
216
+ status: 401,
217
+ headers: { 'Content-Type': 'application/json' },
218
+ });
219
+ }
220
+ userMap.set(req, _resolveUser(session.user));
221
+ return next();
222
+ };
223
+ const optionalAuth = async (req, next) => {
224
+ if (isDev && devAutoLogin) {
225
+ if (!userMap.has(req))
226
+ userMap.set(req, DEV_USER);
227
+ return next();
228
+ }
229
+ const session = await auth.api.getSession({ headers: req.headers });
230
+ if (session?.user) {
231
+ userMap.set(req, _resolveUser(session.user));
232
+ }
233
+ else {
234
+ userMap.set(req, null);
235
+ }
236
+ return next();
237
+ };
238
+ return { requireAuth, optionalAuth };
239
+ }
240
+ // ─────────────────────────────────────────────────────────────────────────────
241
+ // createRequestDevLoginHandler
242
+ // ─────────────────────────────────────────────────────────────────────────────
243
+ /**
244
+ * @description Creates a framework-agnostic request handler for a dev login endpoint.
245
+ *
246
+ * Web Standard equivalent of `createDevLoginHandler`. Mount at `/api/dev/login`
247
+ * to get a role-switching endpoint for local development. Accepts `?role=<platformRole>`
248
+ * and optional `?email=` / `?name=` / `?redirect=` query params. Issues a base64url
249
+ * session cookie and returns an HTTP 302 redirect.
250
+ *
251
+ * **Guards against production use:** the handler returns HTTP 404 when
252
+ * `NODE_ENV === 'production'` — safe to leave mounted in all environments.
253
+ *
254
+ * @param options - Allowed roles, cookie name, and max-age.
255
+ * @returns A request handler function `(req: Request) => Response`.
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * import { createRequestDevLoginHandler } from '@soulcraft/sdk/server'
260
+ *
261
+ * const devLogin = createRequestDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] })
262
+ *
263
+ * // SvelteKit: export const GET = ({ request }) => devLogin(request)
264
+ * // Bun: if (url.pathname === '/api/dev/login') return devLogin(req)
265
+ *
266
+ * // Usage: GET /api/dev/login?role=staff → sets cookie + redirects to /
267
+ * ```
268
+ */
269
+ export function createRequestDevLoginHandler(options = {}) {
270
+ const DEFAULT_ROLES = [
271
+ 'creator', 'viewer', 'customer', 'staff', 'manager', 'owner', 'learner', 'instructor',
272
+ ];
273
+ const allowedRoles = options.allowedRoles ?? DEFAULT_ROLES;
274
+ const cookieName = options.cookieName ?? 'soulcraft_dev_session';
275
+ const maxAgeSeconds = options.maxAgeSeconds ?? 86_400;
276
+ return function requestDevLoginHandler(req) {
277
+ if (process.env['NODE_ENV'] === 'production') {
278
+ return new Response(JSON.stringify({ error: 'Not found' }), {
279
+ status: 404,
280
+ headers: { 'Content-Type': 'application/json' },
281
+ });
282
+ }
283
+ const url = new URL(req.url);
284
+ const role = url.searchParams.get('role');
285
+ if (!role || !allowedRoles.includes(role)) {
286
+ return new Response(JSON.stringify({
287
+ error: `Invalid role. Allowed: ${allowedRoles.join(', ')}`,
288
+ allowedRoles,
289
+ }), {
290
+ status: 400,
291
+ headers: { 'Content-Type': 'application/json' },
292
+ });
293
+ }
294
+ const email = url.searchParams.get('email') ?? `dev-${role}@soulcraft.com`;
295
+ const name = url.searchParams.get('name') ?? `Dev ${role.charAt(0).toUpperCase() + role.slice(1)}`;
296
+ const redirect = url.searchParams.get('redirect') ?? '/';
297
+ const session = {
298
+ user: {
299
+ id: `dev-user-${role}`,
300
+ email,
301
+ name,
302
+ image: null,
303
+ platformRole: role,
304
+ emailHash: computeEmailHash(email),
305
+ },
306
+ sessionId: `dev-session-${Date.now()}`,
307
+ expiresAt: Date.now() + maxAgeSeconds * 1000,
308
+ };
309
+ const cookieValue = _encodeSessionCookie(session);
310
+ const cookieHeader = [
311
+ `${cookieName}=${cookieValue}`,
312
+ `Path=/`,
313
+ `HttpOnly`,
314
+ `SameSite=Lax`,
315
+ `Max-Age=${maxAgeSeconds}`,
316
+ ].join('; ');
317
+ return new Response(null, {
318
+ status: 302,
319
+ headers: {
320
+ Location: redirect,
321
+ 'Set-Cookie': cookieHeader,
322
+ },
323
+ });
324
+ };
325
+ }
326
+ // ─────────────────────────────────────────────────────────────────────────────
327
+ // createRequestGuestSessionHandler
328
+ // ─────────────────────────────────────────────────────────────────────────────
329
+ /**
330
+ * @description Creates a framework-agnostic request handler that issues a guest
331
+ * session cookie.
332
+ *
333
+ * Web Standard equivalent of `createGuestSessionHandler`. Venue visitors can browse
334
+ * and initiate bookings without creating an account. Mount at e.g. `/api/guest/session`
335
+ * to issue a session cookie with `platformRole: 'guest'` and a unique guest ID on
336
+ * each call (if no valid guest session already exists).
337
+ *
338
+ * The guest session cookie can be verified using `createGuestCookieVerifier`,
339
+ * which returns a `SessionVerifier` compatible with `createRequestAuthMiddleware`.
340
+ *
341
+ * @param options - Cookie name, max-age, and optional `onGuestCreated` callback.
342
+ * @returns An async request handler function `(req: Request) => Promise<Response>`.
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * import { createRequestGuestSessionHandler, createGuestCookieVerifier } from '@soulcraft/sdk/server'
347
+ *
348
+ * const guestSession = createRequestGuestSessionHandler({
349
+ * onGuestCreated: async (guestId) => {
350
+ * await db.guests.insert({ id: guestId, createdAt: new Date() })
351
+ * },
352
+ * })
353
+ *
354
+ * // SvelteKit: export const POST = ({ request }) => guestSession(request)
355
+ * // Bun: if (url.pathname === '/api/guest/session') return guestSession(req)
356
+ * ```
357
+ */
358
+ export function createRequestGuestSessionHandler(options = {}) {
359
+ const cookieName = options.cookieName ?? 'soulcraft_guest_session';
360
+ const maxAgeSeconds = options.maxAgeSeconds ?? 3_600;
361
+ const onGuestCreated = options.onGuestCreated;
362
+ return async function requestGuestSessionHandler(req) {
363
+ // Return existing guest session if still valid
364
+ const cookieHeader = req.headers.get('cookie') ?? '';
365
+ const existingValue = _parseCookie(cookieHeader, cookieName);
366
+ if (existingValue) {
367
+ const existing = _decodeSessionCookie(existingValue);
368
+ if (existing) {
369
+ return new Response(JSON.stringify({ guestId: existing.user.id, existing: true }), {
370
+ status: 200,
371
+ headers: { 'Content-Type': 'application/json' },
372
+ });
373
+ }
374
+ }
375
+ // Create a new guest session
376
+ const guestId = `guest-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
377
+ const email = `${guestId}@guest.soulcraft.com`;
378
+ const session = {
379
+ user: {
380
+ id: guestId,
381
+ email,
382
+ name: 'Guest',
383
+ image: null,
384
+ platformRole: 'guest',
385
+ emailHash: computeEmailHash(email),
386
+ },
387
+ sessionId: `guest-session-${Date.now()}`,
388
+ expiresAt: Date.now() + maxAgeSeconds * 1000,
389
+ };
390
+ if (onGuestCreated)
391
+ await onGuestCreated(guestId);
392
+ const cookieValue = _encodeSessionCookie(session);
393
+ const setCookieHeader = [
394
+ `${cookieName}=${cookieValue}`,
395
+ `Path=/`,
396
+ `HttpOnly`,
397
+ `SameSite=Lax`,
398
+ `Max-Age=${maxAgeSeconds}`,
399
+ ].join('; ');
400
+ return new Response(JSON.stringify({ guestId, existing: false }), {
401
+ status: 200,
402
+ headers: {
403
+ 'Content-Type': 'application/json',
404
+ 'Set-Cookie': setCookieHeader,
405
+ },
406
+ });
407
+ };
408
+ }
409
+ //# sourceMappingURL=request-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-middleware.js","sourceRoot":"","sources":["../../../src/modules/auth/request-middleware.ts"],"names":[],"mappings":"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"}
@@ -41,6 +41,9 @@ export { createAuthMiddleware, createRemoteSessionVerifier, createDevSessionVeri
41
41
  export type { AuthMiddlewareOptions, AuthMiddleware, AuthContext, BetterAuthLike, SessionVerifier, RemoteSessionVerifierOptions, DevSessionVerifierOptions, DevLoginHandlerOptions, GuestSessionHandlerOptions, } from '../modules/auth/middleware.js';
42
42
  export { createBackchannelLogoutHandler } from '../modules/auth/backchannel.js';
43
43
  export type { BackchannelLogoutConfig, BackchannelAuthLike, } from '../modules/auth/backchannel.js';
44
+ export { createRequestAuthMiddleware, createRequestDevLoginHandler, createRequestGuestSessionHandler, getUser, } from '../modules/auth/request-middleware.js';
45
+ export type { RequestMiddleware, RequestAuthMiddleware, } from '../modules/auth/request-middleware.js';
46
+ export { createRequestBackchannelLogoutHandler } from '../modules/auth/request-backchannel.js';
44
47
  export { createSoulcraftAuth } from '../modules/auth/sveltekit.js';
45
48
  export type { SoulcraftAuthOptions, SoulcraftAuth, SvelteKitHandle, SvelteKitEvent, SvelteKitRequestHandler, } from '../modules/auth/sveltekit.js';
46
49
  export { verifyServiceToken, extractBearerToken, } from '../modules/auth/service-token.js';
@@ -66,8 +69,6 @@ export { createNamespaceWsHandler } from './ws-handler.js';
66
69
  export type { NamespaceWsHandlerConfig, NamespaceWsHandler, WsSession, } from './ws-handler.js';
67
70
  export { createRpcHandler } from './rpc-handler.js';
68
71
  export type { RpcHandlerConfig } from './rpc-handler.js';
69
- export { createSoulcraftRouter } from './hono-router.js';
70
- export type { SoulcraftRouterConfig } from './hono-router.js';
71
72
  export { createAnnotationsHandler, createAuthHandler, createChatHandler, createCertificationHandler, createCollectionsHandler, createCommerceHandler, createConfigHandler, createExportHandler, createFormatsHandler, createGraphHandler, createImportHandler, createMediaHandler, createProjectHandler, createPublishHandler, createPulseHandler, createRealtimeHandler, createSearchHandler, createSessionHandler, createSettingsHandler, createWorkspaceHandler, } from './handlers/index.js';
72
73
  export type { AnnotationAiClient, AnnotationsHandlerOptions, ChatHandlerOptions, ChatAIClient, AnthropicStreamEvent, ToolDefinition, ToolExecutor, ToolExecutionContext, SystemPromptBuilder, SystemPromptContext, ChatBillingCheck, ChatEventEmitter, ModelSelector, TieredRouting, RetrievedMemory, UserExpertiseProfile, AIPlan, PlanStep, StepProgress, PlanExecutionResult, AIClientResolverOptions, ResolvedAIClient, CapabilityTokenFactory, AuthHandlerOptions, SampleDataProvider, CollectionsHandlerOptions, PaymentProvider, CommerceHandlerOptions, ConfigService, ConfigBillingService, ConfigHandlerOptions, ExportPipeline, ExportHandlerOptions, FormatConverter, FormatsHandlerOptions, ImportPipeline, ImportHandlerOptions, MediaBackend, MediaHandlerOptions, KitLoader, ProjectHandlerOptions, PublishBackend, VenueDeployService, AcademyPublishService, PublishHandlerOptions, PulseHandlerOptions, RealtimeBackend, RealtimeHandlerOptions, SessionEventEmitter, SessionHandlerOptions, ApiKeyService, SettingsBillingService, StorageTracker, StorageLimitResolver, SettingsHandlerOptions, WorkspaceManager, WorkspaceHandlerOptions, } from './handlers/index.js';
73
74
  export { analyzeComplexity, calculateComplexityScore, selectTieredRouting, createDefaultModelSelector, estimateCost, formatCost, DEFAULT_MODELS, DEFAULT_MODEL_TIERS, streamMessage, sendMessage, createAIClientResolver, } from './handlers/index.js';