@betterportal/framework 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +13 -0
  2. package/lib/adapters/h3.d.ts +51 -0
  3. package/lib/adapters/h3.d.ts.map +1 -0
  4. package/lib/adapters/h3.js +1120 -0
  5. package/lib/adapters/h3.js.map +1 -0
  6. package/lib/codegen/cli.d.ts +3 -0
  7. package/lib/codegen/cli.d.ts.map +1 -0
  8. package/lib/codegen/cli.js +82 -0
  9. package/lib/codegen/cli.js.map +1 -0
  10. package/lib/codegen/emitter.d.ts +7 -0
  11. package/lib/codegen/emitter.d.ts.map +1 -0
  12. package/lib/codegen/emitter.js +453 -0
  13. package/lib/codegen/emitter.js.map +1 -0
  14. package/lib/codegen/init.d.ts +3 -0
  15. package/lib/codegen/init.d.ts.map +1 -0
  16. package/lib/codegen/init.js +90 -0
  17. package/lib/codegen/init.js.map +1 -0
  18. package/lib/codegen/scanner.d.ts +56 -0
  19. package/lib/codegen/scanner.d.ts.map +1 -0
  20. package/lib/codegen/scanner.js +484 -0
  21. package/lib/codegen/scanner.js.map +1 -0
  22. package/lib/codegen/validate.d.ts +14 -0
  23. package/lib/codegen/validate.d.ts.map +1 -0
  24. package/lib/codegen/validate.js +166 -0
  25. package/lib/codegen/validate.js.map +1 -0
  26. package/lib/contracts/auth.d.ts +160 -0
  27. package/lib/contracts/auth.d.ts.map +1 -0
  28. package/lib/contracts/auth.js +123 -0
  29. package/lib/contracts/auth.js.map +1 -0
  30. package/lib/contracts/binding.d.ts +169 -0
  31. package/lib/contracts/binding.d.ts.map +1 -0
  32. package/lib/contracts/binding.js +69 -0
  33. package/lib/contracts/binding.js.map +1 -0
  34. package/lib/contracts/common.d.ts +23 -0
  35. package/lib/contracts/common.d.ts.map +1 -0
  36. package/lib/contracts/common.js +18 -0
  37. package/lib/contracts/common.js.map +1 -0
  38. package/lib/contracts/config.d.ts +93 -0
  39. package/lib/contracts/config.d.ts.map +1 -0
  40. package/lib/contracts/config.js +62 -0
  41. package/lib/contracts/config.js.map +1 -0
  42. package/lib/contracts/controlPlane.d.ts +63 -0
  43. package/lib/contracts/controlPlane.d.ts.map +1 -0
  44. package/lib/contracts/controlPlane.js +2 -0
  45. package/lib/contracts/controlPlane.js.map +1 -0
  46. package/lib/contracts/json.d.ts +9 -0
  47. package/lib/contracts/json.d.ts.map +1 -0
  48. package/lib/contracts/json.js +6 -0
  49. package/lib/contracts/json.js.map +1 -0
  50. package/lib/contracts/manifest.d.ts +158 -0
  51. package/lib/contracts/manifest.d.ts.map +1 -0
  52. package/lib/contracts/manifest.js +40 -0
  53. package/lib/contracts/manifest.js.map +1 -0
  54. package/lib/contracts/observability.d.ts +77 -0
  55. package/lib/contracts/observability.d.ts.map +1 -0
  56. package/lib/contracts/observability.js +99 -0
  57. package/lib/contracts/observability.js.map +1 -0
  58. package/lib/contracts/platformConfig.d.ts +635 -0
  59. package/lib/contracts/platformConfig.d.ts.map +1 -0
  60. package/lib/contracts/platformConfig.js +256 -0
  61. package/lib/contracts/platformConfig.js.map +1 -0
  62. package/lib/contracts/registry.d.ts +104 -0
  63. package/lib/contracts/registry.d.ts.map +1 -0
  64. package/lib/contracts/registry.js +2 -0
  65. package/lib/contracts/registry.js.map +1 -0
  66. package/lib/contracts/route.d.ts +199 -0
  67. package/lib/contracts/route.d.ts.map +1 -0
  68. package/lib/contracts/route.js +26 -0
  69. package/lib/contracts/route.js.map +1 -0
  70. package/lib/contracts/serviceConfig.d.ts +88 -0
  71. package/lib/contracts/serviceConfig.d.ts.map +1 -0
  72. package/lib/contracts/serviceConfig.js +45 -0
  73. package/lib/contracts/serviceConfig.js.map +1 -0
  74. package/lib/contracts/streaming.d.ts +76 -0
  75. package/lib/contracts/streaming.d.ts.map +1 -0
  76. package/lib/contracts/streaming.js +31 -0
  77. package/lib/contracts/streaming.js.map +1 -0
  78. package/lib/contracts/view.d.ts +149 -0
  79. package/lib/contracts/view.d.ts.map +1 -0
  80. package/lib/contracts/view.js +82 -0
  81. package/lib/contracts/view.js.map +1 -0
  82. package/lib/controlPlane/store.d.ts +24 -0
  83. package/lib/controlPlane/store.d.ts.map +1 -0
  84. package/lib/controlPlane/store.js +70 -0
  85. package/lib/controlPlane/store.js.map +1 -0
  86. package/lib/controlPlane/sync.d.ts +8 -0
  87. package/lib/controlPlane/sync.d.ts.map +1 -0
  88. package/lib/controlPlane/sync.js +24 -0
  89. package/lib/controlPlane/sync.js.map +1 -0
  90. package/lib/controlPlane/types.d.ts +15 -0
  91. package/lib/controlPlane/types.d.ts.map +1 -0
  92. package/lib/controlPlane/types.js +2 -0
  93. package/lib/controlPlane/types.js.map +1 -0
  94. package/lib/index.d.ts +40 -0
  95. package/lib/index.d.ts.map +1 -0
  96. package/lib/index.js +40 -0
  97. package/lib/index.js.map +1 -0
  98. package/lib/runtime/auth/envelope.d.ts +32 -0
  99. package/lib/runtime/auth/envelope.d.ts.map +1 -0
  100. package/lib/runtime/auth/envelope.js +123 -0
  101. package/lib/runtime/auth/envelope.js.map +1 -0
  102. package/lib/runtime/auth/issuer.d.ts +44 -0
  103. package/lib/runtime/auth/issuer.d.ts.map +1 -0
  104. package/lib/runtime/auth/issuer.js +82 -0
  105. package/lib/runtime/auth/issuer.js.map +1 -0
  106. package/lib/runtime/auth/jwks.d.ts +7 -0
  107. package/lib/runtime/auth/jwks.d.ts.map +1 -0
  108. package/lib/runtime/auth/jwks.js +69 -0
  109. package/lib/runtime/auth/jwks.js.map +1 -0
  110. package/lib/runtime/auth/keypair.d.ts +21 -0
  111. package/lib/runtime/auth/keypair.d.ts.map +1 -0
  112. package/lib/runtime/auth/keypair.js +50 -0
  113. package/lib/runtime/auth/keypair.js.map +1 -0
  114. package/lib/runtime/auth/tokens.d.ts +25 -0
  115. package/lib/runtime/auth/tokens.d.ts.map +1 -0
  116. package/lib/runtime/auth/tokens.js +137 -0
  117. package/lib/runtime/auth/tokens.js.map +1 -0
  118. package/lib/runtime/auth/verifier.d.ts +45 -0
  119. package/lib/runtime/auth/verifier.d.ts.map +1 -0
  120. package/lib/runtime/auth/verifier.js +76 -0
  121. package/lib/runtime/auth/verifier.js.map +1 -0
  122. package/lib/runtime/bpHeaders.d.ts +10 -0
  123. package/lib/runtime/bpHeaders.d.ts.map +1 -0
  124. package/lib/runtime/bpHeaders.js +53 -0
  125. package/lib/runtime/bpHeaders.js.map +1 -0
  126. package/lib/runtime/configProvider.d.ts +41 -0
  127. package/lib/runtime/configProvider.d.ts.map +1 -0
  128. package/lib/runtime/configProvider.js +232 -0
  129. package/lib/runtime/configProvider.js.map +1 -0
  130. package/lib/runtime/configStore.d.ts +34 -0
  131. package/lib/runtime/configStore.d.ts.map +1 -0
  132. package/lib/runtime/configStore.js +197 -0
  133. package/lib/runtime/configStore.js.map +1 -0
  134. package/lib/runtime/configTicket.d.ts +49 -0
  135. package/lib/runtime/configTicket.d.ts.map +1 -0
  136. package/lib/runtime/configTicket.js +168 -0
  137. package/lib/runtime/configTicket.js.map +1 -0
  138. package/lib/runtime/h3.d.ts +28 -0
  139. package/lib/runtime/h3.d.ts.map +1 -0
  140. package/lib/runtime/h3.js +199 -0
  141. package/lib/runtime/h3.js.map +1 -0
  142. package/lib/runtime/handler.d.ts +55 -0
  143. package/lib/runtime/handler.d.ts.map +1 -0
  144. package/lib/runtime/handler.js +51 -0
  145. package/lib/runtime/handler.js.map +1 -0
  146. package/lib/runtime/http.d.ts +13 -0
  147. package/lib/runtime/http.d.ts.map +1 -0
  148. package/lib/runtime/http.js +114 -0
  149. package/lib/runtime/http.js.map +1 -0
  150. package/lib/runtime/jsonSchema.d.ts +4 -0
  151. package/lib/runtime/jsonSchema.d.ts.map +1 -0
  152. package/lib/runtime/jsonSchema.js +28 -0
  153. package/lib/runtime/jsonSchema.js.map +1 -0
  154. package/lib/runtime/manifest.d.ts +3 -0
  155. package/lib/runtime/manifest.d.ts.map +1 -0
  156. package/lib/runtime/manifest.js +5 -0
  157. package/lib/runtime/manifest.js.map +1 -0
  158. package/lib/runtime/media.d.ts +20 -0
  159. package/lib/runtime/media.d.ts.map +1 -0
  160. package/lib/runtime/media.js +70 -0
  161. package/lib/runtime/media.js.map +1 -0
  162. package/lib/runtime/registry.d.ts +67 -0
  163. package/lib/runtime/registry.d.ts.map +1 -0
  164. package/lib/runtime/registry.js +290 -0
  165. package/lib/runtime/registry.js.map +1 -0
  166. package/lib/runtime/serviceConfig.d.ts +38 -0
  167. package/lib/runtime/serviceConfig.d.ts.map +1 -0
  168. package/lib/runtime/serviceConfig.js +152 -0
  169. package/lib/runtime/serviceConfig.js.map +1 -0
  170. package/lib/runtime/statusViews.d.ts +23 -0
  171. package/lib/runtime/statusViews.d.ts.map +1 -0
  172. package/lib/runtime/statusViews.js +48 -0
  173. package/lib/runtime/statusViews.js.map +1 -0
  174. package/lib/runtime/stream.d.ts +41 -0
  175. package/lib/runtime/stream.d.ts.map +1 -0
  176. package/lib/runtime/stream.js +92 -0
  177. package/lib/runtime/stream.js.map +1 -0
  178. package/lib/runtime/streamHandler.d.ts +48 -0
  179. package/lib/runtime/streamHandler.d.ts.map +1 -0
  180. package/lib/runtime/streamHandler.js +49 -0
  181. package/lib/runtime/streamHandler.js.map +1 -0
  182. package/lib/runtime/tenantResolution.d.ts +4 -0
  183. package/lib/runtime/tenantResolution.d.ts.map +1 -0
  184. package/lib/runtime/tenantResolution.js +19 -0
  185. package/lib/runtime/tenantResolution.js.map +1 -0
  186. package/lib/runtime/uuid.d.ts +6 -0
  187. package/lib/runtime/uuid.d.ts.map +1 -0
  188. package/lib/runtime/uuid.js +27 -0
  189. package/lib/runtime/uuid.js.map +1 -0
  190. package/lib/runtime/view.d.ts +48 -0
  191. package/lib/runtime/view.d.ts.map +1 -0
  192. package/lib/runtime/view.js +111 -0
  193. package/lib/runtime/view.js.map +1 -0
  194. package/package.json +56 -0
