@soulcraft/sdk 3.0.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.
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/rpc-handler.d.ts +25 -11
- package/dist/server/rpc-handler.d.ts.map +1 -1
- package/dist/server/rpc-handler.js +18 -11
- package/dist/server/rpc-handler.js.map +1 -1
- package/package.json +1 -1
- package/dist/modules/auth/backchannel.d.ts +0 -59
- package/dist/modules/auth/backchannel.d.ts.map +0 -1
- package/dist/modules/auth/backchannel.js +0 -36
- package/dist/modules/auth/backchannel.js.map +0 -1
- package/dist/modules/auth/middleware.d.ts +0 -272
- package/dist/modules/auth/middleware.d.ts.map +0 -1
- package/dist/modules/auth/middleware.js +0 -295
- package/dist/modules/auth/middleware.js.map +0 -1
package/dist/server/index.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export type { NamespaceRouterConfig, NamespaceRouter, NamespaceProvider, Namespa
|
|
|
59
59
|
export { createNamespaceWsHandler } from './ws-handler.js';
|
|
60
60
|
export type { NamespaceWsHandlerConfig, NamespaceWsHandler, WsSession, } from './ws-handler.js';
|
|
61
61
|
export { createRpcHandler } from './rpc-handler.js';
|
|
62
|
-
export type { RpcHandlerConfig } from './rpc-handler.js';
|
|
62
|
+
export type { RpcHandlerConfig, RpcRequestContext } from './rpc-handler.js';
|
|
63
63
|
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';
|
|
64
64
|
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';
|
|
65
65
|
export { analyzeComplexity, calculateComplexityScore, selectTieredRouting, createDefaultModelSelector, estimateCost, formatCost, DEFAULT_MODELS, DEFAULT_MODEL_TIERS, streamMessage, sendMessage, createAIClientResolver, } from './handlers/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,8 +30,20 @@
|
|
|
30
30
|
* })
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
import type { NamespaceRouterConfig } from './namespace-router.js';
|
|
33
|
+
import type { NamespaceRouterConfig, UserContext } from './namespace-router.js';
|
|
34
34
|
import type { RpcCacheConfig } from './rpc-cache.js';
|
|
35
|
+
/**
|
|
36
|
+
* @description Optional pre-authenticated context for RPC requests.
|
|
37
|
+
* When provided, the handler skips the `authenticate()` callback and uses
|
|
38
|
+
* the given user directly. This is the recommended pattern when auth is
|
|
39
|
+
* already handled by framework middleware (e.g., SvelteKit hooks).
|
|
40
|
+
*/
|
|
41
|
+
export interface RpcRequestContext {
|
|
42
|
+
/** The authenticated user — skips the router's authenticate() callback. */
|
|
43
|
+
user: UserContext;
|
|
44
|
+
/** The active workspace ID (from headers, cookies, or framework locals). */
|
|
45
|
+
workspaceId?: string;
|
|
46
|
+
}
|
|
35
47
|
/**
|
|
36
48
|
* @description Configuration for {@link createRpcHandler}.
|
|
37
49
|
* Extends {@link NamespaceRouterConfig} with optional RPC response caching.
|
|
@@ -54,19 +66,21 @@ export interface RpcHandlerConfig extends NamespaceRouterConfig {
|
|
|
54
66
|
* Streaming results are delivered as SSE (`text/event-stream`).
|
|
55
67
|
*
|
|
56
68
|
* @param config - Namespace router configuration (auth, brain resolution, providers).
|
|
57
|
-
* @returns An async function: `(request
|
|
69
|
+
* @returns An async function: `(request, ctx?) => Promise<Response>`.
|
|
58
70
|
*
|
|
59
|
-
* @example
|
|
71
|
+
* @example Without pre-auth (handler calls authenticate itself):
|
|
60
72
|
* ```typescript
|
|
61
|
-
* const handleRpc = createRpcHandler({
|
|
62
|
-
* resolveBrain: async (ctx) => pool.forUser(ctx.user!.emailHash, ctx.workspaceId),
|
|
63
|
-
* authenticate: async (ctx) => verifySession(ctx.request),
|
|
64
|
-
* providers: { graph: graphHandler, search: searchHandler },
|
|
65
|
-
* })
|
|
66
|
-
*
|
|
67
|
-
* // Use in any server framework:
|
|
73
|
+
* const handleRpc = createRpcHandler({ authenticate, resolveBrain, providers })
|
|
68
74
|
* const response = await handleRpc(request)
|
|
69
75
|
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example With pre-auth (SvelteKit — auth handled by hooks):
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const handleRpc = createRpcHandler({ resolveBrain, providers })
|
|
80
|
+
*
|
|
81
|
+
* export const POST: RequestHandler = ({ request, locals }) =>
|
|
82
|
+
* handleRpc(request, { user: locals.user, workspaceId: locals.workspaceId })
|
|
83
|
+
* ```
|
|
70
84
|
*/
|
|
71
|
-
export declare function createRpcHandler(config: RpcHandlerConfig): (request: Request) => Promise<Response>;
|
|
85
|
+
export declare function createRpcHandler(config: RpcHandlerConfig): (request: Request, ctx?: RpcRequestContext) => Promise<Response>;
|
|
72
86
|
//# sourceMappingURL=rpc-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-handler.d.ts","sourceRoot":"","sources":["../../src/server/rpc-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAkB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"rpc-handler.d.ts","sourceRoot":"","sources":["../../src/server/rpc-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAkB,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAC/F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAGpD;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,IAAI,EAAE,WAAW,CAAA;IACjB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,cAAc,CAAA;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,GACvB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,QAAQ,CAAC,CA2ClE"}
|
|
@@ -40,26 +40,28 @@ import { createCachedDispatch } from './rpc-cache.js';
|
|
|
40
40
|
* Streaming results are delivered as SSE (`text/event-stream`).
|
|
41
41
|
*
|
|
42
42
|
* @param config - Namespace router configuration (auth, brain resolution, providers).
|
|
43
|
-
* @returns An async function: `(request
|
|
43
|
+
* @returns An async function: `(request, ctx?) => Promise<Response>`.
|
|
44
44
|
*
|
|
45
|
-
* @example
|
|
45
|
+
* @example Without pre-auth (handler calls authenticate itself):
|
|
46
46
|
* ```typescript
|
|
47
|
-
* const handleRpc = createRpcHandler({
|
|
48
|
-
* resolveBrain: async (ctx) => pool.forUser(ctx.user!.emailHash, ctx.workspaceId),
|
|
49
|
-
* authenticate: async (ctx) => verifySession(ctx.request),
|
|
50
|
-
* providers: { graph: graphHandler, search: searchHandler },
|
|
51
|
-
* })
|
|
52
|
-
*
|
|
53
|
-
* // Use in any server framework:
|
|
47
|
+
* const handleRpc = createRpcHandler({ authenticate, resolveBrain, providers })
|
|
54
48
|
* const response = await handleRpc(request)
|
|
55
49
|
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example With pre-auth (SvelteKit — auth handled by hooks):
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const handleRpc = createRpcHandler({ resolveBrain, providers })
|
|
54
|
+
*
|
|
55
|
+
* export const POST: RequestHandler = ({ request, locals }) =>
|
|
56
|
+
* handleRpc(request, { user: locals.user, workspaceId: locals.workspaceId })
|
|
57
|
+
* ```
|
|
56
58
|
*/
|
|
57
59
|
export function createRpcHandler(config) {
|
|
58
60
|
const baseRouter = createNamespaceRouter(config);
|
|
59
61
|
const router = config.cache
|
|
60
62
|
? createCachedDispatch(baseRouter, config.cache)
|
|
61
63
|
: baseRouter;
|
|
62
|
-
return async (request) => {
|
|
64
|
+
return async (request, ctx) => {
|
|
63
65
|
// ── Parse JSON body ────────────────────────────────────────────────────
|
|
64
66
|
let body;
|
|
65
67
|
try {
|
|
@@ -80,7 +82,12 @@ export function createRpcHandler(config) {
|
|
|
80
82
|
stream: body.stream ?? false,
|
|
81
83
|
};
|
|
82
84
|
// ── Dispatch ──────────────────────────────────────────────────────────
|
|
83
|
-
|
|
85
|
+
// When a pre-authenticated context is provided, pass it to the router so
|
|
86
|
+
// it skips the authenticate() callback. Otherwise pass the raw request.
|
|
87
|
+
const dispatchCtx = ctx
|
|
88
|
+
? { user: ctx.user, workspaceId: ctx.workspaceId ?? '', request }
|
|
89
|
+
: request;
|
|
90
|
+
const result = await router.dispatch(rpc, dispatchCtx);
|
|
84
91
|
return _toResponse(result);
|
|
85
92
|
};
|
|
86
93
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc-handler.js","sourceRoot":"","sources":["../../src/server/rpc-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"rpc-handler.js","sourceRoot":"","sources":["../../src/server/rpc-handler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module modules/auth/backchannel
|
|
3
|
-
* @description Shared types for OIDC back-channel logout handlers.
|
|
4
|
-
*
|
|
5
|
-
* The framework-agnostic handler (`createRequestBackchannelLogoutHandler`) lives in
|
|
6
|
-
* `request-backchannel.ts` and imports these types. This module provides the shared
|
|
7
|
-
* configuration interface and the minimal better-auth API surface needed for session
|
|
8
|
-
* revocation.
|
|
9
|
-
*
|
|
10
|
-
* ## Protocol
|
|
11
|
-
*
|
|
12
|
-
* 1. IdP POSTs `application/x-www-form-urlencoded` body with `logout_token` field
|
|
13
|
-
* 2. Handler verifies HS256 JWT signature using the OIDC client secret
|
|
14
|
-
* 3. Handler validates standard claims: `iss`, `aud`, `events` (must contain
|
|
15
|
-
* `http://schemas.openid.net/event/backchannel-logout`)
|
|
16
|
-
* 4. Handler deletes all better-auth sessions for the `sub` (user ID) claim
|
|
17
|
-
* 5. Returns 200 on success, 400 for malformed tokens, 401 for bad signatures
|
|
18
|
-
*
|
|
19
|
-
* ## Usage
|
|
20
|
-
*
|
|
21
|
-
* ```typescript
|
|
22
|
-
* import { createRequestBackchannelLogoutHandler } from '@soulcraft/sdk/server'
|
|
23
|
-
*
|
|
24
|
-
* const handleLogout = createRequestBackchannelLogoutHandler({
|
|
25
|
-
* auth,
|
|
26
|
-
* clientSecret: process.env.SOULCRAFT_OIDC_CLIENT_SECRET!,
|
|
27
|
-
* idpUrl: process.env.SOULCRAFT_IDP_URL!,
|
|
28
|
-
* clientId: process.env.SOULCRAFT_OIDC_CLIENT_ID!,
|
|
29
|
-
* })
|
|
30
|
-
*
|
|
31
|
-
* // SvelteKit: export const POST = ({ request }) => handleLogout(request)
|
|
32
|
-
* // Bun: if (url.pathname === '/api/auth/backchannel-logout') return handleLogout(req)
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
/** Minimal better-auth API surface needed for session deletion. */
|
|
36
|
-
export interface BackchannelAuthLike {
|
|
37
|
-
api: {
|
|
38
|
-
revokeUserSessions(opts: {
|
|
39
|
-
body: {
|
|
40
|
-
userId: string;
|
|
41
|
-
};
|
|
42
|
-
headers?: Headers;
|
|
43
|
-
}): Promise<unknown>;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* @description Configuration for `createRequestBackchannelLogoutHandler()`.
|
|
48
|
-
*/
|
|
49
|
-
export interface BackchannelLogoutConfig {
|
|
50
|
-
/** The product's better-auth instance (used to delete sessions). */
|
|
51
|
-
auth: BackchannelAuthLike;
|
|
52
|
-
/** This product's OIDC client secret — used to verify the logout_token signature. */
|
|
53
|
-
clientSecret: string;
|
|
54
|
-
/** The central IdP base URL — used to validate the `iss` claim. */
|
|
55
|
-
idpUrl: string;
|
|
56
|
-
/** This product's OIDC client ID — used to validate the `aud` claim. */
|
|
57
|
-
clientId: string;
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=backchannel.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"backchannel.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/backchannel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;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"}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module modules/auth/backchannel
|
|
3
|
-
* @description Shared types for OIDC back-channel logout handlers.
|
|
4
|
-
*
|
|
5
|
-
* The framework-agnostic handler (`createRequestBackchannelLogoutHandler`) lives in
|
|
6
|
-
* `request-backchannel.ts` and imports these types. This module provides the shared
|
|
7
|
-
* configuration interface and the minimal better-auth API surface needed for session
|
|
8
|
-
* revocation.
|
|
9
|
-
*
|
|
10
|
-
* ## Protocol
|
|
11
|
-
*
|
|
12
|
-
* 1. IdP POSTs `application/x-www-form-urlencoded` body with `logout_token` field
|
|
13
|
-
* 2. Handler verifies HS256 JWT signature using the OIDC client secret
|
|
14
|
-
* 3. Handler validates standard claims: `iss`, `aud`, `events` (must contain
|
|
15
|
-
* `http://schemas.openid.net/event/backchannel-logout`)
|
|
16
|
-
* 4. Handler deletes all better-auth sessions for the `sub` (user ID) claim
|
|
17
|
-
* 5. Returns 200 on success, 400 for malformed tokens, 401 for bad signatures
|
|
18
|
-
*
|
|
19
|
-
* ## Usage
|
|
20
|
-
*
|
|
21
|
-
* ```typescript
|
|
22
|
-
* import { createRequestBackchannelLogoutHandler } from '@soulcraft/sdk/server'
|
|
23
|
-
*
|
|
24
|
-
* const handleLogout = createRequestBackchannelLogoutHandler({
|
|
25
|
-
* auth,
|
|
26
|
-
* clientSecret: process.env.SOULCRAFT_OIDC_CLIENT_SECRET!,
|
|
27
|
-
* idpUrl: process.env.SOULCRAFT_IDP_URL!,
|
|
28
|
-
* clientId: process.env.SOULCRAFT_OIDC_CLIENT_ID!,
|
|
29
|
-
* })
|
|
30
|
-
*
|
|
31
|
-
* // SvelteKit: export const POST = ({ request }) => handleLogout(request)
|
|
32
|
-
* // Bun: if (url.pathname === '/api/auth/backchannel-logout') return handleLogout(req)
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export {};
|
|
36
|
-
//# sourceMappingURL=backchannel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"backchannel.js","sourceRoot":"","sources":["../../../src/modules/auth/backchannel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG"}
|
|
@@ -1,272 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module modules/auth/middleware
|
|
3
|
-
* @description Session verification factories and shared auth types for Soulcraft
|
|
4
|
-
* product backends.
|
|
5
|
-
*
|
|
6
|
-
* ## Session verification strategies
|
|
7
|
-
*
|
|
8
|
-
* All products select the right session verifier for their deployment context:
|
|
9
|
-
*
|
|
10
|
-
* ```
|
|
11
|
-
* Production (all products):
|
|
12
|
-
* createRemoteSessionVerifier({ idpUrl: 'https://auth.soulcraft.com' })
|
|
13
|
-
*
|
|
14
|
-
* Development (all products):
|
|
15
|
-
* createDevSessionVerifier({ role: 'owner' }) // auto-login, no OAuth needed
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
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
|
|
26
|
-
*
|
|
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.).
|
|
30
|
-
*
|
|
31
|
-
* @example Production setup (Venue / Academy)
|
|
32
|
-
* ```typescript
|
|
33
|
-
* import {
|
|
34
|
-
* createRequestAuthMiddleware,
|
|
35
|
-
* createRemoteSessionVerifier,
|
|
36
|
-
* getUser,
|
|
37
|
-
* } from '@soulcraft/sdk/server'
|
|
38
|
-
*
|
|
39
|
-
* const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
|
|
40
|
-
* const { requireAuth } = createRequestAuthMiddleware(verifySession)
|
|
41
|
-
*
|
|
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
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
import type { SoulcraftSessionUser, SoulcraftSession } from './types.js';
|
|
51
|
-
/** Minimal better-auth API surface the middleware depends on. */
|
|
52
|
-
export interface BetterAuthLike {
|
|
53
|
-
api: {
|
|
54
|
-
getSession(opts: {
|
|
55
|
-
headers: Headers;
|
|
56
|
-
}): Promise<{
|
|
57
|
-
user: Record<string, unknown>;
|
|
58
|
-
session: {
|
|
59
|
-
id: string;
|
|
60
|
-
expiresAt: Date | string | number;
|
|
61
|
-
};
|
|
62
|
-
} | null>;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* A session verifier function — the common abstraction for session resolution
|
|
67
|
-
* across all products.
|
|
68
|
-
*
|
|
69
|
-
* Returned by `createRemoteSessionVerifier` and `createDevSessionVerifier`.
|
|
70
|
-
* Pass to `createRequestAuthMiddleware` for the framework-agnostic middleware.
|
|
71
|
-
*/
|
|
72
|
-
export type SessionVerifier = (cookieHeader: string) => Promise<SoulcraftSession | null>;
|
|
73
|
-
/**
|
|
74
|
-
* Options for `createRequestAuthMiddleware()` and legacy middleware.
|
|
75
|
-
*/
|
|
76
|
-
export interface AuthMiddlewareOptions {
|
|
77
|
-
/**
|
|
78
|
-
* If true, a synthetic dev user is injected in non-production environments
|
|
79
|
-
* when a `BetterAuthLike` auth instance is provided and session lookup fails.
|
|
80
|
-
* Not used when a `SessionVerifier` function is provided — use
|
|
81
|
-
* `createDevSessionVerifier` instead for full dev auto-login in that mode.
|
|
82
|
-
* @default true
|
|
83
|
-
*/
|
|
84
|
-
devAutoLogin?: boolean;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Options for `createRemoteSessionVerifier()`.
|
|
88
|
-
*/
|
|
89
|
-
export interface RemoteSessionVerifierOptions {
|
|
90
|
-
/** The central IdP base URL, e.g. `"https://auth.soulcraft.com"`. */
|
|
91
|
-
idpUrl: string;
|
|
92
|
-
/** Session cache TTL in milliseconds. Default: 30 000 (30 seconds). */
|
|
93
|
-
cacheTtlMs?: number;
|
|
94
|
-
/** Maximum cached sessions. Default: 500. */
|
|
95
|
-
cacheMax?: number;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Options for `createDevSessionVerifier()`.
|
|
99
|
-
*/
|
|
100
|
-
export interface DevSessionVerifierOptions {
|
|
101
|
-
/**
|
|
102
|
-
* The platform role to assign to the synthetic dev session.
|
|
103
|
-
* @default 'owner'
|
|
104
|
-
*/
|
|
105
|
-
role?: SoulcraftSessionUser['platformRole'];
|
|
106
|
-
/**
|
|
107
|
-
* Email address for the synthetic dev user.
|
|
108
|
-
* @default 'dev@soulcraft.com'
|
|
109
|
-
*/
|
|
110
|
-
email?: string;
|
|
111
|
-
/**
|
|
112
|
-
* Display name for the synthetic dev user.
|
|
113
|
-
* @default 'Dev User'
|
|
114
|
-
*/
|
|
115
|
-
name?: string;
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Options for `createRequestDevLoginHandler()`.
|
|
119
|
-
*/
|
|
120
|
-
export interface DevLoginHandlerOptions {
|
|
121
|
-
/**
|
|
122
|
-
* Allowed platform roles. The role must be in this list for the handler to
|
|
123
|
-
* issue a session cookie. Defaults to all non-guest platform roles.
|
|
124
|
-
* @default ['creator','viewer','customer','staff','manager','owner','learner','instructor']
|
|
125
|
-
*/
|
|
126
|
-
allowedRoles?: SoulcraftSessionUser['platformRole'][];
|
|
127
|
-
/**
|
|
128
|
-
* Cookie name for the issued dev session.
|
|
129
|
-
* @default 'soulcraft_dev_session'
|
|
130
|
-
*/
|
|
131
|
-
cookieName?: string;
|
|
132
|
-
/**
|
|
133
|
-
* Session cookie max-age in seconds.
|
|
134
|
-
* @default 86400 (24 hours)
|
|
135
|
-
*/
|
|
136
|
-
maxAgeSeconds?: number;
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Options for `createRequestGuestSessionHandler()`.
|
|
140
|
-
*/
|
|
141
|
-
export interface GuestSessionHandlerOptions {
|
|
142
|
-
/**
|
|
143
|
-
* Cookie name for the issued guest session.
|
|
144
|
-
* @default 'soulcraft_guest_session'
|
|
145
|
-
*/
|
|
146
|
-
cookieName?: string;
|
|
147
|
-
/**
|
|
148
|
-
* Guest session max-age in seconds.
|
|
149
|
-
* @default 3600 (1 hour)
|
|
150
|
-
*/
|
|
151
|
-
maxAgeSeconds?: number;
|
|
152
|
-
/**
|
|
153
|
-
* An optional callback invoked when a new guest session is created.
|
|
154
|
-
* Receives the generated guest ID. Useful for analytics or initializing
|
|
155
|
-
* a guest cart/basket in the product's store.
|
|
156
|
-
*
|
|
157
|
-
* @param guestId - The newly generated unique guest ID.
|
|
158
|
-
*/
|
|
159
|
-
onGuestCreated?: (guestId: string) => Promise<void> | void;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Creates a cached remote session verifier that proxies session lookups to
|
|
163
|
-
* the central IdP at `auth.soulcraft.com`.
|
|
164
|
-
*
|
|
165
|
-
* Used by products that operate as OIDC clients (Venue, Academy, and Workshop
|
|
166
|
-
* in production). Caches successful lookups in an LRU cache to avoid per-request
|
|
167
|
-
* HTTP round-trips to the IdP.
|
|
168
|
-
*
|
|
169
|
-
* The verifier sends the cookie header to the IdP's `/api/auth/get-session` endpoint
|
|
170
|
-
* and returns the resolved `SoulcraftSession` or `null` if the session is invalid.
|
|
171
|
-
*
|
|
172
|
-
* Pass the returned function to `createRequestAuthMiddleware`:
|
|
173
|
-
* ```typescript
|
|
174
|
-
* const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
|
|
175
|
-
* const { requireAuth } = createRequestAuthMiddleware(verifySession)
|
|
176
|
-
* ```
|
|
177
|
-
*
|
|
178
|
-
* @param options - IdP URL, cache TTL, and max cache size.
|
|
179
|
-
* @returns A `SessionVerifier` — async function that accepts a cookie header string.
|
|
180
|
-
*
|
|
181
|
-
* @example
|
|
182
|
-
* ```typescript
|
|
183
|
-
* const verifySession = createRemoteSessionVerifier({
|
|
184
|
-
* idpUrl: 'https://auth.soulcraft.com',
|
|
185
|
-
* cacheTtlMs: 30_000,
|
|
186
|
-
* })
|
|
187
|
-
*
|
|
188
|
-
* const session = await verifySession(request.headers.get('cookie') ?? '')
|
|
189
|
-
* if (!session) return new Response('Unauthorized', { status: 401 })
|
|
190
|
-
* ```
|
|
191
|
-
*/
|
|
192
|
-
export declare function createRemoteSessionVerifier(options: RemoteSessionVerifierOptions): SessionVerifier;
|
|
193
|
-
/**
|
|
194
|
-
* Creates a session verifier that always resolves to a synthetic dev session.
|
|
195
|
-
*
|
|
196
|
-
* Intended for products that run as OIDC clients but need local development auth
|
|
197
|
-
* without OAuth, network calls, SQLite, or real cookies. The returned verifier always
|
|
198
|
-
* succeeds — any request resolves to the configured synthetic user.
|
|
199
|
-
*
|
|
200
|
-
* Designed as a drop-in replacement for `createRemoteSessionVerifier` in local dev:
|
|
201
|
-
*
|
|
202
|
-
* ```typescript
|
|
203
|
-
* const verifySession = process.env.SOULCRAFT_IDP_URL
|
|
204
|
-
* ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
|
|
205
|
-
* : createDevSessionVerifier({ role: 'owner' })
|
|
206
|
-
*
|
|
207
|
-
* const { requireAuth } = createRequestAuthMiddleware(verifySession)
|
|
208
|
-
* ```
|
|
209
|
-
*
|
|
210
|
-
* **Never use in production.** The verifier performs no validation whatsoever.
|
|
211
|
-
*
|
|
212
|
-
* @param options - Optional synthetic user configuration.
|
|
213
|
-
* @returns A `SessionVerifier` with the same signature as `createRemoteSessionVerifier`.
|
|
214
|
-
*
|
|
215
|
-
* @example
|
|
216
|
-
* ```typescript
|
|
217
|
-
* const verifySession = process.env.SOULCRAFT_IDP_URL
|
|
218
|
-
* ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
|
|
219
|
-
* : createDevSessionVerifier({ role: 'owner' })
|
|
220
|
-
*
|
|
221
|
-
* export const handle = async ({ event, resolve }) => {
|
|
222
|
-
* const session = await verifySession(event.request.headers.get('cookie') ?? '')
|
|
223
|
-
* event.locals.session = session
|
|
224
|
-
* return resolve(event)
|
|
225
|
-
* }
|
|
226
|
-
* ```
|
|
227
|
-
*/
|
|
228
|
-
export declare function createDevSessionVerifier(options?: DevSessionVerifierOptions): SessionVerifier;
|
|
229
|
-
/**
|
|
230
|
-
* Creates a session verifier that reads the cookie issued by `createRequestDevLoginHandler`.
|
|
231
|
-
*
|
|
232
|
-
* Use this together with `createRequestDevLoginHandler` when you want dev role-switching
|
|
233
|
-
* (e.g. clicking "Login as Staff" in a dev UI) rather than a fixed synthetic user.
|
|
234
|
-
*
|
|
235
|
-
* The verifier decodes the base64url cookie value and returns the embedded session.
|
|
236
|
-
* Falls back to `null` (unauthenticated) if the cookie is absent or expired.
|
|
237
|
-
*
|
|
238
|
-
* ```typescript
|
|
239
|
-
* // Only one of these in dev — pick what fits your workflow:
|
|
240
|
-
*
|
|
241
|
-
* // Option A: Fixed dev user, no login UI needed
|
|
242
|
-
* const verifySession = createDevSessionVerifier({ role: 'owner' })
|
|
243
|
-
*
|
|
244
|
-
* // Option B: Role-switching dev login UI
|
|
245
|
-
* const loginHandler = createRequestDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] })
|
|
246
|
-
* const verifySession = createDevCookieVerifier()
|
|
247
|
-
* ```
|
|
248
|
-
*
|
|
249
|
-
* @param cookieName - Must match the `cookieName` passed to `createRequestDevLoginHandler`. Default: `'soulcraft_dev_session'`.
|
|
250
|
-
* @returns A `SessionVerifier` compatible with `createRequestAuthMiddleware`.
|
|
251
|
-
*/
|
|
252
|
-
export declare function createDevCookieVerifier(cookieName?: string): SessionVerifier;
|
|
253
|
-
/**
|
|
254
|
-
* Creates a session verifier that reads the cookie issued by `createRequestGuestSessionHandler`.
|
|
255
|
-
*
|
|
256
|
-
* Returns the guest `SoulcraftSession` or `null` if no valid guest cookie is present.
|
|
257
|
-
* Compose with `createRemoteSessionVerifier` to allow both authenticated and guest access:
|
|
258
|
-
*
|
|
259
|
-
* ```typescript
|
|
260
|
-
* const verifyReal = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
|
|
261
|
-
* const verifyGuest = createGuestCookieVerifier()
|
|
262
|
-
*
|
|
263
|
-
* const { optionalAuth } = createRequestAuthMiddleware(async (cookie) =>
|
|
264
|
-
* await verifyReal(cookie) ?? await verifyGuest(cookie)
|
|
265
|
-
* )
|
|
266
|
-
* ```
|
|
267
|
-
*
|
|
268
|
-
* @param cookieName - Must match the `cookieName` passed to `createRequestGuestSessionHandler`. Default: `'soulcraft_guest_session'`.
|
|
269
|
-
* @returns A `SessionVerifier` compatible with `createRequestAuthMiddleware`.
|
|
270
|
-
*/
|
|
271
|
-
export declare function createGuestCookieVerifier(cookieName?: string): SessionVerifier;
|
|
272
|
-
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAMxE,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE;QACH,UAAU,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,OAAO,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAC;gBAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;aAAE,CAAA;SAAE,GAAG,IAAI,CAAC,CAAA;KACtJ,CAAA;CACF;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;AAExF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAA;IACd,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,CAAA;IAC3C;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC,cAAc,CAAC,EAAE,CAAA;IACrD;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC3D;AA+BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,eAAe,CAkEjB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,yBAA8B,GACtC,eAAe,CAsBjB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,SAA0B,GACnC,eAAe,CAMjB;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,SAA4B,GACrC,eAAe,CAMjB"}
|
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module modules/auth/middleware
|
|
3
|
-
* @description Session verification factories and shared auth types for Soulcraft
|
|
4
|
-
* product backends.
|
|
5
|
-
*
|
|
6
|
-
* ## Session verification strategies
|
|
7
|
-
*
|
|
8
|
-
* All products select the right session verifier for their deployment context:
|
|
9
|
-
*
|
|
10
|
-
* ```
|
|
11
|
-
* Production (all products):
|
|
12
|
-
* createRemoteSessionVerifier({ idpUrl: 'https://auth.soulcraft.com' })
|
|
13
|
-
*
|
|
14
|
-
* Development (all products):
|
|
15
|
-
* createDevSessionVerifier({ role: 'owner' }) // auto-login, no OAuth needed
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
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
|
|
26
|
-
*
|
|
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.).
|
|
30
|
-
*
|
|
31
|
-
* @example Production setup (Venue / Academy)
|
|
32
|
-
* ```typescript
|
|
33
|
-
* import {
|
|
34
|
-
* createRequestAuthMiddleware,
|
|
35
|
-
* createRemoteSessionVerifier,
|
|
36
|
-
* getUser,
|
|
37
|
-
* } from '@soulcraft/sdk/server'
|
|
38
|
-
*
|
|
39
|
-
* const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
|
|
40
|
-
* const { requireAuth } = createRequestAuthMiddleware(verifySession)
|
|
41
|
-
*
|
|
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
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
import { LRUCache } from 'lru-cache';
|
|
51
|
-
import { computeEmailHash } from './config.js';
|
|
52
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
53
|
-
// Shared internal helpers
|
|
54
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
55
|
-
/** Parse a simple `name=value` cookie from a raw cookie header string. */
|
|
56
|
-
function _parseCookie(cookieHeader, name) {
|
|
57
|
-
for (const part of cookieHeader.split(';')) {
|
|
58
|
-
const [k, ...rest] = part.trim().split('=');
|
|
59
|
-
if (k?.trim() === name)
|
|
60
|
-
return rest.join('=').trim();
|
|
61
|
-
}
|
|
62
|
-
return undefined;
|
|
63
|
-
}
|
|
64
|
-
/** Decode a session payload encoded by `_encodeSessionCookie`. Returns null on any error. */
|
|
65
|
-
function _decodeSessionCookie(value) {
|
|
66
|
-
try {
|
|
67
|
-
const raw = JSON.parse(Buffer.from(value, 'base64url').toString('utf-8'));
|
|
68
|
-
if (!raw.user || !raw.sessionId || !raw.expiresAt)
|
|
69
|
-
return null;
|
|
70
|
-
if (raw.expiresAt < Date.now())
|
|
71
|
-
return null;
|
|
72
|
-
return raw;
|
|
73
|
-
}
|
|
74
|
-
catch {
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
79
|
-
// createRemoteSessionVerifier
|
|
80
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
81
|
-
/**
|
|
82
|
-
* Creates a cached remote session verifier that proxies session lookups to
|
|
83
|
-
* the central IdP at `auth.soulcraft.com`.
|
|
84
|
-
*
|
|
85
|
-
* Used by products that operate as OIDC clients (Venue, Academy, and Workshop
|
|
86
|
-
* in production). Caches successful lookups in an LRU cache to avoid per-request
|
|
87
|
-
* HTTP round-trips to the IdP.
|
|
88
|
-
*
|
|
89
|
-
* The verifier sends the cookie header to the IdP's `/api/auth/get-session` endpoint
|
|
90
|
-
* and returns the resolved `SoulcraftSession` or `null` if the session is invalid.
|
|
91
|
-
*
|
|
92
|
-
* Pass the returned function to `createRequestAuthMiddleware`:
|
|
93
|
-
* ```typescript
|
|
94
|
-
* const verifySession = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
|
|
95
|
-
* const { requireAuth } = createRequestAuthMiddleware(verifySession)
|
|
96
|
-
* ```
|
|
97
|
-
*
|
|
98
|
-
* @param options - IdP URL, cache TTL, and max cache size.
|
|
99
|
-
* @returns A `SessionVerifier` — async function that accepts a cookie header string.
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* ```typescript
|
|
103
|
-
* const verifySession = createRemoteSessionVerifier({
|
|
104
|
-
* idpUrl: 'https://auth.soulcraft.com',
|
|
105
|
-
* cacheTtlMs: 30_000,
|
|
106
|
-
* })
|
|
107
|
-
*
|
|
108
|
-
* const session = await verifySession(request.headers.get('cookie') ?? '')
|
|
109
|
-
* if (!session) return new Response('Unauthorized', { status: 401 })
|
|
110
|
-
* ```
|
|
111
|
-
*/
|
|
112
|
-
export function createRemoteSessionVerifier(options) {
|
|
113
|
-
const cacheTtl = options.cacheTtlMs ?? 30_000;
|
|
114
|
-
const cacheMax = options.cacheMax ?? 500;
|
|
115
|
-
const sessionUrl = `${options.idpUrl.replace(/\/$/, '')}/api/auth/get-session`;
|
|
116
|
-
const cache = new LRUCache({
|
|
117
|
-
max: cacheMax,
|
|
118
|
-
ttl: cacheTtl,
|
|
119
|
-
});
|
|
120
|
-
return async function verifyRemoteSession(cookieHeader) {
|
|
121
|
-
if (!cookieHeader)
|
|
122
|
-
return null;
|
|
123
|
-
// Use cookie header as cache key — it contains the session token
|
|
124
|
-
const cached = cache.get(cookieHeader);
|
|
125
|
-
if (cached !== undefined)
|
|
126
|
-
return cached;
|
|
127
|
-
let response;
|
|
128
|
-
try {
|
|
129
|
-
response = await fetch(sessionUrl, {
|
|
130
|
-
headers: { cookie: cookieHeader },
|
|
131
|
-
credentials: 'include',
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
if (!response.ok)
|
|
138
|
-
return null;
|
|
139
|
-
let data;
|
|
140
|
-
try {
|
|
141
|
-
data = await response.json();
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
// `get-session` returns the JSON literal `null` when no session is active.
|
|
147
|
-
// The fetch succeeds (200 OK) and `response.json()` parses it without error,
|
|
148
|
-
// but `data` is null — not an object. Guard before any property access.
|
|
149
|
-
if (!data || typeof data !== 'object')
|
|
150
|
-
return null;
|
|
151
|
-
const rawUser = data['user'];
|
|
152
|
-
const rawSession = data['session'];
|
|
153
|
-
if (!rawUser || !rawSession)
|
|
154
|
-
return null;
|
|
155
|
-
const email = String(rawUser['email'] ?? '');
|
|
156
|
-
const session = {
|
|
157
|
-
user: {
|
|
158
|
-
id: String(rawUser['id'] ?? ''),
|
|
159
|
-
email,
|
|
160
|
-
name: String(rawUser['name'] ?? ''),
|
|
161
|
-
image: rawUser['image'] ?? null,
|
|
162
|
-
platformRole: rawUser['platformRole'] ?? 'creator',
|
|
163
|
-
emailHash: rawUser['emailHash'] ? String(rawUser['emailHash']) : computeEmailHash(email),
|
|
164
|
-
...(rawUser['handle'] ? { handle: String(rawUser['handle']) } : {}),
|
|
165
|
-
},
|
|
166
|
-
sessionId: String(rawSession['id'] ?? ''),
|
|
167
|
-
expiresAt: Number(rawSession['expiresAt'] ?? 0),
|
|
168
|
-
};
|
|
169
|
-
cache.set(cookieHeader, session);
|
|
170
|
-
return session;
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
174
|
-
// createDevSessionVerifier
|
|
175
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
176
|
-
/**
|
|
177
|
-
* Creates a session verifier that always resolves to a synthetic dev session.
|
|
178
|
-
*
|
|
179
|
-
* Intended for products that run as OIDC clients but need local development auth
|
|
180
|
-
* without OAuth, network calls, SQLite, or real cookies. The returned verifier always
|
|
181
|
-
* succeeds — any request resolves to the configured synthetic user.
|
|
182
|
-
*
|
|
183
|
-
* Designed as a drop-in replacement for `createRemoteSessionVerifier` in local dev:
|
|
184
|
-
*
|
|
185
|
-
* ```typescript
|
|
186
|
-
* const verifySession = process.env.SOULCRAFT_IDP_URL
|
|
187
|
-
* ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
|
|
188
|
-
* : createDevSessionVerifier({ role: 'owner' })
|
|
189
|
-
*
|
|
190
|
-
* const { requireAuth } = createRequestAuthMiddleware(verifySession)
|
|
191
|
-
* ```
|
|
192
|
-
*
|
|
193
|
-
* **Never use in production.** The verifier performs no validation whatsoever.
|
|
194
|
-
*
|
|
195
|
-
* @param options - Optional synthetic user configuration.
|
|
196
|
-
* @returns A `SessionVerifier` with the same signature as `createRemoteSessionVerifier`.
|
|
197
|
-
*
|
|
198
|
-
* @example
|
|
199
|
-
* ```typescript
|
|
200
|
-
* const verifySession = process.env.SOULCRAFT_IDP_URL
|
|
201
|
-
* ? createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL })
|
|
202
|
-
* : createDevSessionVerifier({ role: 'owner' })
|
|
203
|
-
*
|
|
204
|
-
* export const handle = async ({ event, resolve }) => {
|
|
205
|
-
* const session = await verifySession(event.request.headers.get('cookie') ?? '')
|
|
206
|
-
* event.locals.session = session
|
|
207
|
-
* return resolve(event)
|
|
208
|
-
* }
|
|
209
|
-
* ```
|
|
210
|
-
*/
|
|
211
|
-
export function createDevSessionVerifier(options = {}) {
|
|
212
|
-
const role = options.role ?? 'owner';
|
|
213
|
-
const email = options.email ?? 'dev@soulcraft.com';
|
|
214
|
-
const name = options.name ?? 'Dev User';
|
|
215
|
-
const session = {
|
|
216
|
-
user: {
|
|
217
|
-
id: 'dev-user-001',
|
|
218
|
-
email,
|
|
219
|
-
name,
|
|
220
|
-
image: null,
|
|
221
|
-
platformRole: role,
|
|
222
|
-
emailHash: computeEmailHash(email),
|
|
223
|
-
handle: 'dev',
|
|
224
|
-
},
|
|
225
|
-
sessionId: 'dev-session-001',
|
|
226
|
-
expiresAt: Date.now() + 30 * 24 * 60 * 60 * 1000,
|
|
227
|
-
};
|
|
228
|
-
return async function verifyDevSession() {
|
|
229
|
-
return session;
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
233
|
-
// createDevCookieVerifier
|
|
234
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
235
|
-
/**
|
|
236
|
-
* Creates a session verifier that reads the cookie issued by `createRequestDevLoginHandler`.
|
|
237
|
-
*
|
|
238
|
-
* Use this together with `createRequestDevLoginHandler` when you want dev role-switching
|
|
239
|
-
* (e.g. clicking "Login as Staff" in a dev UI) rather than a fixed synthetic user.
|
|
240
|
-
*
|
|
241
|
-
* The verifier decodes the base64url cookie value and returns the embedded session.
|
|
242
|
-
* Falls back to `null` (unauthenticated) if the cookie is absent or expired.
|
|
243
|
-
*
|
|
244
|
-
* ```typescript
|
|
245
|
-
* // Only one of these in dev — pick what fits your workflow:
|
|
246
|
-
*
|
|
247
|
-
* // Option A: Fixed dev user, no login UI needed
|
|
248
|
-
* const verifySession = createDevSessionVerifier({ role: 'owner' })
|
|
249
|
-
*
|
|
250
|
-
* // Option B: Role-switching dev login UI
|
|
251
|
-
* const loginHandler = createRequestDevLoginHandler({ allowedRoles: ['owner', 'staff', 'customer'] })
|
|
252
|
-
* const verifySession = createDevCookieVerifier()
|
|
253
|
-
* ```
|
|
254
|
-
*
|
|
255
|
-
* @param cookieName - Must match the `cookieName` passed to `createRequestDevLoginHandler`. Default: `'soulcraft_dev_session'`.
|
|
256
|
-
* @returns A `SessionVerifier` compatible with `createRequestAuthMiddleware`.
|
|
257
|
-
*/
|
|
258
|
-
export function createDevCookieVerifier(cookieName = 'soulcraft_dev_session') {
|
|
259
|
-
return async function verifyDevCookie(cookieHeader) {
|
|
260
|
-
const value = _parseCookie(cookieHeader, cookieName);
|
|
261
|
-
if (!value)
|
|
262
|
-
return null;
|
|
263
|
-
return _decodeSessionCookie(value);
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
267
|
-
// createGuestCookieVerifier
|
|
268
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
269
|
-
/**
|
|
270
|
-
* Creates a session verifier that reads the cookie issued by `createRequestGuestSessionHandler`.
|
|
271
|
-
*
|
|
272
|
-
* Returns the guest `SoulcraftSession` or `null` if no valid guest cookie is present.
|
|
273
|
-
* Compose with `createRemoteSessionVerifier` to allow both authenticated and guest access:
|
|
274
|
-
*
|
|
275
|
-
* ```typescript
|
|
276
|
-
* const verifyReal = createRemoteSessionVerifier({ idpUrl: process.env.SOULCRAFT_IDP_URL! })
|
|
277
|
-
* const verifyGuest = createGuestCookieVerifier()
|
|
278
|
-
*
|
|
279
|
-
* const { optionalAuth } = createRequestAuthMiddleware(async (cookie) =>
|
|
280
|
-
* await verifyReal(cookie) ?? await verifyGuest(cookie)
|
|
281
|
-
* )
|
|
282
|
-
* ```
|
|
283
|
-
*
|
|
284
|
-
* @param cookieName - Must match the `cookieName` passed to `createRequestGuestSessionHandler`. Default: `'soulcraft_guest_session'`.
|
|
285
|
-
* @returns A `SessionVerifier` compatible with `createRequestAuthMiddleware`.
|
|
286
|
-
*/
|
|
287
|
-
export function createGuestCookieVerifier(cookieName = 'soulcraft_guest_session') {
|
|
288
|
-
return async function verifyGuestCookie(cookieHeader) {
|
|
289
|
-
const value = _parseCookie(cookieHeader, cookieName);
|
|
290
|
-
if (!value)
|
|
291
|
-
return null;
|
|
292
|
-
return _decodeSessionCookie(value);
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
//# sourceMappingURL=middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/modules/auth/middleware.ts"],"names":[],"mappings":"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"}
|