@soulcraft/sdk 1.6.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/create-client-sdk.d.ts +16 -2
- package/dist/client/create-client-sdk.d.ts.map +1 -1
- package/dist/client/create-client-sdk.js +2 -7
- package/dist/client/create-client-sdk.js.map +1 -1
- package/dist/client/index.d.ts +48 -37
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +61 -42
- package/dist/client/index.js.map +1 -1
- package/dist/client/namespace-proxy.d.ts +108 -0
- package/dist/client/namespace-proxy.d.ts.map +1 -0
- package/dist/client/namespace-proxy.js +151 -0
- package/dist/client/namespace-proxy.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/app-context/index.d.ts +214 -0
- package/dist/modules/app-context/index.d.ts.map +1 -0
- package/dist/modules/app-context/index.js +569 -0
- package/dist/modules/app-context/index.js.map +1 -0
- package/dist/modules/auth/products.d.ts +208 -0
- package/dist/modules/auth/products.d.ts.map +1 -0
- package/dist/modules/auth/products.js +165 -0
- package/dist/modules/auth/products.js.map +1 -0
- package/dist/namespaces.d.ts +2942 -0
- package/dist/namespaces.d.ts.map +1 -0
- package/dist/namespaces.js +37 -0
- package/dist/namespaces.js.map +1 -0
- package/dist/rpc.d.ts +156 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +26 -0
- package/dist/rpc.js.map +1 -0
- package/dist/server/create-sdk.d.ts.map +1 -1
- package/dist/server/create-sdk.js +3 -13
- package/dist/server/create-sdk.js.map +1 -1
- package/dist/server/handlers/annotations.d.ts +52 -0
- package/dist/server/handlers/annotations.d.ts.map +1 -0
- package/dist/server/handlers/annotations.js +204 -0
- package/dist/server/handlers/annotations.js.map +1 -0
- package/dist/server/handlers/auth.d.ts +53 -0
- package/dist/server/handlers/auth.d.ts.map +1 -0
- package/dist/server/handlers/auth.js +66 -0
- package/dist/server/handlers/auth.js.map +1 -0
- package/dist/server/handlers/certification.d.ts +32 -0
- package/dist/server/handlers/certification.d.ts.map +1 -0
- package/dist/server/handlers/certification.js +253 -0
- package/dist/server/handlers/certification.js.map +1 -0
- package/dist/server/handlers/chat/conversations.d.ts +91 -0
- package/dist/server/handlers/chat/conversations.d.ts.map +1 -0
- package/dist/server/handlers/chat/conversations.js +314 -0
- package/dist/server/handlers/chat/conversations.js.map +1 -0
- package/dist/server/handlers/chat/delegator.d.ts +144 -0
- package/dist/server/handlers/chat/delegator.d.ts.map +1 -0
- package/dist/server/handlers/chat/delegator.js +431 -0
- package/dist/server/handlers/chat/delegator.js.map +1 -0
- package/dist/server/handlers/chat/engine.d.ts +81 -0
- package/dist/server/handlers/chat/engine.d.ts.map +1 -0
- package/dist/server/handlers/chat/engine.js +442 -0
- package/dist/server/handlers/chat/engine.js.map +1 -0
- package/dist/server/handlers/chat/executor.d.ts +65 -0
- package/dist/server/handlers/chat/executor.d.ts.map +1 -0
- package/dist/server/handlers/chat/executor.js +375 -0
- package/dist/server/handlers/chat/executor.js.map +1 -0
- package/dist/server/handlers/chat/index.d.ts +62 -0
- package/dist/server/handlers/chat/index.d.ts.map +1 -0
- package/dist/server/handlers/chat/index.js +182 -0
- package/dist/server/handlers/chat/index.js.map +1 -0
- package/dist/server/handlers/chat/memory.d.ts +91 -0
- package/dist/server/handlers/chat/memory.d.ts.map +1 -0
- package/dist/server/handlers/chat/memory.js +293 -0
- package/dist/server/handlers/chat/memory.js.map +1 -0
- package/dist/server/handlers/chat/models.d.ts +180 -0
- package/dist/server/handlers/chat/models.d.ts.map +1 -0
- package/dist/server/handlers/chat/models.js +304 -0
- package/dist/server/handlers/chat/models.js.map +1 -0
- package/dist/server/handlers/chat/planner.d.ts +116 -0
- package/dist/server/handlers/chat/planner.d.ts.map +1 -0
- package/dist/server/handlers/chat/planner.js +344 -0
- package/dist/server/handlers/chat/planner.js.map +1 -0
- package/dist/server/handlers/chat/types.d.ts +500 -0
- package/dist/server/handlers/chat/types.d.ts.map +1 -0
- package/dist/server/handlers/chat/types.js +11 -0
- package/dist/server/handlers/chat/types.js.map +1 -0
- package/dist/server/handlers/collections.d.ts +67 -0
- package/dist/server/handlers/collections.d.ts.map +1 -0
- package/dist/server/handlers/collections.js +484 -0
- package/dist/server/handlers/collections.js.map +1 -0
- package/dist/server/handlers/commerce.d.ts +106 -0
- package/dist/server/handlers/commerce.d.ts.map +1 -0
- package/dist/server/handlers/commerce.js +62 -0
- package/dist/server/handlers/commerce.js.map +1 -0
- package/dist/server/handlers/config.d.ts +112 -0
- package/dist/server/handlers/config.d.ts.map +1 -0
- package/dist/server/handlers/config.js +122 -0
- package/dist/server/handlers/config.js.map +1 -0
- package/dist/server/handlers/export.d.ts +72 -0
- package/dist/server/handlers/export.d.ts.map +1 -0
- package/dist/server/handlers/export.js +175 -0
- package/dist/server/handlers/export.js.map +1 -0
- package/dist/server/handlers/formats.d.ts +77 -0
- package/dist/server/handlers/formats.d.ts.map +1 -0
- package/dist/server/handlers/formats.js +65 -0
- package/dist/server/handlers/formats.js.map +1 -0
- package/dist/server/handlers/graph.d.ts +31 -0
- package/dist/server/handlers/graph.d.ts.map +1 -0
- package/dist/server/handlers/graph.js +490 -0
- package/dist/server/handlers/graph.js.map +1 -0
- package/dist/server/handlers/import.d.ts +96 -0
- package/dist/server/handlers/import.d.ts.map +1 -0
- package/dist/server/handlers/import.js +108 -0
- package/dist/server/handlers/import.js.map +1 -0
- package/dist/server/handlers/index.d.ts +68 -0
- package/dist/server/handlers/index.d.ts.map +1 -0
- package/dist/server/handlers/index.js +71 -0
- package/dist/server/handlers/index.js.map +1 -0
- package/dist/server/handlers/media.d.ts +76 -0
- package/dist/server/handlers/media.d.ts.map +1 -0
- package/dist/server/handlers/media.js +53 -0
- package/dist/server/handlers/media.js.map +1 -0
- package/dist/server/handlers/project.d.ts +45 -0
- package/dist/server/handlers/project.d.ts.map +1 -0
- package/dist/server/handlers/project.js +181 -0
- package/dist/server/handlers/project.js.map +1 -0
- package/dist/server/handlers/publish.d.ts +102 -0
- package/dist/server/handlers/publish.d.ts.map +1 -0
- package/dist/server/handlers/publish.js +130 -0
- package/dist/server/handlers/publish.js.map +1 -0
- package/dist/server/handlers/pulse.d.ts +39 -0
- package/dist/server/handlers/pulse.d.ts.map +1 -0
- package/dist/server/handlers/pulse.js +78 -0
- package/dist/server/handlers/pulse.js.map +1 -0
- package/dist/server/handlers/realtime.d.ts +55 -0
- package/dist/server/handlers/realtime.d.ts.map +1 -0
- package/dist/server/handlers/realtime.js +49 -0
- package/dist/server/handlers/realtime.js.map +1 -0
- package/dist/server/handlers/search.d.ts +21 -0
- package/dist/server/handlers/search.d.ts.map +1 -0
- package/dist/server/handlers/search.js +237 -0
- package/dist/server/handlers/search.js.map +1 -0
- package/dist/server/handlers/session.d.ts +47 -0
- package/dist/server/handlers/session.d.ts.map +1 -0
- package/dist/server/handlers/session.js +286 -0
- package/dist/server/handlers/session.js.map +1 -0
- package/dist/server/handlers/settings.d.ts +97 -0
- package/dist/server/handlers/settings.d.ts.map +1 -0
- package/dist/server/handlers/settings.js +131 -0
- package/dist/server/handlers/settings.js.map +1 -0
- package/dist/server/handlers/workspace.d.ts +78 -0
- package/dist/server/handlers/workspace.d.ts.map +1 -0
- package/dist/server/handlers/workspace.js +270 -0
- package/dist/server/handlers/workspace.js.map +1 -0
- package/dist/server/hono-router.d.ts +66 -0
- package/dist/server/hono-router.d.ts.map +1 -0
- package/dist/server/hono-router.js +203 -0
- package/dist/server/hono-router.js.map +1 -0
- package/dist/server/index.d.ts +29 -19
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +33 -19
- package/dist/server/index.js.map +1 -1
- package/dist/server/namespace-router.d.ts +204 -0
- package/dist/server/namespace-router.d.ts.map +1 -0
- package/dist/server/namespace-router.js +262 -0
- package/dist/server/namespace-router.js.map +1 -0
- package/dist/transports/http-namespace.d.ts +210 -0
- package/dist/transports/http-namespace.d.ts.map +1 -0
- package/dist/transports/http-namespace.js +514 -0
- package/dist/transports/http-namespace.js.map +1 -0
- package/dist/transports/workshop.d.ts +173 -0
- package/dist/transports/workshop.d.ts.map +1 -0
- package/dist/transports/workshop.js +307 -0
- package/dist/transports/workshop.js.map +1 -0
- package/dist/types.d.ts +65 -67
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +7 -3
- package/dist/types.js.map +1 -1
- package/docs/ADR-004-product-registry.md +108 -0
- package/package.json +1 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module modules/auth/products
|
|
3
|
+
* @description Centralized registry of all Soulcraft platform products and their
|
|
4
|
+
* auth configuration. This is the single source of truth for:
|
|
5
|
+
*
|
|
6
|
+
* - Which products exist on the platform
|
|
7
|
+
* - Their production domains and local dev ports
|
|
8
|
+
* - Their OIDC client IDs and redirect callback paths
|
|
9
|
+
* - Whether they require backchannel logout support
|
|
10
|
+
* - Which env var holds their OIDC client secret
|
|
11
|
+
*
|
|
12
|
+
* The auth server (`auth.soulcraft.com`) consumes this registry to derive all
|
|
13
|
+
* its registration arrays — trusted origins, CORS, OIDC trusted clients, and
|
|
14
|
+
* backchannel logout recipients — instead of maintaining five parallel hardcoded lists.
|
|
15
|
+
*
|
|
16
|
+
* ## Adding a new product
|
|
17
|
+
*
|
|
18
|
+
* 1. Add an entry to `SOULCRAFT_PRODUCTS` below (TypeScript enforces completeness).
|
|
19
|
+
* 2. Add `{PRODUCT}_OIDC_CLIENT_SECRET` (or equivalent) to the auth server's
|
|
20
|
+
* `.env.production`. Generate with: `openssl rand -hex 32`
|
|
21
|
+
* 3. Publish a new version of `@soulcraft/sdk`.
|
|
22
|
+
* 4. Deploy the auth server — it will pick up the new product automatically.
|
|
23
|
+
* 5. Set `SOULCRAFT_IDP_URL` in the product's own `.env.production`.
|
|
24
|
+
*
|
|
25
|
+
* @see ADR-002-product-registry.md for design rationale.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Full auth configuration for a single Soulcraft platform product.
|
|
29
|
+
*
|
|
30
|
+
* Consumed by the auth server to derive trusted origins, CORS origins, OIDC
|
|
31
|
+
* client registrations, and backchannel logout recipients.
|
|
32
|
+
*/
|
|
33
|
+
export interface ProductRegistration {
|
|
34
|
+
/** Human-readable display name, e.g. `"Soulcraft Workshop"`. */
|
|
35
|
+
name: string;
|
|
36
|
+
/**
|
|
37
|
+
* Production domain without scheme or trailing slash.
|
|
38
|
+
* e.g. `"workshop.soulcraft.com"`, `"soulcraft.com"`
|
|
39
|
+
*/
|
|
40
|
+
domain: string;
|
|
41
|
+
/** Local development port. Used to derive `http://localhost:{devPort}` origins. */
|
|
42
|
+
devPort: number;
|
|
43
|
+
/**
|
|
44
|
+
* OIDC client ID registered on the auth server.
|
|
45
|
+
* Must be unique across all products. e.g. `"workshop"`.
|
|
46
|
+
*/
|
|
47
|
+
clientId: string;
|
|
48
|
+
/**
|
|
49
|
+
* Name of the environment variable that holds this product's OIDC client secret
|
|
50
|
+
* (or backchannel secret for cookie-proxy products). e.g. `"WORKSHOP_OIDC_CLIENT_SECRET"`.
|
|
51
|
+
*/
|
|
52
|
+
secretEnvVar: string;
|
|
53
|
+
/**
|
|
54
|
+
* How this product authenticates users:
|
|
55
|
+
* - `'oidc-redirect'` — full OIDC authorization code flow with redirect callbacks
|
|
56
|
+
* - `'cookie-proxy'` — validates the shared `.soulcraft.com` session cookie directly
|
|
57
|
+
* against `GET /api/auth/get-session`; no OIDC redirect involved
|
|
58
|
+
*/
|
|
59
|
+
authMode: 'oidc-redirect' | 'cookie-proxy';
|
|
60
|
+
/**
|
|
61
|
+
* Paths on this product's origin that the auth server should register as OIDC
|
|
62
|
+
* redirect URIs. Empty array for cookie-proxy products. Both production and dev
|
|
63
|
+
* variants are derived automatically via `deriveRedirectUrls`.
|
|
64
|
+
*/
|
|
65
|
+
callbackPaths: string[];
|
|
66
|
+
/**
|
|
67
|
+
* Additional paths to include as OIDC redirect URIs beyond the callback paths.
|
|
68
|
+
* Typically the homepage (`"/"`) which is used as `post_logout_redirect_uri`.
|
|
69
|
+
* Defaults to `["/"]` when omitted.
|
|
70
|
+
*/
|
|
71
|
+
extraRedirectPaths?: string[];
|
|
72
|
+
/**
|
|
73
|
+
* When `true`, the auth server includes this product in its OIDC backchannel
|
|
74
|
+
* logout registry. The product's `{domain}/api/auth/backchannel-logout` endpoint
|
|
75
|
+
* will be notified on every sign-out so it can terminate local sessions immediately.
|
|
76
|
+
*
|
|
77
|
+
* Set to `false` only for products that do not implement a backchannel endpoint
|
|
78
|
+
* (e.g. read-only dashboards, analytics tools).
|
|
79
|
+
*/
|
|
80
|
+
backchannelRequired: boolean;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Central registry of all Soulcraft platform products.
|
|
84
|
+
*
|
|
85
|
+
* `as const satisfies Record<string, ProductRegistration>` provides two guarantees:
|
|
86
|
+
* - TypeScript enforces that every entry has all required `ProductRegistration` fields
|
|
87
|
+
* - Literal types are preserved so `keyof typeof SOULCRAFT_PRODUCTS` yields
|
|
88
|
+
* `'workshop' | 'venue' | 'portal' | 'academy' | 'pulse'` (not just `string`)
|
|
89
|
+
*
|
|
90
|
+
* Adding a product here automatically:
|
|
91
|
+
* - Extends the `SoulcraftProduct` union type
|
|
92
|
+
* - Includes the product in all auth server derivations (origins, CORS, OIDC clients)
|
|
93
|
+
*/
|
|
94
|
+
export declare const SOULCRAFT_PRODUCTS: {
|
|
95
|
+
readonly workshop: {
|
|
96
|
+
readonly name: "Soulcraft Workshop";
|
|
97
|
+
readonly domain: "workshop.soulcraft.com";
|
|
98
|
+
readonly devPort: 5001;
|
|
99
|
+
readonly clientId: "workshop";
|
|
100
|
+
readonly secretEnvVar: "WORKSHOP_OIDC_CLIENT_SECRET";
|
|
101
|
+
readonly authMode: "oidc-redirect";
|
|
102
|
+
readonly callbackPaths: ["/api/auth/oauth2/callback/soulcraft-idp", "/api/auth/callback/soulcraft-idp"];
|
|
103
|
+
readonly extraRedirectPaths: ["/"];
|
|
104
|
+
readonly backchannelRequired: true;
|
|
105
|
+
};
|
|
106
|
+
readonly venue: {
|
|
107
|
+
readonly name: "Soulcraft Venue";
|
|
108
|
+
readonly domain: "venue.soulcraft.com";
|
|
109
|
+
readonly devPort: 5174;
|
|
110
|
+
readonly clientId: "venue";
|
|
111
|
+
readonly secretEnvVar: "VENUE_OIDC_CLIENT_SECRET";
|
|
112
|
+
readonly authMode: "oidc-redirect";
|
|
113
|
+
readonly callbackPaths: ["/api/auth/callback/soulcraft-idp"];
|
|
114
|
+
readonly extraRedirectPaths: ["/"];
|
|
115
|
+
readonly backchannelRequired: true;
|
|
116
|
+
};
|
|
117
|
+
readonly portal: {
|
|
118
|
+
readonly name: "Soulcraft Portal";
|
|
119
|
+
readonly domain: "soulcraft.com";
|
|
120
|
+
readonly devPort: 8080;
|
|
121
|
+
readonly clientId: "portal";
|
|
122
|
+
readonly secretEnvVar: "PORTAL_OIDC_CLIENT_SECRET";
|
|
123
|
+
readonly authMode: "oidc-redirect";
|
|
124
|
+
readonly callbackPaths: ["/api/auth/callback/soulcraft-idp", "/auth/callback"];
|
|
125
|
+
readonly extraRedirectPaths: ["/"];
|
|
126
|
+
readonly backchannelRequired: true;
|
|
127
|
+
};
|
|
128
|
+
readonly academy: {
|
|
129
|
+
readonly name: "Soulcraft Academy";
|
|
130
|
+
readonly domain: "academy.soulcraft.com";
|
|
131
|
+
readonly devPort: 5002;
|
|
132
|
+
readonly clientId: "academy";
|
|
133
|
+
readonly secretEnvVar: "ACADEMY_OIDC_CLIENT_SECRET";
|
|
134
|
+
readonly authMode: "oidc-redirect";
|
|
135
|
+
readonly callbackPaths: ["/api/auth/callback/soulcraft-idp"];
|
|
136
|
+
readonly extraRedirectPaths: ["/"];
|
|
137
|
+
readonly backchannelRequired: true;
|
|
138
|
+
};
|
|
139
|
+
readonly pulse: {
|
|
140
|
+
readonly name: "Soulcraft Pulse";
|
|
141
|
+
readonly domain: "pulse.soulcraft.com";
|
|
142
|
+
readonly devPort: 5004;
|
|
143
|
+
readonly clientId: "pulse";
|
|
144
|
+
readonly secretEnvVar: "PULSE_BACKCHANNEL_SECRET";
|
|
145
|
+
readonly authMode: "cookie-proxy";
|
|
146
|
+
readonly callbackPaths: [];
|
|
147
|
+
readonly extraRedirectPaths: ["/"];
|
|
148
|
+
readonly backchannelRequired: false;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Union of all registered Soulcraft product keys.
|
|
153
|
+
*
|
|
154
|
+
* Automatically derived from `SOULCRAFT_PRODUCTS` — adding a product to the
|
|
155
|
+
* registry extends this type without any manual update.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* function validateProduct(p: string): p is SoulcraftProduct {
|
|
159
|
+
* return p in SOULCRAFT_PRODUCTS
|
|
160
|
+
* }
|
|
161
|
+
*/
|
|
162
|
+
export type SoulcraftProduct = keyof typeof SOULCRAFT_PRODUCTS;
|
|
163
|
+
/**
|
|
164
|
+
* Derive the full list of trusted origins for all registered products.
|
|
165
|
+
*
|
|
166
|
+
* Returns both the production HTTPS origin and the `http://localhost:{devPort}`
|
|
167
|
+
* development origin for every product in `SOULCRAFT_PRODUCTS`.
|
|
168
|
+
*
|
|
169
|
+
* Used by the auth server for:
|
|
170
|
+
* - `betterAuth({ trustedOrigins: deriveOrigins() })` — callback URL validation
|
|
171
|
+
* - `cors({ origin: deriveOrigins() })` — CORS preflight on the Hono layer
|
|
172
|
+
*
|
|
173
|
+
* @returns Deduplicated list of origin strings (scheme + host, no trailing slash).
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* deriveOrigins()
|
|
177
|
+
* // → [
|
|
178
|
+
* // 'https://workshop.soulcraft.com', 'http://localhost:5001',
|
|
179
|
+
* // 'https://venue.soulcraft.com', 'http://localhost:5174',
|
|
180
|
+
* // 'https://soulcraft.com', 'http://localhost:8080',
|
|
181
|
+
* // 'https://academy.soulcraft.com', 'http://localhost:5002',
|
|
182
|
+
* // 'https://pulse.soulcraft.com', 'http://localhost:5004',
|
|
183
|
+
* // ]
|
|
184
|
+
*/
|
|
185
|
+
export declare function deriveOrigins(): string[];
|
|
186
|
+
/**
|
|
187
|
+
* Derive all OIDC redirect URIs for a single product registration.
|
|
188
|
+
*
|
|
189
|
+
* Combines callback paths and extra redirect paths, generating both production
|
|
190
|
+
* and local development variants for each. Results are ordered: production paths
|
|
191
|
+
* first (all), then dev paths (all), matching the ordering in the auth server.
|
|
192
|
+
*
|
|
193
|
+
* @param p - A `ProductRegistration` from `SOULCRAFT_PRODUCTS`.
|
|
194
|
+
* @returns List of fully-qualified redirect URI strings.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* deriveRedirectUrls(SOULCRAFT_PRODUCTS.workshop)
|
|
198
|
+
* // → [
|
|
199
|
+
* // 'https://workshop.soulcraft.com/api/auth/oauth2/callback/soulcraft-idp',
|
|
200
|
+
* // 'https://workshop.soulcraft.com/api/auth/callback/soulcraft-idp',
|
|
201
|
+
* // 'https://workshop.soulcraft.com/',
|
|
202
|
+
* // 'http://localhost:5001/api/auth/oauth2/callback/soulcraft-idp',
|
|
203
|
+
* // 'http://localhost:5001/api/auth/callback/soulcraft-idp',
|
|
204
|
+
* // 'http://localhost:5001/',
|
|
205
|
+
* // ]
|
|
206
|
+
*/
|
|
207
|
+
export declare function deriveRedirectUrls(p: ProductRegistration): string[];
|
|
208
|
+
//# sourceMappingURL=products.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"products.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/products.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,QAAQ,EAAE,eAAe,GAAG,cAAc,CAAA;IAC1C;;;;OAIG;IACH,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B;;;;;;;OAOG;IACH,mBAAmB,EAAE,OAAO,CAAA;CAC7B;AAMD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+DyB,CAAA;AAExD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,kBAAkB,CAAA;AAM9D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAKxC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAQnE"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module modules/auth/products
|
|
3
|
+
* @description Centralized registry of all Soulcraft platform products and their
|
|
4
|
+
* auth configuration. This is the single source of truth for:
|
|
5
|
+
*
|
|
6
|
+
* - Which products exist on the platform
|
|
7
|
+
* - Their production domains and local dev ports
|
|
8
|
+
* - Their OIDC client IDs and redirect callback paths
|
|
9
|
+
* - Whether they require backchannel logout support
|
|
10
|
+
* - Which env var holds their OIDC client secret
|
|
11
|
+
*
|
|
12
|
+
* The auth server (`auth.soulcraft.com`) consumes this registry to derive all
|
|
13
|
+
* its registration arrays — trusted origins, CORS, OIDC trusted clients, and
|
|
14
|
+
* backchannel logout recipients — instead of maintaining five parallel hardcoded lists.
|
|
15
|
+
*
|
|
16
|
+
* ## Adding a new product
|
|
17
|
+
*
|
|
18
|
+
* 1. Add an entry to `SOULCRAFT_PRODUCTS` below (TypeScript enforces completeness).
|
|
19
|
+
* 2. Add `{PRODUCT}_OIDC_CLIENT_SECRET` (or equivalent) to the auth server's
|
|
20
|
+
* `.env.production`. Generate with: `openssl rand -hex 32`
|
|
21
|
+
* 3. Publish a new version of `@soulcraft/sdk`.
|
|
22
|
+
* 4. Deploy the auth server — it will pick up the new product automatically.
|
|
23
|
+
* 5. Set `SOULCRAFT_IDP_URL` in the product's own `.env.production`.
|
|
24
|
+
*
|
|
25
|
+
* @see ADR-002-product-registry.md for design rationale.
|
|
26
|
+
*/
|
|
27
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
28
|
+
// Registry
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Central registry of all Soulcraft platform products.
|
|
32
|
+
*
|
|
33
|
+
* `as const satisfies Record<string, ProductRegistration>` provides two guarantees:
|
|
34
|
+
* - TypeScript enforces that every entry has all required `ProductRegistration` fields
|
|
35
|
+
* - Literal types are preserved so `keyof typeof SOULCRAFT_PRODUCTS` yields
|
|
36
|
+
* `'workshop' | 'venue' | 'portal' | 'academy' | 'pulse'` (not just `string`)
|
|
37
|
+
*
|
|
38
|
+
* Adding a product here automatically:
|
|
39
|
+
* - Extends the `SoulcraftProduct` union type
|
|
40
|
+
* - Includes the product in all auth server derivations (origins, CORS, OIDC clients)
|
|
41
|
+
*/
|
|
42
|
+
export const SOULCRAFT_PRODUCTS = {
|
|
43
|
+
workshop: {
|
|
44
|
+
name: 'Soulcraft Workshop',
|
|
45
|
+
domain: 'workshop.soulcraft.com',
|
|
46
|
+
devPort: 5001,
|
|
47
|
+
clientId: 'workshop',
|
|
48
|
+
secretEnvVar: 'WORKSHOP_OIDC_CLIENT_SECRET',
|
|
49
|
+
authMode: 'oidc-redirect',
|
|
50
|
+
callbackPaths: [
|
|
51
|
+
'/api/auth/oauth2/callback/soulcraft-idp',
|
|
52
|
+
// Legacy path kept for in-flight sessions during transitions
|
|
53
|
+
'/api/auth/callback/soulcraft-idp',
|
|
54
|
+
],
|
|
55
|
+
extraRedirectPaths: ['/'],
|
|
56
|
+
backchannelRequired: true,
|
|
57
|
+
},
|
|
58
|
+
venue: {
|
|
59
|
+
name: 'Soulcraft Venue',
|
|
60
|
+
domain: 'venue.soulcraft.com',
|
|
61
|
+
devPort: 5174,
|
|
62
|
+
clientId: 'venue',
|
|
63
|
+
secretEnvVar: 'VENUE_OIDC_CLIENT_SECRET',
|
|
64
|
+
authMode: 'oidc-redirect',
|
|
65
|
+
callbackPaths: ['/api/auth/callback/soulcraft-idp'],
|
|
66
|
+
extraRedirectPaths: ['/'],
|
|
67
|
+
backchannelRequired: true,
|
|
68
|
+
},
|
|
69
|
+
portal: {
|
|
70
|
+
name: 'Soulcraft Portal',
|
|
71
|
+
domain: 'soulcraft.com',
|
|
72
|
+
devPort: 8080,
|
|
73
|
+
clientId: 'portal',
|
|
74
|
+
secretEnvVar: 'PORTAL_OIDC_CLIENT_SECRET',
|
|
75
|
+
authMode: 'oidc-redirect',
|
|
76
|
+
callbackPaths: ['/api/auth/callback/soulcraft-idp', '/auth/callback'],
|
|
77
|
+
extraRedirectPaths: ['/'],
|
|
78
|
+
backchannelRequired: true,
|
|
79
|
+
},
|
|
80
|
+
academy: {
|
|
81
|
+
name: 'Soulcraft Academy',
|
|
82
|
+
domain: 'academy.soulcraft.com',
|
|
83
|
+
devPort: 5002,
|
|
84
|
+
clientId: 'academy',
|
|
85
|
+
secretEnvVar: 'ACADEMY_OIDC_CLIENT_SECRET',
|
|
86
|
+
authMode: 'oidc-redirect',
|
|
87
|
+
callbackPaths: ['/api/auth/callback/soulcraft-idp'],
|
|
88
|
+
extraRedirectPaths: ['/'],
|
|
89
|
+
backchannelRequired: true,
|
|
90
|
+
},
|
|
91
|
+
pulse: {
|
|
92
|
+
name: 'Soulcraft Pulse',
|
|
93
|
+
domain: 'pulse.soulcraft.com',
|
|
94
|
+
devPort: 5004,
|
|
95
|
+
clientId: 'pulse',
|
|
96
|
+
// Pulse uses cookie-proxy; PULSE_BACKCHANNEL_SECRET doubles as the OIDC client
|
|
97
|
+
// secret for the minimal OIDC client entry that registers the homepage as a valid
|
|
98
|
+
// post_logout_redirect_uri. Backchannel is best-effort; no startup failure if absent.
|
|
99
|
+
secretEnvVar: 'PULSE_BACKCHANNEL_SECRET',
|
|
100
|
+
authMode: 'cookie-proxy',
|
|
101
|
+
callbackPaths: [],
|
|
102
|
+
extraRedirectPaths: ['/'],
|
|
103
|
+
backchannelRequired: false,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
107
|
+
// Derivation helpers
|
|
108
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
109
|
+
/**
|
|
110
|
+
* Derive the full list of trusted origins for all registered products.
|
|
111
|
+
*
|
|
112
|
+
* Returns both the production HTTPS origin and the `http://localhost:{devPort}`
|
|
113
|
+
* development origin for every product in `SOULCRAFT_PRODUCTS`.
|
|
114
|
+
*
|
|
115
|
+
* Used by the auth server for:
|
|
116
|
+
* - `betterAuth({ trustedOrigins: deriveOrigins() })` — callback URL validation
|
|
117
|
+
* - `cors({ origin: deriveOrigins() })` — CORS preflight on the Hono layer
|
|
118
|
+
*
|
|
119
|
+
* @returns Deduplicated list of origin strings (scheme + host, no trailing slash).
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* deriveOrigins()
|
|
123
|
+
* // → [
|
|
124
|
+
* // 'https://workshop.soulcraft.com', 'http://localhost:5001',
|
|
125
|
+
* // 'https://venue.soulcraft.com', 'http://localhost:5174',
|
|
126
|
+
* // 'https://soulcraft.com', 'http://localhost:8080',
|
|
127
|
+
* // 'https://academy.soulcraft.com', 'http://localhost:5002',
|
|
128
|
+
* // 'https://pulse.soulcraft.com', 'http://localhost:5004',
|
|
129
|
+
* // ]
|
|
130
|
+
*/
|
|
131
|
+
export function deriveOrigins() {
|
|
132
|
+
return Object.values(SOULCRAFT_PRODUCTS).flatMap((p) => [
|
|
133
|
+
`https://${p.domain}`,
|
|
134
|
+
`http://localhost:${p.devPort}`,
|
|
135
|
+
]);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Derive all OIDC redirect URIs for a single product registration.
|
|
139
|
+
*
|
|
140
|
+
* Combines callback paths and extra redirect paths, generating both production
|
|
141
|
+
* and local development variants for each. Results are ordered: production paths
|
|
142
|
+
* first (all), then dev paths (all), matching the ordering in the auth server.
|
|
143
|
+
*
|
|
144
|
+
* @param p - A `ProductRegistration` from `SOULCRAFT_PRODUCTS`.
|
|
145
|
+
* @returns List of fully-qualified redirect URI strings.
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* deriveRedirectUrls(SOULCRAFT_PRODUCTS.workshop)
|
|
149
|
+
* // → [
|
|
150
|
+
* // 'https://workshop.soulcraft.com/api/auth/oauth2/callback/soulcraft-idp',
|
|
151
|
+
* // 'https://workshop.soulcraft.com/api/auth/callback/soulcraft-idp',
|
|
152
|
+
* // 'https://workshop.soulcraft.com/',
|
|
153
|
+
* // 'http://localhost:5001/api/auth/oauth2/callback/soulcraft-idp',
|
|
154
|
+
* // 'http://localhost:5001/api/auth/callback/soulcraft-idp',
|
|
155
|
+
* // 'http://localhost:5001/',
|
|
156
|
+
* // ]
|
|
157
|
+
*/
|
|
158
|
+
export function deriveRedirectUrls(p) {
|
|
159
|
+
const extraPaths = p.extraRedirectPaths ?? ['/'];
|
|
160
|
+
const allPaths = [...p.callbackPaths, ...extraPaths];
|
|
161
|
+
const prod = allPaths.map((path) => `https://${p.domain}${path}`);
|
|
162
|
+
const dev = allPaths.map((path) => `http://localhost:${p.devPort}${path}`);
|
|
163
|
+
return [...prod, ...dev];
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=products.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"products.js","sourceRoot":"","sources":["../../../src/modules/auth/products.ts"],"names":[],"mappings":"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"}
|