@@ -0,0 +1,232 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { resolve as resolvePath } from "node:path";
3
+ import { parse } from "yaml";
4
+ import { BetterPortalConfigSchema, BetterPortalOriginPolicySchema } from "../contracts/platformConfig.js";
5
+ import { hostFromHeaderValue, resolveEmbeddedSourceHeader, resolveThemeSourceHeader } from "./http.js";
6
+ const EMPTY_CONFIG = BetterPortalConfigSchema.parse({
7
+ configManagement: { auth: { mechanism: "none", requiredPermissions: [] } }
8
+ });
9
+ export class FileBackedBetterPortalConfigProvider {
10
+ configPath;
11
+ constructor(configPath) {
12
+ this.configPath = configPath;
13
+ }
14
+ async loadConfig() {
15
+ const resolvedConfigPath = resolvePath(this.configPath);
16
+ try {
17
+ const fileContent = await readFile(resolvedConfigPath, "utf8");
18
+ const parsed = parse(fileContent);
19
+ return BetterPortalConfigSchema.parse(parsed);
20
+ }
21
+ catch (err) {
22
+ // Pre-bootstrap: file may not exist yet. Return empty config so the caller
23
+ // can decide how to handle (typically returns 503 or empty UI).
24
+ if (err.code === "ENOENT") {
25
+ return EMPTY_CONFIG;
26
+ }
27
+ throw err;
28
+ }
29
+ }
30
+ }
31
+ export function createBetterPortalConfigProvider(options) {
32
+ return new FileBackedBetterPortalConfigProvider(options.configPath);
33
+ }
34
+ function hostFromUrlValue(value) {
35
+ return hostFromHeaderValue(value);
36
+ }
37
+ function hostFromHostHeader(host) {
38
+ return hostFromHeaderValue(host);
39
+ }
40
+ function findAppByHost(config, requestHost) {
41
+ if (!requestHost) {
42
+ return null;
43
+ }
44
+ return config.apps.find((app) => app.hostnames.some((appHostname) => {
45
+ const appHost = hostFromHostHeader(appHostname);
46
+ if (!appHost) {
47
+ return false;
48
+ }
49
+ if (appHost === requestHost) {
50
+ return true;
51
+ }
52
+ return appHost.split(":")[0] === requestHost.split(":")[0];
53
+ })) ?? null;
54
+ }
55
+ export function describeEmbeddedContextResolution(config, headers, headerTrust = {}) {
56
+ const refererHost = hostFromUrlValue(resolveEmbeddedSourceHeader(headers, headerTrust));
57
+ const originHost = hostFromUrlValue(resolveThemeSourceHeader(headers, headerTrust));
58
+ const candidates = [...new Set([refererHost, originHost].filter((value) => !!value))];
59
+ return {
60
+ candidates,
61
+ appHosts: config.apps.map((app) => ({
62
+ appId: app.id,
63
+ hosts: app.hostnames
64
+ .map((hostname) => hostFromHostHeader(hostname))
65
+ .filter((value) => !!value)
66
+ }))
67
+ };
68
+ }
69
+ function buildResolvedContext(config, appId) {
70
+ if (!appId) {
71
+ return null;
72
+ }
73
+ const app = config.apps.find((entry) => entry.id === appId) ?? null;
74
+ if (!app) {
75
+ return null;
76
+ }
77
+ const tenant = config.tenants.find((entry) => entry.id === app.tenantId) ?? null;
78
+ if (!tenant || !tenant.active) {
79
+ return null;
80
+ }
81
+ return { tenant, app };
82
+ }
83
+ export function resolveThemeRequestContext(config, headers, requestHost, headerTrust = {}) {
84
+ const originHostname = hostFromUrlValue(resolveThemeSourceHeader(headers, headerTrust));
85
+ const refererHostname = hostFromUrlValue(resolveEmbeddedSourceHeader(headers, headerTrust));
86
+ const hostHostname = hostFromHostHeader(requestHost);
87
+ const app = findAppByHost(config, hostHostname) ??
88
+ findAppByHost(config, originHostname) ??
89
+ findAppByHost(config, refererHostname);
90
+ return buildResolvedContext(config, app?.id ?? null);
91
+ }
92
+ export function resolveEmbeddedRequestContext(config, headers, headerTrust = {}) {
93
+ const refererHostname = hostFromUrlValue(resolveEmbeddedSourceHeader(headers, headerTrust));
94
+ const originHostname = hostFromUrlValue(resolveThemeSourceHeader(headers, headerTrust));
95
+ const app = findAppByHost(config, refererHostname) ??
96
+ findAppByHost(config, originHostname);
97
+ return buildResolvedContext(config, app?.id ?? null);
98
+ }
99
+ export function resolveServiceForTenant(config, serviceId, context) {
100
+ const tenantService = context.tenant.services.find((s) => s.enabled && (s.id === serviceId || s.serviceId === serviceId));
101
+ if (tenantService) {
102
+ return { tenant: context.tenant, app: context.app, service: tenantService };
103
+ }
104
+ if (context.tenant.activatedPlatformServices.includes(serviceId)) {
105
+ const platformService = config.platformServices.find((ps) => ps.enabled && (ps.id === serviceId || ps.serviceId === serviceId));
106
+ if (platformService) {
107
+ return {
108
+ tenant: context.tenant,
109
+ app: context.app,
110
+ service: {
111
+ id: platformService.id,
112
+ hostname: platformService.hostname,
113
+ apiKeyHash: platformService.apiKeyHash,
114
+ serviceId: platformService.serviceId,
115
+ capabilities: platformService.capabilities,
116
+ title: platformService.title,
117
+ description: platformService.description,
118
+ deploymentMode: "bp-hosted",
119
+ createdAt: platformService.createdAt,
120
+ enabled: true
121
+ }
122
+ };
123
+ }
124
+ }
125
+ return null;
126
+ }
127
+ function ensureAllowedOrigins(app) {
128
+ const generated = app.hostnames.flatMap((hostname) => {
129
+ if (hostname.startsWith("http://") || hostname.startsWith("https://")) {
130
+ return [hostname];
131
+ }
132
+ return [
133
+ `https://${hostname}`,
134
+ `http://${hostname}`
135
+ ];
136
+ });
137
+ return [...new Set([...generated, ...app.originOverrides])];
138
+ }
139
+ export function buildOriginPolicy(context) {
140
+ return BetterPortalOriginPolicySchema.parse({
141
+ allowedOrigins: ensureAllowedOrigins(context.app),
142
+ allowedReferers: [...new Set([
143
+ ...ensureAllowedOrigins(context.app),
144
+ ...context.app.refererOverrides
145
+ ])]
146
+ });
147
+ }
148
+ export function isAllowedOriginForContext(context, origin) {
149
+ if (!origin) {
150
+ return false;
151
+ }
152
+ return buildOriginPolicy(context).allowedOrigins.includes(origin);
153
+ }
154
+ export function isAllowedRefererForContext(context, referer) {
155
+ if (!referer) {
156
+ return false;
157
+ }
158
+ return buildOriginPolicy(context).allowedReferers.includes(referer);
159
+ }
160
+ export function serviceBaseUrl(service) {
161
+ const url = "hostname" in service ? service.hostname : service.endpointBaseUrl;
162
+ return url.replace(/\/+$/, "");
163
+ }
164
+ function splitRoutePath(pathname) {
165
+ return pathname.replace(/^\/+|\/+$/g, "").split("/").filter((segment) => segment.length > 0);
166
+ }
167
+ function routeParamName(segment) {
168
+ if (segment.startsWith(":") && segment.length > 1) {
169
+ return segment.slice(1);
170
+ }
171
+ const braceMatch = segment.match(/^\{([A-Za-z_][A-Za-z0-9_]*)\}$/);
172
+ return braceMatch?.[1] ?? null;
173
+ }
174
+ function routePatternMatches(routePath, pathname) {
175
+ if (routePath === pathname) {
176
+ return true;
177
+ }
178
+ const routeSegments = splitRoutePath(routePath);
179
+ const pathSegments = splitRoutePath(pathname);
180
+ if (routeSegments.length !== pathSegments.length) {
181
+ return false;
182
+ }
183
+ return routeSegments.every((segment, index) => routeParamName(segment) !== null || segment === pathSegments[index]);
184
+ }
185
+ export function resolveAppRoute(app, pathname) {
186
+ const normalizedPath = pathname.trim().length > 0 ? pathname : "/";
187
+ return app.routes.find((route) => route.enabled && routePatternMatches(route.path, normalizedPath)) ?? null;
188
+ }
189
+ export function inferServicePathFromViewId(viewId) {
190
+ const normalized = viewId.replace(/\.index$/, "").replace(/\./g, "/");
191
+ return normalized.startsWith("/") ? normalized : `/${normalized}`;
192
+ }
193
+ function extractRouteParams(routePath, currentPath) {
194
+ const routeSegments = splitRoutePath(routePath);
195
+ const currentSegments = splitRoutePath(currentPath);
196
+ if (routeSegments.length !== currentSegments.length) {
197
+ return null;
198
+ }
199
+ const params = {};
200
+ for (let i = 0; i < routeSegments.length; i++) {
201
+ const paramName = routeParamName(routeSegments[i]);
202
+ if (paramName) {
203
+ params[paramName] = currentSegments[i];
204
+ }
205
+ else if (routeSegments[i] !== currentSegments[i]) {
206
+ return null;
207
+ }
208
+ }
209
+ return params;
210
+ }
211
+ function interpolatePath(pathTemplate, params) {
212
+ const [pathPart, queryPart] = pathTemplate.split("?", 2);
213
+ const resolvedSegments = splitRoutePath(pathPart).map((segment) => {
214
+ const paramName = routeParamName(segment);
215
+ return paramName ? (params[paramName] ?? segment) : segment;
216
+ });
217
+ const resolvedPath = resolvedSegments.length === 0 ? "/" : `/${resolvedSegments.join("/")}`;
218
+ const resolvedQuery = queryPart?.replace(/(?::([A-Za-z_][A-Za-z0-9_]*)|\{([A-Za-z_][A-Za-z0-9_]*)\})/g, (match, colonName, braceName) => params[colonName ?? braceName ?? ""] ?? match);
219
+ return resolvedQuery ? `${resolvedPath}?${resolvedQuery}` : resolvedPath;
220
+ }
221
+ export function buildServiceViewUrl(binding, route, currentPath) {
222
+ const baseUrl = serviceBaseUrl(binding);
223
+ const params = extractRouteParams(route.path, currentPath) ?? {};
224
+ const servicePath = route.resolvedServicePath ?? route.targetPath;
225
+ const resolvedPath = servicePath
226
+ ? interpolatePath(servicePath, params)
227
+ : Object.keys(params).length > 0
228
+ ? interpolatePath(route.path, params)
229
+ : inferServicePathFromViewId(route.viewId);
230
+ return `${baseUrl}${resolvedPath}`;
231
+ }
232
+ //# sourceMappingURL=configProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configProvider.js","sourceRoot":"","sources":["../../src/runtime/configProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { ConfigSchemaDescriptor } from "../contracts/config.js";
2
+ import type { ServiceConfigState, ServiceConfigTicketClaims } from "../contracts/serviceConfig.js";
3
+ export interface ServiceConfigStore {
4
+ read(ticket: ServiceConfigTicketClaims): ServiceConfigState;
5
+ write(tenantId: string, appId: string | undefined, values: Record<string, unknown>, ticket: ServiceConfigTicketClaims): ServiceConfigState;
6
+ clearKey?(tenantId: string, appId: string | undefined, key: string, ticket: ServiceConfigTicketClaims): ServiceConfigState;
7
+ }
8
+ export declare class InMemoryServiceConfigStore implements ServiceConfigStore {
9
+ private state;
10
+ read(ticket: ServiceConfigTicketClaims): ServiceConfigState;
11
+ write(tenantId: string, appId: string | undefined, values: Record<string, unknown>, ticket: ServiceConfigTicketClaims): ServiceConfigState;
12
+ clearKey(tenantId: string, appId: string | undefined, key: string, ticket: ServiceConfigTicketClaims): ServiceConfigState;
13
+ }
14
+ export interface FileBackedServiceConfigStoreOptions {
15
+ filePath: string;
16
+ configSchemas: ConfigSchemaDescriptor[];
17
+ encryptionKey: string;
18
+ }
19
+ export declare class FileBackedServiceConfigStore implements ServiceConfigStore {
20
+ private state;
21
+ private readonly key;
22
+ private readonly secretKeys;
23
+ private readonly filePath;
24
+ constructor(options: FileBackedServiceConfigStoreOptions);
25
+ read(ticket: ServiceConfigTicketClaims): ServiceConfigState;
26
+ write(tenantId: string, appId: string | undefined, values: Record<string, unknown>, ticket: ServiceConfigTicketClaims): ServiceConfigState;
27
+ clearKey(tenantId: string, appId: string | undefined, key: string, ticket: ServiceConfigTicketClaims): ServiceConfigState;
28
+ private readBucket;
29
+ private ensureTenantBucket;
30
+ private decryptRecord;
31
+ private loadFromDisk;
32
+ private saveToDisk;
33
+ }
34
+ //# sourceMappingURL=configStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configStore.d.ts","sourceRoot":"","sources":["../../src/runtime/configStore.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAErE,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAyBnG,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,MAAM,EAAE,yBAAyB,GAAG,kBAAkB,CAAC;IAC5D,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,yBAAyB,GAChC,kBAAkB,CAAC;IACtB,QAAQ,CAAC,CACP,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,yBAAyB,GAChC,kBAAkB,CAAC;CACvB;AAID,qBAAa,0BAA2B,YAAW,kBAAkB;IACnE,OAAO,CAAC,KAAK,CAAgD;IAE7D,IAAI,CAAC,MAAM,EAAE,yBAAyB,GAAG,kBAAkB;IAI3D,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,yBAAyB,GAChC,kBAAkB;IAmBrB,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,yBAAyB,GAChC,kBAAkB;CAkBtB;AAyED,MAAM,WAAW,mCAAmC;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,sBAAsB,EAAE,CAAC;IACxC,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,4BAA6B,YAAW,kBAAkB;IACrE,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,OAAO,EAAE,mCAAmC;IAOxD,IAAI,CAAC,MAAM,EAAE,yBAAyB,GAAG,kBAAkB;IAI3D,KAAK,CACH,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,yBAAyB,GAChC,kBAAkB;IAsBrB,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,yBAAyB,GAChC,kBAAkB;IAqBrB,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,UAAU;CAOnB"}
@@ -0,0 +1,197 @@
1
+ import * as av from "anyvali";
2
+ import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "node:crypto";
3
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
4
+ import { dirname } from "node:path";
5
+ const ValuesSchema = av.record(av.any());
6
+ function emptyBucket() {
7
+ return { tenant: {}, app: {} };
8
+ }
9
+ function cloneBucket(bucket) {
10
+ return {
11
+ tenant: { ...(bucket?.tenant ?? {}) },
12
+ app: Object.fromEntries(Object.entries(bucket?.app ?? {}).map(([appId, values]) => [appId, { ...values }]))
13
+ };
14
+ }
15
+ // -- In-memory (dev) --------------------------------------------------
16
+ export class InMemoryServiceConfigStore {
17
+ state = { tenants: {} };
18
+ read(ticket) {
19
+ return cloneBucket(this.state.tenants[ticket.tenantId]);
20
+ }
21
+ write(tenantId, appId, values, ticket) {
22
+ const parsed = ValuesSchema.parse(values);
23
+ if (tenantId !== ticket.tenantId) {
24
+ return this.read(ticket);
25
+ }
26
+ const current = this.state.tenants[tenantId] ?? emptyBucket();
27
+ if (appId) {
28
+ this.state.tenants[tenantId] = {
29
+ tenant: current.tenant,
30
+ app: { ...current.app, [appId]: { ...(current.app[appId] ?? {}), ...parsed } }
31
+ };
32
+ }
33
+ else {
34
+ this.state.tenants[tenantId] = { tenant: { ...current.tenant, ...parsed }, app: current.app };
35
+ }
36
+ return this.read(ticket);
37
+ }
38
+ clearKey(tenantId, appId, key, ticket) {
39
+ if (tenantId !== ticket.tenantId)
40
+ return this.read(ticket);
41
+ const current = this.state.tenants[tenantId] ?? emptyBucket();
42
+ if (appId) {
43
+ const appValues = { ...(current.app[appId] ?? {}) };
44
+ delete appValues[key];
45
+ this.state.tenants[tenantId] = {
46
+ tenant: current.tenant,
47
+ app: { ...current.app, [appId]: appValues }
48
+ };
49
+ }
50
+ else {
51
+ const tenantValues = { ...current.tenant };
52
+ delete tenantValues[key];
53
+ this.state.tenants[tenantId] = { tenant: tenantValues, app: current.app };
54
+ }
55
+ return this.read(ticket);
56
+ }
57
+ }
58
+ // -- Encryption helpers -----------------------------------------------
59
+ const ALGORITHM = "aes-256-gcm";
60
+ const IV_LENGTH = 16;
61
+ const AUTH_TAG_LENGTH = 16;
62
+ const ENCRYPTED_PREFIX = "enc:aes256gcm:";
63
+ function deriveKey(secret) {
64
+ return scryptSync(secret, "bp-config-store", 32);
65
+ }
66
+ function encryptValue(plaintext, key) {
67
+ const iv = randomBytes(IV_LENGTH);
68
+ const cipher = createCipheriv(ALGORITHM, key, iv);
69
+ const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
70
+ const authTag = cipher.getAuthTag();
71
+ const payload = Buffer.concat([iv, authTag, encrypted]).toString("base64");
72
+ return `${ENCRYPTED_PREFIX}${payload}`;
73
+ }
74
+ function decryptValue(ciphertext, key) {
75
+ if (!ciphertext.startsWith(ENCRYPTED_PREFIX))
76
+ return ciphertext;
77
+ const payload = Buffer.from(ciphertext.slice(ENCRYPTED_PREFIX.length), "base64");
78
+ const iv = payload.subarray(0, IV_LENGTH);
79
+ const authTag = payload.subarray(IV_LENGTH, IV_LENGTH + AUTH_TAG_LENGTH);
80
+ const encrypted = payload.subarray(IV_LENGTH + AUTH_TAG_LENGTH);
81
+ const decipher = createDecipheriv(ALGORITHM, key, iv);
82
+ decipher.setAuthTag(authTag);
83
+ return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf8");
84
+ }
85
+ function resolveSecretKeys(configSchemas) {
86
+ return new Set(configSchemas.flatMap((schema) => schema.fields
87
+ .filter((field) => field.visibility === "secret")
88
+ .map((field) => field.key)));
89
+ }
90
+ function encryptSecrets(values, secretKeys, key) {
91
+ return Object.fromEntries(Object.entries(values).map(([k, v]) => [
92
+ k,
93
+ secretKeys.has(k) && typeof v === "string" ? encryptValue(v, key) : v
94
+ ]));
95
+ }
96
+ function decryptSecrets(values, secretKeys, key) {
97
+ return Object.fromEntries(Object.entries(values).map(([k, v]) => [
98
+ k,
99
+ secretKeys.has(k) && typeof v === "string" && v.startsWith(ENCRYPTED_PREFIX)
100
+ ? decryptValue(v, key)
101
+ : v
102
+ ]));
103
+ }
104
+ export class FileBackedServiceConfigStore {
105
+ state;
106
+ key;
107
+ secretKeys;
108
+ filePath;
109
+ constructor(options) {
110
+ this.filePath = options.filePath;
111
+ this.key = deriveKey(options.encryptionKey);
112
+ this.secretKeys = resolveSecretKeys(options.configSchemas);
113
+ this.state = this.loadFromDisk();
114
+ }
115
+ read(ticket) {
116
+ return this.readBucket(ticket.tenantId);
117
+ }
118
+ write(tenantId, appId, values, ticket) {
119
+ const parsed = ValuesSchema.parse(values);
120
+ if (tenantId !== ticket.tenantId) {
121
+ return this.read(ticket);
122
+ }
123
+ const encrypted = encryptSecrets(parsed, this.secretKeys, this.key);
124
+ const current = this.ensureTenantBucket(tenantId);
125
+ if (appId) {
126
+ this.state.tenants[tenantId] = {
127
+ tenant: current.tenant,
128
+ app: { ...current.app, [appId]: { ...(current.app[appId] ?? {}), ...encrypted } }
129
+ };
130
+ }
131
+ else {
132
+ this.state.tenants[tenantId] = { tenant: { ...current.tenant, ...encrypted }, app: current.app };
133
+ }
134
+ this.saveToDisk();
135
+ return this.read(ticket);
136
+ }
137
+ clearKey(tenantId, appId, key, ticket) {
138
+ if (tenantId !== ticket.tenantId)
139
+ return this.read(ticket);
140
+ const current = this.ensureTenantBucket(tenantId);
141
+ if (appId) {
142
+ const appValues = { ...(current.app[appId] ?? {}) };
143
+ delete appValues[key];
144
+ this.state.tenants[tenantId] = {
145
+ tenant: current.tenant,
146
+ app: { ...current.app, [appId]: appValues }
147
+ };
148
+ }
149
+ else {
150
+ const tenantValues = { ...current.tenant };
151
+ delete tenantValues[key];
152
+ this.state.tenants[tenantId] = { tenant: tenantValues, app: current.app };
153
+ }
154
+ this.saveToDisk();
155
+ return this.read(ticket);
156
+ }
157
+ readBucket(tenantId) {
158
+ const bucket = this.ensureTenantBucket(tenantId);
159
+ return {
160
+ tenant: this.decryptRecord(bucket.tenant),
161
+ app: Object.fromEntries(Object.entries(bucket.app).map(([id, vals]) => [id, this.decryptRecord(vals)]))
162
+ };
163
+ }
164
+ ensureTenantBucket(tenantId) {
165
+ if (!this.state.tenants[tenantId] && this.state.legacy) {
166
+ this.state.tenants[tenantId] = this.state.legacy;
167
+ delete this.state.legacy;
168
+ this.saveToDisk();
169
+ }
170
+ if (!this.state.tenants[tenantId]) {
171
+ this.state.tenants[tenantId] = emptyBucket();
172
+ }
173
+ return this.state.tenants[tenantId];
174
+ }
175
+ decryptRecord(values) {
176
+ return decryptSecrets(values, this.secretKeys, this.key);
177
+ }
178
+ loadFromDisk() {
179
+ if (!existsSync(this.filePath)) {
180
+ return { tenants: {} };
181
+ }
182
+ const raw = readFileSync(this.filePath, "utf8");
183
+ const parsed = JSON.parse(raw);
184
+ if (parsed && typeof parsed === "object" && parsed.tenants && typeof parsed.tenants === "object") {
185
+ return { tenants: parsed.tenants };
186
+ }
187
+ return { tenants: {}, legacy: { tenant: parsed.tenant ?? {}, app: parsed.app ?? {} } };
188
+ }
189
+ saveToDisk() {
190
+ const dir = dirname(this.filePath);
191
+ if (!existsSync(dir)) {
192
+ mkdirSync(dir, { recursive: true });
193
+ }
194
+ writeFileSync(this.filePath, JSON.stringify({ tenants: this.state.tenants }, null, 2), "utf8");
195
+ }
196
+ }
197
+ //# sourceMappingURL=configStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configStore.js","sourceRoot":"","sources":["../../src/runtime/configStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { type ServiceConfigAction, type ServiceConfigTicketClaims } from "../contracts/serviceConfig.js";
2
+ /** Audience every BetterPortal service-config ticket is minted for. */
3
+ export declare const CONFIG_TICKET_AUDIENCE = "betterportal-service-config";
4
+ export interface SignServiceConfigTicketOptions {
5
+ /** PEM of the CP signing key (cpState.keyPair.privateKeyPem). */
6
+ privateKeyPem: string;
7
+ /** kid published in the CP JWKS. */
8
+ kid: string;
9
+ /** CP issuer (cpState.issuer); becomes the `iss` claim and verifier expectation. */
10
+ issuer: string;
11
+ tenantId: string;
12
+ serviceId: string;
13
+ actions: ServiceConfigAction[];
14
+ subject?: string;
15
+ bindingId?: string;
16
+ expiresInSeconds: number;
17
+ jti?: string;
18
+ }
19
+ /**
20
+ * Mint a config ticket as an RS256 JWT signed by the control plane's key.
21
+ * Replaces the legacy symmetric HMAC ticket - services verify it against the
22
+ * CP JWKS, so no shared secret is required and only the CP can issue tickets.
23
+ */
24
+ export declare function signServiceConfigTicket(options: SignServiceConfigTicketOptions): string;
25
+ export interface VerifyServiceConfigTicketOptions {
26
+ /** JWKS endpoint of the issuing control plane (delivered to the service at redeem). */
27
+ jwksUri?: string;
28
+ /** In-process key lookup, used instead of jwksUri when supplied (no network). */
29
+ keyResolver?: (kid: string) => Promise<string> | string;
30
+ /** Expected `iss` - the CP URL the service was installed against. */
31
+ issuer: string;
32
+ /** This service's id; the ticket's `serviceId` must match. */
33
+ serviceId: string;
34
+ clockToleranceSeconds?: number;
35
+ }
36
+ /**
37
+ * Verify a CP-signed config ticket against the CP JWKS. Throws on any failure.
38
+ * Pins RS256, rejects jku/x5u key references, and re-checks iss/aud/exp/serviceId
39
+ * after library verification (defence in depth).
40
+ */
41
+ export declare function verifyServiceConfigTicket(token: string, options: VerifyServiceConfigTicketOptions): Promise<ServiceConfigTicketClaims>;
42
+ /**
43
+ * Build a `validateTicket` callback for `registerServiceConfigRoutes` that
44
+ * verifies CP-signed tickets against the CP JWKS. Returns null (not throw) on
45
+ * any failure so the route responds 401 rather than 500.
46
+ */
47
+ export declare function createCpConfigTicketValidator(options: VerifyServiceConfigTicketOptions): (ticketValue: string | null, ...rest: unknown[]) => Promise<ServiceConfigTicketClaims | null>;
48
+ export declare function clearConfigTicketJwksCache(): void;
49
+ //# sourceMappingURL=configTicket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configTicket.d.ts","sourceRoot":"","sources":["../../src/runtime/configTicket.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC/B,MAAM,+BAA+B,CAAC;AAOvC,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,gCAAgC,CAAC;AAIpE,MAAM,WAAW,8BAA8B;IAC7C,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,oFAAoF;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,8BAA8B,GAAG,MAAM,CAqBvF;AAgCD,MAAM,WAAW,gCAAgC;IAC/C,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACxD,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAoEpC;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,gCAAgC,GACxC,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAS/F;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}