@cosmicdrift/kumiko-server-runtime 0.359.0 → 0.361.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/pii-boot-gate.js
CHANGED
|
@@ -32,7 +32,7 @@ export function assertPiiBootInvariants(features, opts) {
|
|
|
32
32
|
].join(" and ");
|
|
33
33
|
if (opts.mode === "dev") {
|
|
34
34
|
// biome-ignore lint/suspicious/noConsole: boot-time security warning
|
|
35
|
-
console.warn(`[${tag}] ${carriers} carry pii/userOwned/tenantOwned/recordOwned annotations or a non-"none" defineEvent PII stance but no \`kms\` adapter is configured — fields are stored in PLAINTEXT locally. Pass { kms: new InMemoryKmsAdapter() } (ephemeral DB) or createPgKmsAdapter(...) to exercise crypto-shredding in dev.`);
|
|
35
|
+
console.warn(`[${tag}] ${carriers} carry pii/userOwned/tenantOwned/recordOwned annotations or a non-"none" defineEvent PII stance but no \`kms\` adapter is configured — fields are stored in PLAINTEXT locally. Plaintext PII means dev/e2e raw reads will not see the ciphertext prod stores. Pass { kms: new InMemoryKmsAdapter() } (ephemeral DB) or createPgKmsAdapter(...) (persistent dev DB) to exercise crypto-shredding in dev.`);
|
|
36
36
|
// skip: dev mode, plaintext-PII warning already logged above
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const APP_BASE_URL_ENV = "APP_BASE_URL";
|
|
2
|
+
type AuthOriginOptions = {
|
|
3
|
+
readonly allowedOrigins?: readonly string[];
|
|
4
|
+
readonly unsafeSkipOriginCheck?: boolean;
|
|
5
|
+
readonly cookieDomain?: string;
|
|
6
|
+
readonly publicOrigin?: string;
|
|
7
|
+
readonly mail?: {
|
|
8
|
+
readonly baseUrl: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export declare function resolveAuthPublicOrigin(auth: AuthOriginOptions, envSource: Record<string, string | undefined>, warn: (message: string) => void): string | undefined;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { publicOriginOf } from "@cosmicdrift/kumiko-framework/api";
|
|
2
|
+
export const APP_BASE_URL_ENV = "APP_BASE_URL";
|
|
3
|
+
// The mail link base is what users already open from auth mails, so it wins
|
|
4
|
+
// over the infra-provided APP_BASE_URL. Missing or unparsable in production
|
|
5
|
+
// is a loud warning, not a boot failure: the double-submit CSRF token still
|
|
6
|
+
// protects, the Origin guard is defense in depth.
|
|
7
|
+
export function resolveAuthPublicOrigin(auth, envSource, warn) {
|
|
8
|
+
if ((auth.allowedOrigins?.length ?? 0) > 0 || auth.unsafeSkipOriginCheck === true) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const envBaseUrl = envSource[APP_BASE_URL_ENV] === "" ? undefined : envSource[APP_BASE_URL_ENV];
|
|
12
|
+
const baseUrl = auth.publicOrigin ?? auth.mail?.baseUrl ?? envBaseUrl;
|
|
13
|
+
const origin = baseUrl === undefined ? undefined : publicOriginOf(baseUrl);
|
|
14
|
+
if (origin === undefined &&
|
|
15
|
+
auth.cookieDomain === undefined &&
|
|
16
|
+
envSource["NODE_ENV"] === "production") {
|
|
17
|
+
warn("[runProdApp] WARNING: no valid public app URL is known (auth.publicOrigin, " +
|
|
18
|
+
`auth.mail.baseUrl or ${APP_BASE_URL_ENV}), so the server-side Origin guard is OFF. ` +
|
|
19
|
+
"Cookie-authenticated requests are protected by the CSRF token only. Set " +
|
|
20
|
+
`auth.mail.baseUrl or ${APP_BASE_URL_ENV} to the app's https URL.`);
|
|
21
|
+
}
|
|
22
|
+
return origin;
|
|
23
|
+
}
|
package/dist/run-prod-app.d.ts
CHANGED
|
@@ -132,6 +132,10 @@ export type RunProdAppAuthOptions = {
|
|
|
132
132
|
* AuthRoutesConfig.cookieDomain). Set to the registrable parent
|
|
133
133
|
* domain when login and app live on different subdomains. */
|
|
134
134
|
readonly cookieDomain?: string;
|
|
135
|
+
/** Secure flag for the session cookies (see AuthRoutesConfig.secureCookies).
|
|
136
|
+
* Defaults to NODE_ENV === "production"; set it to true when TLS ends at a
|
|
137
|
+
* proxy and NODE_ENV is not "production". */
|
|
138
|
+
readonly secureCookies?: boolean;
|
|
135
139
|
/** Former cookie domains cleared on login/logout (see
|
|
136
140
|
* AuthRoutesConfig.retiredCookieDomains). */
|
|
137
141
|
readonly retiredCookieDomains?: readonly string[];
|
|
@@ -144,6 +148,10 @@ export type RunProdAppAuthOptions = {
|
|
|
144
148
|
* — accept the wide-cookie CSRF risk explicitly instead of setting
|
|
145
149
|
* `allowedOrigins`. */
|
|
146
150
|
readonly unsafeSkipOriginCheck?: boolean;
|
|
151
|
+
/** Canonical public origin for the default Origin guard (see
|
|
152
|
+
* AuthRoutesConfig.publicOrigin). Defaults to the origin of
|
|
153
|
+
* `mail.baseUrl`, then of the APP_BASE_URL env. */
|
|
154
|
+
readonly publicOrigin?: string;
|
|
147
155
|
/** Number of trusted reverse-proxy hops between the client and this
|
|
148
156
|
* process for client-IP derivation (see AuthRoutesConfig.trustedProxyHops,
|
|
149
157
|
* kumiko-framework#1539) — closes the X-Forwarded-For spoofing hole on
|
package/dist/run-prod-app.js
CHANGED
|
@@ -71,6 +71,7 @@ import { buildBunServeOptions, resolveDerivedMaxRequestBodySize } from "./bun-se
|
|
|
71
71
|
import { buildComposeAuthOptions, composeFeatures } from "./compose-features.js";
|
|
72
72
|
import { makeDispatchSystemWrite } from "./extra-routes-deps.js";
|
|
73
73
|
import { assertPiiBootInvariants } from "./pii-boot-gate.js";
|
|
74
|
+
import { resolveAuthPublicOrigin } from "./resolve-auth-public-origin.js";
|
|
74
75
|
import { addConfigAccessorFactory, buildBootExtraContext, buildProdSessionAuth, loggerFromExtraContext, resolveAuthMail, wireProdPatAutoRevoke, } from "./run-prod-app-boot-context.js";
|
|
75
76
|
import { buildStaticFallback } from "./run-prod-app-static-files.js";
|
|
76
77
|
import { withSecurityHeaders } from "./security-headers.js";
|
|
@@ -279,6 +280,12 @@ export async function runProdApp(options) {
|
|
|
279
280
|
const effectiveAuth = options.auth
|
|
280
281
|
? resolveAuthMail(options.auth, jwtSecret, envSource)
|
|
281
282
|
: undefined;
|
|
283
|
+
const authPublicOrigin = effectiveAuth
|
|
284
|
+
? resolveAuthPublicOrigin(effectiveAuth, envSource, (message) => {
|
|
285
|
+
// biome-ignore lint/suspicious/noConsole: boot-time warn, no logger configured this early
|
|
286
|
+
console.warn(message);
|
|
287
|
+
})
|
|
288
|
+
: undefined;
|
|
282
289
|
// 3. Feature registry. Auth-mode auto-mixes config/user/tenant/auth-email-
|
|
283
290
|
// password via composeFeatures — same source-of-truth as runDevApp
|
|
284
291
|
// AND the per-app drizzle-Schema-Generator, so Migration und Runtime
|
|
@@ -532,6 +539,9 @@ export async function runProdApp(options) {
|
|
|
532
539
|
...(effectiveAuth.cookieDomain !== undefined && {
|
|
533
540
|
cookieDomain: effectiveAuth.cookieDomain,
|
|
534
541
|
}),
|
|
542
|
+
...(effectiveAuth.secureCookies !== undefined && {
|
|
543
|
+
secureCookies: effectiveAuth.secureCookies,
|
|
544
|
+
}),
|
|
535
545
|
...(effectiveAuth.retiredCookieDomains !== undefined && {
|
|
536
546
|
retiredCookieDomains: effectiveAuth.retiredCookieDomains,
|
|
537
547
|
}),
|
|
@@ -541,6 +551,7 @@ export async function runProdApp(options) {
|
|
|
541
551
|
...(effectiveAuth.unsafeSkipOriginCheck !== undefined && {
|
|
542
552
|
unsafeSkipOriginCheck: effectiveAuth.unsafeSkipOriginCheck,
|
|
543
553
|
}),
|
|
554
|
+
...(authPublicOrigin !== undefined && { publicOrigin: authPublicOrigin }),
|
|
544
555
|
...(trustedProxyHops !== undefined && { trustedProxyHops }),
|
|
545
556
|
...(effectiveAuth.postAuthLanding !== undefined && {
|
|
546
557
|
postAuthLanding: effectiveAuth.postAuthLanding,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-server-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.361.0",
|
|
4
4
|
"description": "Production server-boot runtime for Kumiko apps: connections, schema-drift-gate, seeds, lifecycle, graceful shutdown. Symmetric to kumiko-dev-server's runDevApp, without dev/scaffold/codegen tooling.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -84,11 +84,11 @@
|
|
|
84
84
|
}
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@cosmicdrift/kumiko-bundled-features": "0.
|
|
88
|
-
"@cosmicdrift/kumiko-framework": "0.
|
|
89
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
90
|
-
"@cosmicdrift/kumiko-renderer-web": "0.
|
|
91
|
-
"@cosmicdrift/kumiko-types": "0.
|
|
87
|
+
"@cosmicdrift/kumiko-bundled-features": "0.361.0",
|
|
88
|
+
"@cosmicdrift/kumiko-framework": "0.361.0",
|
|
89
|
+
"@cosmicdrift/kumiko-headless": "0.361.0",
|
|
90
|
+
"@cosmicdrift/kumiko-renderer-web": "0.361.0",
|
|
91
|
+
"@cosmicdrift/kumiko-types": "0.361.0",
|
|
92
92
|
"bun-types": "^1.3.13",
|
|
93
93
|
"ioredis": "^5.10.1",
|
|
94
94
|
"temporal-polyfill": "^0.3.2"
|