@cosmicdrift/kumiko-types 0.264.1 → 0.265.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/handlers.ts +26 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.264.1",
3
+ "version": "0.265.0",
4
4
  "description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
package/src/handlers.ts CHANGED
@@ -179,6 +179,25 @@ export type AuthClaimsHookDef = {
179
179
  readonly declaredKeys?: ReadonlySet<string>;
180
180
  };
181
181
 
182
+ // --- Active Membership ---
183
+
184
+ // Not a member of the target tenant, the principal is blocked (see
185
+ // engine/active-membership.ts's principalStatus contract), or the tenant is in teardown.
186
+ export type ActiveMembershipRejection = "not_a_member" | "principal_blocked" | "tenant_teardown";
187
+
188
+ export type ActiveMembership = {
189
+ readonly tenantId: TenantId;
190
+ // Raw membership roles — the caller runs buildSessionRoles(globalRoles,
191
+ // roles) itself; this building block never merges global roles in.
192
+ readonly roles: readonly string[];
193
+ readonly tenantName?: string;
194
+ readonly tenantKey?: string;
195
+ };
196
+
197
+ export type ActiveMembershipResult =
198
+ | { readonly kind: "active"; readonly membership: ActiveMembership }
199
+ | { readonly kind: "rejected"; readonly reason: ActiveMembershipRejection };
200
+
182
201
  // --- Handler Events ---
183
202
 
184
203
  export type WriteEvent<TPayload = unknown> = {
@@ -610,6 +629,13 @@ export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedCon
610
629
  // before the JWT is signed. Thin pass-through to dispatcher.resolveAuthClaims
611
630
  // so there's a single resolve impl — both entry-points can't drift.
612
631
  readonly resolveAuthClaims: (user: SessionUser) => Promise<Record<string, unknown>>;
632
+
633
+ // Membership check for interactive sign-in paths (login, MFA completion,
634
+ // tenant switch). Thin pass-through to dispatcher.resolveActiveMembership so there's a single resolve impl.
635
+ readonly resolveActiveMembership: (
636
+ userId: string,
637
+ tenantId: TenantId,
638
+ ) => Promise<ActiveMembershipResult>;
613
639
  };
614
640
 
615
641
  // Job execution: db + registry + systemUser + logging guaranteed, plus a