@cosmicdrift/kumiko-dev-server 0.109.0 → 0.110.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.109.0",
3
+ "version": "0.110.0",
4
4
  "description": "Development server bootstrap for Kumiko apps. Bundles the client, mints dev-JWTs, injects the resolved AppSchema, and seeds an admin. Not for production.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -50,8 +50,8 @@
50
50
  "kumiko-schema-check": "./bin/kumiko-schema-check.ts"
51
51
  },
52
52
  "dependencies": {
53
- "@cosmicdrift/kumiko-bundled-features": "0.109.0",
54
- "@cosmicdrift/kumiko-framework": "0.109.0",
53
+ "@cosmicdrift/kumiko-bundled-features": "0.110.0",
54
+ "@cosmicdrift/kumiko-framework": "0.110.0",
55
55
  "ts-morph": "^28.0.0"
56
56
  },
57
57
  "publishConfig": {
@@ -29,7 +29,9 @@ import {
29
29
  patScopesFromFeature,
30
30
  } from "@cosmicdrift/kumiko-bundled-features/personal-access-tokens";
31
31
  import {
32
+ bindAutoRevokeFromFeature,
32
33
  createSessionCallbacks,
34
+ SESSIONS_FEATURE,
33
35
  type SessionCallbacks,
34
36
  } from "@cosmicdrift/kumiko-bundled-features/sessions";
35
37
  import { TenantQueries } from "@cosmicdrift/kumiko-bundled-features/tenant";
@@ -463,6 +465,12 @@ export async function runDevApp(options: RunDevAppOptions): Promise<KumikoServer
463
465
  db: stack.db,
464
466
  ...(expiresInMs !== undefined && { expiresInMs }),
465
467
  });
468
+ // Secure-by-default (symmetrisch zu runProdApp): Password-Change/
469
+ // -Reset mass-revoked die Sessions des Users ohne App-Opt-in.
470
+ const sessionsFeature = features.find((f) => f.name === SESSIONS_FEATURE);
471
+ if (sessionsFeature) {
472
+ bindAutoRevokeFromFeature(sessionsFeature)?.(sessionCallbacks.sessionMassRevoker);
473
+ }
466
474
  }
467
475
  if (patFeature) {
468
476
  patResolver = createPatResolver({ db: stack.db, scopes: patScopesFromFeature(patFeature) });
@@ -61,6 +61,7 @@ import {
61
61
  SECRETS_FEATURE_NAME,
62
62
  } from "@cosmicdrift/kumiko-bundled-features/secrets";
63
63
  import {
64
+ bindAutoRevokeFromFeature,
64
65
  createSessionCallbacks,
65
66
  SESSIONS_FEATURE,
66
67
  } from "@cosmicdrift/kumiko-bundled-features/sessions";
@@ -942,19 +943,20 @@ export async function runProdApp(options: RunProdAppOptions): Promise<ProdAppHan
942
943
  // sessionStrictMode=true: Prod-Sessions sollen nicht stillschweigend
943
944
  // von einem JWT-ohne-sid umgangen werden können. sessionMassRevoker
944
945
  // (4. callback aus createSessionCallbacks) ist nicht Teil der
945
- // AuthRoutesConfig-Surface — der wird vom sessions-Feature selbst über
946
- // die `autoRevokeOnPasswordChange`-Option konsumiert, nicht über die
947
- // auth-routes.
946
+ // AuthRoutesConfig-Surface — der geht via bindAutoRevokeFromFeature ans
947
+ // sessions-Feature (Password-Change/-Reset revoked alle Sessions), nicht
948
+ // über die auth-routes.
948
949
  // Secure-by-default: if the sessions feature is mounted, server-side revocation +
949
- // sessionStrictMode are wired automatically; `auth.sessions` only overrides the config,
950
- // and `auth.sessions: false` is the explicit opt-out (back to stateless JWTs).
951
- const sessionsFeatureMounted = features.some((f) => f.name === SESSIONS_FEATURE);
950
+ // sessionStrictMode + auto-revoke-on-password-change are wired automatically;
951
+ // `auth.sessions` only overrides the config, and `auth.sessions: false` is the
952
+ // explicit opt-out (back to stateless JWTs).
953
+ const sessionsFeature = features.find((f) => f.name === SESSIONS_FEATURE);
952
954
  const sessionAuthFragment = shouldWireProdSessions(
953
955
  Boolean(effectiveAuth),
954
- sessionsFeatureMounted,
956
+ sessionsFeature !== undefined,
955
957
  effectiveAuth?.sessions,
956
958
  )
957
- ? buildProdSessionAuth(db, resolveProdSessionsConfig(effectiveAuth?.sessions))
959
+ ? buildProdSessionAuth(db, resolveProdSessionsConfig(effectiveAuth?.sessions), sessionsFeature)
958
960
  : undefined;
959
961
 
960
962
  // PAT opt-in: if the personal-access-tokens feature is mounted, wire its
@@ -1492,6 +1494,7 @@ export function staticCachePolicy(pathname: string): CachePolicy {
1492
1494
  function buildProdSessionAuth(
1493
1495
  db: import("@cosmicdrift/kumiko-framework/db").DbConnection,
1494
1496
  opts: ProdSessionsConfig,
1497
+ sessionsFeature: import("@cosmicdrift/kumiko-framework/engine").FeatureDefinition | undefined,
1495
1498
  ): {
1496
1499
  readonly sessionCreator: ReturnType<typeof createSessionCallbacks>["sessionCreator"];
1497
1500
  readonly sessionRevoker: ReturnType<typeof createSessionCallbacks>["sessionRevoker"];
@@ -1502,6 +1505,11 @@ function buildProdSessionAuth(
1502
1505
  db,
1503
1506
  ...(opts.expiresInMs !== undefined && { expiresInMs: opts.expiresInMs }),
1504
1507
  });
1508
+ // Secure-by-default: password-change/-reset mass-revokes the user's live
1509
+ // sessions without the app opting in via autoRevokeOnPasswordChange.
1510
+ if (sessionsFeature) {
1511
+ bindAutoRevokeFromFeature(sessionsFeature)?.(cbs.sessionMassRevoker);
1512
+ }
1505
1513
  return {
1506
1514
  sessionCreator: cbs.sessionCreator,
1507
1515
  sessionRevoker: cbs.sessionRevoker,