@stigmer/server 3.14.1 → 3.15.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/boot/compose.d.ts +8 -1
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +121 -14
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/config.d.ts +14 -0
- package/dist/boot/config.d.ts.map +1 -1
- package/dist/boot/config.js +1 -0
- package/dist/boot/config.js.map +1 -1
- package/dist/domain/apikey/verifier.d.ts +8 -1
- package/dist/domain/apikey/verifier.d.ts.map +1 -1
- package/dist/domain/apikey/verifier.js +14 -2
- package/dist/domain/apikey/verifier.js.map +1 -1
- package/dist/domain/identityaccount/constants.d.ts +66 -0
- package/dist/domain/identityaccount/constants.d.ts.map +1 -0
- package/dist/domain/identityaccount/constants.js +153 -0
- package/dist/domain/identityaccount/constants.js.map +1 -0
- package/dist/domain/identityaccount/controller.d.ts +34 -0
- package/dist/domain/identityaccount/controller.d.ts.map +1 -0
- package/dist/domain/identityaccount/controller.js +342 -0
- package/dist/domain/identityaccount/controller.js.map +1 -0
- package/dist/domain/identityaccount/operator.d.ts +14 -0
- package/dist/domain/identityaccount/operator.d.ts.map +1 -0
- package/dist/domain/identityaccount/operator.js +67 -0
- package/dist/domain/identityaccount/operator.js.map +1 -0
- package/dist/domain/identityaccount/provisioning.d.ts +52 -0
- package/dist/domain/identityaccount/provisioning.d.ts.map +1 -0
- package/dist/domain/identityaccount/provisioning.js +114 -0
- package/dist/domain/identityaccount/provisioning.js.map +1 -0
- package/dist/domain/identityaccount/resolve.d.ts +36 -0
- package/dist/domain/identityaccount/resolve.d.ts.map +1 -0
- package/dist/domain/identityaccount/resolve.js +12 -0
- package/dist/domain/identityaccount/resolve.js.map +1 -0
- package/dist/domain/identityaccount/resource-store.d.ts +4 -0
- package/dist/domain/identityaccount/resource-store.d.ts.map +1 -0
- package/dist/domain/identityaccount/resource-store.js +131 -0
- package/dist/domain/identityaccount/resource-store.js.map +1 -0
- package/dist/domain/identityaccount/steps.d.ts +79 -0
- package/dist/domain/identityaccount/steps.d.ts.map +1 -0
- package/dist/domain/identityaccount/steps.js +291 -0
- package/dist/domain/identityaccount/steps.js.map +1 -0
- package/dist/domain/identityaccount/store-contract.d.ts +22 -0
- package/dist/domain/identityaccount/store-contract.d.ts.map +1 -0
- package/dist/domain/identityaccount/store-contract.js +307 -0
- package/dist/domain/identityaccount/store-contract.js.map +1 -0
- package/dist/domain/identityaccount/store.d.ts +66 -0
- package/dist/domain/identityaccount/store.d.ts.map +1 -0
- package/dist/domain/identityaccount/store.js +13 -0
- package/dist/domain/identityaccount/store.js.map +1 -0
- package/dist/extensions/drivers.d.ts +26 -0
- package/dist/extensions/drivers.d.ts.map +1 -1
- package/dist/extensions/gate-slots.d.ts +16 -1
- package/dist/extensions/gate-slots.d.ts.map +1 -1
- package/dist/extensions/gate-slots.js +1 -0
- package/dist/extensions/gate-slots.js.map +1 -1
- package/dist/extensions/identity-federation.d.ts +36 -0
- package/dist/extensions/identity-federation.d.ts.map +1 -0
- package/dist/extensions/identity-federation.js +2 -0
- package/dist/extensions/identity-federation.js.map +1 -0
- package/dist/extensions/registry.d.ts +18 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/extensions/registry.js +20 -0
- package/dist/extensions/registry.js.map +1 -1
- package/dist/identity/oidc-discovery.d.ts +36 -0
- package/dist/identity/oidc-discovery.d.ts.map +1 -0
- package/dist/identity/oidc-discovery.js +60 -0
- package/dist/identity/oidc-discovery.js.map +1 -0
- package/dist/identity/oidc-userinfo.d.ts +30 -0
- package/dist/identity/oidc-userinfo.d.ts.map +1 -0
- package/dist/identity/oidc-userinfo.js +28 -0
- package/dist/identity/oidc-userinfo.js.map +1 -0
- package/dist/identity/oidc-verifier.d.ts +6 -0
- package/dist/identity/oidc-verifier.d.ts.map +1 -1
- package/dist/identity/oidc-verifier.js +35 -34
- package/dist/identity/oidc-verifier.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/interceptors/auth.d.ts +10 -0
- package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
- package/dist/pipeline/interceptors/auth.js +9 -1
- package/dist/pipeline/interceptors/auth.js.map +1 -1
- package/dist/transport/console/handler.d.ts +22 -5
- package/dist/transport/console/handler.d.ts.map +1 -1
- package/dist/transport/console/handler.js +53 -24
- package/dist/transport/console/handler.js.map +1 -1
- package/package.json +4 -4
- package/src/boot/__tests__/auth-enabled-composition.test.ts +274 -4
- package/src/boot/__tests__/config.test.ts +41 -3
- package/src/boot/compose.ts +148 -15
- package/src/boot/config.ts +15 -0
- package/src/domain/apikey/__tests__/verifier.test.ts +146 -22
- package/src/domain/apikey/verifier.ts +24 -2
- package/src/domain/identityaccount/__tests__/constants.test.ts +155 -0
- package/src/domain/identityaccount/__tests__/identityaccount.test.ts +484 -0
- package/src/domain/identityaccount/__tests__/operator.test.ts +180 -0
- package/src/domain/identityaccount/__tests__/provisioning.test.ts +281 -0
- package/src/domain/identityaccount/__tests__/resolve.test.ts +114 -0
- package/src/domain/identityaccount/__tests__/resource-store.test.ts +216 -0
- package/src/domain/identityaccount/__tests__/support.ts +58 -0
- package/src/domain/identityaccount/constants.ts +178 -0
- package/src/domain/identityaccount/controller.ts +667 -0
- package/src/domain/identityaccount/operator.ts +94 -0
- package/src/domain/identityaccount/provisioning.ts +182 -0
- package/src/domain/identityaccount/resolve.ts +52 -0
- package/src/domain/identityaccount/resource-store.ts +157 -0
- package/src/domain/identityaccount/steps.ts +377 -0
- package/src/domain/identityaccount/store-contract.ts +471 -0
- package/src/domain/identityaccount/store.ts +70 -0
- package/src/extensions/__tests__/identity-account-composed.test.ts +803 -0
- package/src/extensions/__tests__/identity-account-points.test.ts +129 -0
- package/src/extensions/__tests__/registry.test.ts +4 -0
- package/src/extensions/__tests__/tier-truthfulness.test.ts +299 -0
- package/src/extensions/drivers.ts +26 -0
- package/src/extensions/gate-slots.ts +16 -0
- package/src/extensions/identity-federation.ts +58 -0
- package/src/extensions/registry.ts +44 -1
- package/src/identity/__tests__/oidc-discovery.test.ts +122 -0
- package/src/identity/__tests__/oidc-userinfo.test.ts +103 -0
- package/src/identity/__tests__/oidc-verifier.test.ts +173 -3
- package/src/identity/oidc-discovery.ts +84 -0
- package/src/identity/oidc-userinfo.ts +64 -0
- package/src/identity/oidc-verifier.ts +42 -45
- package/src/index.ts +19 -0
- package/src/pipeline/interceptors/auth.ts +13 -1
- package/src/pipeline/steps/__tests__/authorize-annotation-completeness.test.ts +184 -0
- package/src/transport/console/__tests__/handler.test.ts +93 -23
- package/src/transport/console/__tests__/resolver.test.ts +6 -0
- package/src/transport/console/handler.ts +84 -30
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
* nginx-equivalence-gated); this module owns the HTTP half: the lane
|
|
7
7
|
* guard, header policy, config synthesis, and file streaming.
|
|
8
8
|
*
|
|
9
|
+
* /config.json is also how the served console learns to sign in
|
|
10
|
+
* (20260913.02 sp.console-login; stigmer#924): the composition root hands
|
|
11
|
+
* the lane the server's authentication posture (ConsoleSignInPosture) and
|
|
12
|
+
* the lane publishes it in the console's own vocabulary — the OIDC
|
|
13
|
+
* issuer, audience and the console's PKCE client id under the posture,
|
|
14
|
+
* `disabled` under trusted local.
|
|
15
|
+
*
|
|
9
16
|
* Lane guard (consoleLaneEligible): the lane claims GET/HEAD only — RPC
|
|
10
17
|
* traffic is POST on service-qualified paths, and OPTIONS preflights keep
|
|
11
18
|
* flowing to the RPC lane's CORS handling — and it never claims:
|
|
@@ -74,18 +81,39 @@ function isServiceShapedPath(pathname: string): boolean {
|
|
|
74
81
|
return segments.length === 2 && (segments[0] ?? "").includes(".");
|
|
75
82
|
}
|
|
76
83
|
|
|
84
|
+
/**
|
|
85
|
+
* How the console this lane serves signs in — the server's authentication
|
|
86
|
+
* posture as the console needs to hear it (20260913.02 sp.console-login).
|
|
87
|
+
* A modeled state, never a nullable: "no issuer configured" and "forgot to
|
|
88
|
+
* wire the posture" must stay distinguishable at the call site.
|
|
89
|
+
*
|
|
90
|
+
* Under `oidc`, `consoleClientId` is the PUBLIC client the operator
|
|
91
|
+
* registered for the browser's PKCE flow, or "" when they have not
|
|
92
|
+
* (Q-CL-1): the lane publishes that truth as-is and the console refuses
|
|
93
|
+
* with copy that names the knob (Q-CL-2), while the composition root has
|
|
94
|
+
* already WARNed at wiring time. Emitting `disabled` instead would send
|
|
95
|
+
* the console into every RPC tokenless, to fail with a worse message.
|
|
96
|
+
*/
|
|
97
|
+
export type ConsoleSignInPosture =
|
|
98
|
+
| { readonly posture: "trusted-local" }
|
|
99
|
+
| {
|
|
100
|
+
readonly posture: "oidc";
|
|
101
|
+
readonly issuer: string;
|
|
102
|
+
readonly audience: string;
|
|
103
|
+
readonly consoleClientId: string;
|
|
104
|
+
};
|
|
105
|
+
|
|
77
106
|
export interface ConsoleLaneOptions {
|
|
78
107
|
readonly assets: ConsoleAssets;
|
|
79
|
-
|
|
80
|
-
* Fallback port for the synthesized apiUrl when a request carries no
|
|
81
|
-
* Host/:authority (technically possible on HTTP/1.0-style clients).
|
|
82
|
-
*/
|
|
83
|
-
readonly grpcPort: number;
|
|
108
|
+
readonly signIn: ConsoleSignInPosture;
|
|
84
109
|
readonly logger: Logger;
|
|
85
110
|
}
|
|
86
111
|
|
|
87
112
|
export function createConsoleLane(options: ConsoleLaneOptions): LaneHandler {
|
|
88
|
-
const { assets,
|
|
113
|
+
const { assets, signIn, logger } = options;
|
|
114
|
+
// The console's runtime config is a pure function of the posture: one
|
|
115
|
+
// body, built once, served on every request.
|
|
116
|
+
const configJsonBody = JSON.stringify(consoleRuntimeConfig(signIn));
|
|
89
117
|
|
|
90
118
|
return (request: LaneRequest, response: LaneResponse): void => {
|
|
91
119
|
const url = request.url ?? "";
|
|
@@ -94,7 +122,7 @@ export function createConsoleLane(options: ConsoleLaneOptions): LaneHandler {
|
|
|
94
122
|
const query = queryStart === -1 ? "" : url.slice(queryStart);
|
|
95
123
|
|
|
96
124
|
if (rawPath === CONFIG_JSON_PATH) {
|
|
97
|
-
serveConfigJson(request, response,
|
|
125
|
+
serveConfigJson(request, response, configJsonBody);
|
|
98
126
|
return;
|
|
99
127
|
}
|
|
100
128
|
|
|
@@ -134,34 +162,60 @@ export function createConsoleLane(options: ConsoleLaneOptions): LaneHandler {
|
|
|
134
162
|
|
|
135
163
|
/**
|
|
136
164
|
* The runtime config the cloud container's entrypoint.sh generates from
|
|
137
|
-
* env
|
|
138
|
-
* the nginx entrypoint script is not ported).
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
165
|
+
* env, synthesized here from the server's own knowledge instead (DD-012:
|
|
166
|
+
* the nginx entrypoint script is not ported). The field names are the
|
|
167
|
+
* console's loader's (client-apps/web/src/config/runtime-config.ts).
|
|
168
|
+
*
|
|
169
|
+
* `apiUrl` is the empty string, which the console reads as "my own
|
|
170
|
+
* origin" — the rule its `appUrl` already follows (20260913.02 Q-CL-3).
|
|
171
|
+
* This lane and the RPC lane share one port, so the console can never
|
|
172
|
+
* need a different origin, and it makes the answer right behind a
|
|
173
|
+
* TLS-terminating proxy without trusting x-forwarded-proto: the earlier
|
|
174
|
+
* Host-derived `http://<host>` sent an https-loaded console to an http
|
|
175
|
+
* API and died on mixed content.
|
|
176
|
+
*
|
|
177
|
+
* Every value here is public metadata: an OIDC issuer URL, an audience
|
|
178
|
+
* string and a PKCE client id are what a browser is handed by design.
|
|
144
179
|
*/
|
|
180
|
+
function consoleRuntimeConfig(signIn: ConsoleSignInPosture): {
|
|
181
|
+
readonly apiUrl: "";
|
|
182
|
+
readonly appUrl: "";
|
|
183
|
+
readonly authMode: "disabled" | "oidc";
|
|
184
|
+
readonly oidcIssuer: string;
|
|
185
|
+
readonly oidcClientId: string;
|
|
186
|
+
readonly oidcAudience: string;
|
|
187
|
+
} {
|
|
188
|
+
switch (signIn.posture) {
|
|
189
|
+
case "trusted-local":
|
|
190
|
+
return {
|
|
191
|
+
apiUrl: "",
|
|
192
|
+
appUrl: "",
|
|
193
|
+
authMode: "disabled",
|
|
194
|
+
oidcIssuer: "",
|
|
195
|
+
oidcClientId: "",
|
|
196
|
+
oidcAudience: "",
|
|
197
|
+
};
|
|
198
|
+
case "oidc":
|
|
199
|
+
return {
|
|
200
|
+
apiUrl: "",
|
|
201
|
+
appUrl: "",
|
|
202
|
+
authMode: "oidc",
|
|
203
|
+
oidcIssuer: signIn.issuer,
|
|
204
|
+
oidcClientId: signIn.consoleClientId,
|
|
205
|
+
oidcAudience: signIn.audience,
|
|
206
|
+
};
|
|
207
|
+
default: {
|
|
208
|
+
const exhaustive: never = signIn;
|
|
209
|
+
throw new Error(`unhandled sign-in posture ${String(exhaustive)}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
145
214
|
function serveConfigJson(
|
|
146
215
|
request: LaneRequest,
|
|
147
216
|
response: LaneResponse,
|
|
148
|
-
|
|
217
|
+
body: string,
|
|
149
218
|
): void {
|
|
150
|
-
// HTTP/1.1 carries Host; Node maps HTTP/2's :authority into the same
|
|
151
|
-
// headers view (and Http2ServerRequest.authority falls back to it).
|
|
152
|
-
const host = request.headers.host ?? request.headers[":authority"];
|
|
153
|
-
const apiUrl =
|
|
154
|
-
typeof host === "string" && host !== ""
|
|
155
|
-
? `http://${host}`
|
|
156
|
-
: `http://localhost:${grpcPort}`;
|
|
157
|
-
const body = JSON.stringify({
|
|
158
|
-
apiUrl,
|
|
159
|
-
appUrl: "",
|
|
160
|
-
authMode: "disabled",
|
|
161
|
-
oidcIssuer: "",
|
|
162
|
-
oidcClientId: "",
|
|
163
|
-
oidcAudience: "",
|
|
164
|
-
});
|
|
165
219
|
response.statusCode = 200;
|
|
166
220
|
response.setHeader("Content-Type", "application/json");
|
|
167
221
|
response.setHeader("Cache-Control", CONFIG_JSON_CACHE_CONTROL);
|