@cosmicdrift/kumiko-types 0.264.1 → 0.266.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 +33 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-types",
3
- "version": "0.264.1",
3
+ "version": "0.266.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
@@ -16,13 +16,17 @@ import type { TzContext } from "./tz-context";
16
16
 
17
17
  // --- Access ---
18
18
 
19
- export type OpenToAllDeclaration = { readonly reason: string };
19
+ // "tenant-members": signed-in members may write personal data not bound to the caller by an owner rule.
20
+ export type OpenToAllPersonalData = "tenant-members";
21
+
22
+ export type OpenToAllDeclaration = {
23
+ readonly reason: string;
24
+ readonly personalData?: OpenToAllPersonalData;
25
+ };
20
26
 
21
27
  export type OpenToAllAccessRule = {
22
28
  // `true` is the deprecated pre-#2855 form, kept until the call-site migration (fw#2854).
23
29
  readonly openToAll: OpenToAllDeclaration | true;
24
- // Write handler intentionally accepts personal data from any authenticated caller (boot-validator gate).
25
- readonly publicIntake?: true;
26
30
  };
27
31
 
28
32
  // AccessRule is DEFAULT-DENY: a handler without an access rule is not reachable.
@@ -179,6 +183,25 @@ export type AuthClaimsHookDef = {
179
183
  readonly declaredKeys?: ReadonlySet<string>;
180
184
  };
181
185
 
186
+ // --- Active Membership ---
187
+
188
+ // Not a member of the target tenant, the principal is blocked (see
189
+ // engine/active-membership.ts's principalStatus contract), or the tenant is in teardown.
190
+ export type ActiveMembershipRejection = "not_a_member" | "principal_blocked" | "tenant_teardown";
191
+
192
+ export type ActiveMembership = {
193
+ readonly tenantId: TenantId;
194
+ // Raw membership roles — the caller runs buildSessionRoles(globalRoles,
195
+ // roles) itself; this building block never merges global roles in.
196
+ readonly roles: readonly string[];
197
+ readonly tenantName?: string;
198
+ readonly tenantKey?: string;
199
+ };
200
+
201
+ export type ActiveMembershipResult =
202
+ | { readonly kind: "active"; readonly membership: ActiveMembership }
203
+ | { readonly kind: "rejected"; readonly reason: ActiveMembershipRejection };
204
+
182
205
  // --- Handler Events ---
183
206
 
184
207
  export type WriteEvent<TPayload = unknown> = {
@@ -610,6 +633,13 @@ export type HandlerContext<TMap extends object = KumikoEventTypeMap> = SharedCon
610
633
  // before the JWT is signed. Thin pass-through to dispatcher.resolveAuthClaims
611
634
  // so there's a single resolve impl — both entry-points can't drift.
612
635
  readonly resolveAuthClaims: (user: SessionUser) => Promise<Record<string, unknown>>;
636
+
637
+ // Membership check for interactive sign-in paths (login, MFA completion,
638
+ // tenant switch). Thin pass-through to dispatcher.resolveActiveMembership so there's a single resolve impl.
639
+ readonly resolveActiveMembership: (
640
+ userId: string,
641
+ tenantId: TenantId,
642
+ ) => Promise<ActiveMembershipResult>;
613
643
  };
614
644
 
615
645
  // Job execution: db + registry + systemUser + logging guaranteed, plus a