@tearleads/client-sdk 0.1.36 → 0.1.38

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 (68) hide show
  1. package/client/Tearleads.d.ts +4 -3
  2. package/client/Tearleads.js +4 -3
  3. package/client/Tearleads.js.map +1 -1
  4. package/client/organizations/organizationGroupHistory.js +1 -1
  5. package/client/organizations/organizationGroupHistory.js.map +1 -1
  6. package/client/organizations/organizationHistory.js +1 -1
  7. package/client/organizations/organizationHistory.js.map +1 -1
  8. package/data/keyingProjectionVerification/principalPolicyVerification.js +1 -2
  9. package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
  10. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js +39 -51
  11. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js.map +1 -1
  12. package/data/keyingProjectionVerification/types.d.ts +1 -1
  13. package/data/keyingProjectionVerification/types.js.map +1 -1
  14. package/data/persistence/organizations/organizationAccessRevocationPersistence.js +4 -0
  15. package/data/persistence/organizations/organizationAccessRevocationPersistence.js.map +1 -1
  16. package/data/persistence/organizations/organizationReadModelPersistence.js +7 -1
  17. package/data/persistence/organizations/organizationReadModelPersistence.js.map +1 -1
  18. package/data/principals/principalRecoveryEpoch.js +18 -0
  19. package/data/principals/principalRecoveryEpoch.js.map +1 -0
  20. package/internal/api-client/ApiClient.d.ts +3 -0
  21. package/internal/api-client/ApiClient.js +10 -7
  22. package/internal/api-client/ApiClient.js.map +1 -1
  23. package/internal/api-client/webSocketTickets.js +45 -0
  24. package/internal/api-client/webSocketTickets.js.map +1 -0
  25. package/internal/validators/operation/auth.d.ts +20 -0
  26. package/internal/validators/realtime/index.js +2 -2
  27. package/internal/validators/realtime/index.js.map +1 -1
  28. package/internal/validators/realtime/wsServerFrames.js +3 -8
  29. package/internal/validators/realtime/wsServerFrames.js.map +1 -1
  30. package/internal/validators/realtime/wsShared.js +6 -0
  31. package/internal/validators/realtime/wsShared.js.map +1 -1
  32. package/internal/validators/response/auth/verify.d.ts +8 -0
  33. package/internal/validators/response/auth/verify.js +3 -0
  34. package/internal/validators/response/auth/verify.js.map +1 -1
  35. package/package.json +1 -1
  36. package/stores/documents/documentStore.js +3 -3
  37. package/stores/documents/documentStore.js.map +1 -1
  38. package/sync/reconciliation/service.js +22 -12
  39. package/sync/reconciliation/service.js.map +1 -1
  40. package/sync/reconciliation/serviceTypes.d.ts +10 -1
  41. package/sync/reconciliation/serviceTypes.js.map +1 -1
  42. package/workflows/organizations/currentGroupPolicyMutationContext.js +5 -5
  43. package/workflows/organizations/currentGroupPolicyMutationContext.js.map +1 -1
  44. package/workflows/principals/principalCurrentRecoveryBatch.js +1 -1
  45. package/workflows/principals/principalCurrentRecoveryBatch.js.map +1 -1
  46. package/workflows/principals/principalRecoveryLocalPreference.js.map +1 -1
  47. package/workflows/principals/principalRecoveryMemo.d.ts +9 -4
  48. package/workflows/principals/principalRecoveryMemo.js +94 -34
  49. package/workflows/principals/principalRecoveryMemo.js.map +1 -1
  50. package/workflows/principals/principalRecoveryMemoValidity.js +33 -0
  51. package/workflows/principals/principalRecoveryMemoValidity.js.map +1 -0
  52. package/workflows/principals/principalRecoveryOutage.js +2 -2
  53. package/workflows/principals/principalRecoveryOutage.js.map +1 -1
  54. package/workflows/principals/recoverCurrentOrganizationPolicy.js +8 -3
  55. package/workflows/principals/recoverCurrentOrganizationPolicy.js.map +1 -1
  56. package/workflows/principals/recoverPrincipalPolicyHistory.js +42 -8
  57. package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
  58. package/workflows/principals/recoverPublicPrincipalHistory.js +5 -5
  59. package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -1
  60. package/workflows/principals/recoverScopedPrincipalPolicyHistory.d.ts +9 -2
  61. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +8 -2
  62. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
  63. package/workflows/principals/runtimePolicyRecovery.js +4 -1
  64. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  65. package/workflows/principals/runtimePolicyWarmer.js +12 -4
  66. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
  67. package/workflows/runtimeInput.d.ts +4 -3
  68. package/workflows/runtimeInput.js.map +1 -1
@@ -99,9 +99,10 @@ export declare class Tearleads {
99
99
  log: (message: string) => void;
100
100
  logError: (message: string | Error, cause?: unknown) => void;
101
101
  /**
102
- * Mint a single-use ticket to authenticate the server-events websocket
103
- * handshake (which cannot carry the bearer header). Returns null when no
104
- * session is active. The caller appends it to the websocket URL.
102
+ * A single-use ticket to authenticate the server-events websocket handshake
103
+ * (which cannot carry the bearer header): the one login returned for the
104
+ * first connect of that session, otherwise a freshly minted one. Returns
105
+ * null when no session is active. The caller appends it to the websocket URL.
105
106
  */
106
107
  requestWebSocketTicket(): Promise<string | null>;
107
108
  get domainScope(): DomainScope;
@@ -191,9 +191,10 @@ export class Tearleads {
191
191
  // rejected promises from async loggers accepted by the void callback type.
192
192
  logError = (message, cause) => this.logErrorHandler(message, cause);
193
193
  /**
194
- * Mint a single-use ticket to authenticate the server-events websocket
195
- * handshake (which cannot carry the bearer header). Returns null when no
196
- * session is active. The caller appends it to the websocket URL.
194
+ * A single-use ticket to authenticate the server-events websocket handshake
195
+ * (which cannot carry the bearer header): the one login returned for the
196
+ * first connect of that session, otherwise a freshly minted one. Returns
197
+ * null when no session is active. The caller appends it to the websocket URL.
197
198
  */
198
199
  requestWebSocketTicket() {
199
200
  return this.apiClient.requestWebSocketTicket();
@@ -1 +1 @@
1
- {"version":3,"file":"Tearleads.js","sourceRoot":"","sources":["Tearleads.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiClient, ApiRequestMetrics } from \"@tearleads/api-client\";\nimport type { BlobStore } from \"../data/blobContracts\";\nimport {\n type DocumentProjectorRegistry,\n type DocumentProjectorRegistryInput,\n resolveDocumentProjectorRegistry,\n} from \"../data/documents/documentKinds\";\nimport { createDomainScope, type DomainScope } from \"../data/domainScope\";\nimport type { SecurityIncidentReporter } from \"../data/securityIncidents\";\nimport { disposeDomainSyncCoordinator } from \"../data/sync/syncCoordinator\";\nimport { resolveIdentityTrustDomain } from \"../data/trustedUserIdentity\";\nimport type { ProvisionedSystemContainerSpec } from \"../workflows/registration\";\nimport { ApiVersion } from \"./apiVersion\";\nimport { type BlobStoreFactory, Blobs } from \"./blobs\";\nimport {\n type ContainerContents,\n createContainerContents,\n} from \"./containerContents\";\nimport { Database, type DatabaseOptions } from \"./database\";\nimport { createDeviceFirst, type DeviceFirst } from \"./deviceFirst\";\nimport { createDocuments, type Documents } from \"./documents\";\nimport { Events } from \"./events\";\nimport {\n createIdentity,\n type Identity,\n type IdentityOptions,\n} from \"./identity\";\nimport { type Logger, logErrorToConsole } from \"./logger\";\nimport { Network } from \"./network\";\nimport { createOrganizations, type Organizations } from \"./organizations\";\nimport type { PrincipalHistoryKeyProvider } from \"./principalHistoryProtection\";\nimport { createRoot, type Root, rootRuntimeOf } from \"./root\";\nimport {\n createSecurityIncidentService,\n type SecurityIncidentListener,\n type SecurityIncidents,\n} from \"./securityIncidents\";\nimport { createSession } from \"./session\";\nimport type { Session } from \"./session/sessionTypes\";\nimport { SyncBillingGate } from \"./syncBillingGate\";\nimport { createUserIdentities, type UserIdentities } from \"./userIdentities\";\nimport {\n createRuntime,\n type InternalRuntime,\n type Runtime,\n} from \"./workflowRuntime\";\n\nfunction createClientSecurityIncidentService(input: {\n readonly apiBaseUrl: string;\n readonly database: Database;\n readonly logError: (message: string | Error, cause?: unknown) => void;\n readonly options: ClientOptions;\n}) {\n const identityTrustDomain = resolveIdentityTrustDomain({\n apiBaseUrl: input.apiBaseUrl,\n identityTrustDomain: input.options.identityTrustDomain,\n });\n return {\n identityTrustDomain,\n service: createSecurityIncidentService({\n database: input.database,\n logError: input.logError,\n onIncident: input.options.onSecurityIncident,\n trustDomain: identityTrustDomain,\n }),\n };\n}\n\nexport type ClientDatabaseOptions = Omit<DatabaseOptions, \"status\">;\n\nexport interface ClientOptions {\n apiBaseUrl?: string | undefined;\n /** Reuse a memory-only request counter across client lifetimes. */\n apiRequestMetrics?: ApiRequestMetrics | undefined;\n blobStore?: BlobStore | undefined;\n blobStoreFactory?: BlobStoreFactory | undefined;\n database?: ClientDatabaseOptions | undefined;\n documentProjectors?: DocumentProjectorRegistryInput | undefined;\n events?: ReadonlyArray<unknown> | undefined;\n identity?: IdentityOptions | undefined;\n /**\n * Absolute, host-controlled API namespace for durable user-identity pins.\n * Required only when apiBaseUrl is relative and no browser origin exists.\n */\n identityTrustDomain?: string | undefined;\n identityProvisioning?: \"auto\" | \"manual\" | undefined;\n logger?: Logger | undefined;\n online?: boolean | undefined;\n /** Called after a trust-boundary verification failure is durably recorded. */\n onSecurityIncident?: SecurityIncidentListener | undefined;\n /**\n * Per-pane discriminator so documents in distinct panes derive distinct Loro\n * peer ids (e.g. the pane's local identity namespace). Omit for single-pane.\n */\n peerScope?: string | undefined;\n /** Private host key for durable history progress; omitted uses disposable session keys. */\n principalHistoryKeyProvider?: PrincipalHistoryKeyProvider | undefined;\n /** Compound policy dispatch/recovery deadline in milliseconds; defaults to 60 seconds. */\n principalMutationTimeoutMs?: number | undefined;\n /**\n * App-owned system containers born with every new organization (both\n * registration and additional-org creation provision them atomically in the\n * same server call), e.g. a trash bin. The app owns these because their slot\n * namespaces are app concepts the SDK stays agnostic to.\n */\n provisionedSystemContainers?:\n | ReadonlyArray<ProvisionedSystemContainerSpec>\n | undefined;\n}\n\nexport class Tearleads {\n readonly apiVersion = new ApiVersion();\n readonly apiRequests: ApiRequestMetrics;\n readonly blobs: Blobs;\n readonly database: Database;\n readonly deviceFirst: DeviceFirst;\n readonly documents: Documents;\n readonly events: Events;\n readonly containerContents: ContainerContents;\n readonly identity: Identity;\n readonly network: Network;\n readonly organizations: Organizations;\n readonly root: Root;\n readonly runtime: Runtime;\n readonly securityIncidents: SecurityIncidents;\n readonly session: Session;\n readonly syncBillingGate: SyncBillingGate;\n readonly userIdentities: UserIdentities;\n\n private readonly apiClient: ApiClient;\n private readonly documentProjectors: DocumentProjectorRegistry;\n private readonly disposeSecurityIncidents: () => void;\n private retirePrincipalHistoryProtection = () => {};\n // Tracks the storage/identity pair that owns domain-scoped runtime state.\n private domainScopeKey: string | null = null;\n // Recreated when the storage database or signing identity changes.\n private domainScopeValue: DomainScope = createDomainScope();\n private readonly logErrorHandler: (\n message: string | Error,\n cause?: unknown,\n ) => void;\n private readonly logHandler: (message: string) => void;\n private autoIdentityProvisioned = false;\n private autoIdentityProvisioningPromise: Promise<void> | null = null;\n private expiredSessionLoginPromise: Promise<boolean> | null = null;\n // Rebound to the workflow runtime once it exists; the session is created first.\n private pinLocalUserIdentity: InternalRuntime[\"pinLocalUserIdentity\"] =\n async () => {\n throw new Error(\"Trusted user identity runtime is not initialized\");\n };\n private boundUserId: InternalRuntime[\"boundUserId\"] = async () => {\n throw new Error(\"Trusted user identity runtime is not initialized\");\n };\n\n constructor(options: ClientOptions = {}) {\n const apiBaseUrl = options.apiBaseUrl ?? \"\";\n this.apiRequests = options.apiRequestMetrics ?? new ApiRequestMetrics();\n this.apiClient = this.createApiClient(apiBaseUrl);\n this.blobs = new Blobs(options.blobStore, options.blobStoreFactory);\n this.database = new Database(options.database);\n this.documentProjectors = resolveDocumentProjectorRegistry(\n options.documentProjectors,\n );\n this.events = new Events(options.events, () =>\n this.apiClient.clearWriterProjectionCaches(),\n );\n this.logHandler = options.logger?.log ?? (() => undefined);\n this.logErrorHandler = options.logger?.logError ?? logErrorToConsole;\n const security = createClientSecurityIncidentService({\n apiBaseUrl,\n database: this.database,\n logError: this.logError,\n options,\n });\n this.securityIncidents = security.service.incidents;\n this.disposeSecurityIncidents = security.service.dispose;\n this.network = new Network(options.online);\n this.syncBillingGate = new SyncBillingGate();\n let session: Session | null = null;\n this.identity = createIdentity(\n options.identity,\n (signingFingerprint) =>\n this.blobs.updateIdentityNamespace(signingFingerprint),\n this.log,\n {\n bootstrapLocalRootContainer: async () => {\n if (this.database.status !== \"ready\") {\n throw new Error(\n \"identity.generate requires a ready SQLite database.\",\n );\n }\n if (!session) {\n throw new Error(\n \"identity.generate requires an initialized session.\",\n );\n }\n\n return session.bootstrapLocalRootContainer();\n },\n getUserId: () => session?.userId ?? null,\n },\n );\n session = createSession({\n api: this.apiClient,\n database: this.database,\n documentProjectors: this.documentProjectors,\n identity: this.identity,\n log: this.log,\n logError: this.logError,\n boundUserIdForSigningKey: (signingKeyFingerprint) =>\n this.boundUserId(signingKeyFingerprint),\n onUserIdentityAvailable: (userId, candidate) =>\n this.pinLocalUserIdentity(userId, candidate),\n provisionedSystemContainers: options.provisionedSystemContainers,\n reportSecurityIncident: security.service.report,\n });\n this.session = session;\n const runtime = this.createWorkflowRuntime(\n security.identityTrustDomain,\n options,\n security.service.report,\n );\n this.bindTrustedIdentityRuntime(runtime);\n this.runtime = runtime.publicRuntime;\n this.documents = createDocuments({\n getDefaultContainerId: () => this.session.containerId,\n runtime,\n });\n this.containerContents = createContainerContents(runtime);\n this.deviceFirst = createDeviceFirst(runtime, this.containerContents);\n this.organizations = createOrganizations(runtime, this.containerContents);\n this.root = createRoot(rootRuntimeOf(runtime, this.session));\n this.userIdentities = createUserIdentities({\n log: this.log,\n resolveTrustedUserIdentity: (userId) =>\n runtime.workflowInput().resolveTrustedUserIdentity(userId),\n });\n\n this.configureApiClientCallbacks();\n\n if (options.identityProvisioning === \"auto\") {\n this.startAutomaticIdentityProvisioning();\n }\n }\n\n private createApiClient(apiBaseUrl: string): ApiClient {\n return new ApiClient(apiBaseUrl, {\n metrics: this.apiRequests,\n getIdentity: () => this.identity.signingFingerprint,\n });\n }\n\n /** Rebinds the session's trust callbacks once the runtime exists. */\n private bindTrustedIdentityRuntime(runtime: InternalRuntime): void {\n this.retirePrincipalHistoryProtection =\n runtime.retirePrincipalHistoryProtection;\n this.pinLocalUserIdentity = (userId, candidate) =>\n runtime.pinLocalUserIdentity(userId, candidate);\n this.boundUserId = (signingKeyFingerprint) =>\n runtime.boundUserId(signingKeyFingerprint);\n }\n\n private configureApiClientCallbacks(): void {\n this.apiClient.setOnError((message) => this.logError(message));\n // An authoritative host source owns connectivity. Without one, request\n // outcomes remain reachability hints. Browser and native app bindings both\n // install authoritative sources so a backend outage cannot stop retries.\n this.apiClient.setOnNetworkError(() =>\n this.network.reportReachability(false),\n );\n this.apiClient.setOnNetworkSuccess(() =>\n this.network.reportReachability(true),\n );\n this.apiClient.setOnApiVersion((version) =>\n this.apiVersion.observe(version),\n );\n this.apiClient.setOnSessionExpired(() => this.loginAfterSessionExpired());\n this.apiClient.setOnPaymentRequired((organizationId) =>\n this.syncBillingGate.notifyPaymentRequired(organizationId),\n );\n }\n\n private createWorkflowRuntime(\n identityTrustDomain: string | null,\n options: ClientOptions,\n reportSecurityIncident: SecurityIncidentReporter,\n ): InternalRuntime {\n return createRuntime({\n api: this.apiClient,\n blobs: this.blobs,\n database: this.database,\n documentProjectors: this.documentProjectors,\n events: this.events,\n getDomainScope: () => this.domainScope,\n identity: this.identity,\n identityTrustDomain,\n log: this.log,\n logError: this.logError,\n network: this.network,\n peerScope: options.peerScope ?? null,\n principalHistoryKeyProvider: options.principalHistoryKeyProvider,\n principalMutationTimeoutMs: options.principalMutationTimeoutMs,\n reportSecurityIncident,\n session: this.session,\n syncBillingGate: this.syncBillingGate,\n });\n }\n\n log = (message: string): void => {\n this.logHandler(message);\n };\n\n // Preserve the host's return value so best-effort callers can also catch\n // rejected promises from async loggers accepted by the void callback type.\n logError = (message: string | Error, cause?: unknown): void =>\n this.logErrorHandler(message, cause);\n\n /**\n * Mint a single-use ticket to authenticate the server-events websocket\n * handshake (which cannot carry the bearer header). Returns null when no\n * session is active. The caller appends it to the websocket URL.\n */\n requestWebSocketTicket(): Promise<string | null> {\n return this.apiClient.requestWebSocketTicket();\n }\n\n get domainScope(): DomainScope {\n const nextScopeKey = JSON.stringify([\n this.database.id,\n this.identity.signingFingerprint,\n ]);\n if (this.domainScopeKey !== nextScopeKey) {\n this.domainScopeKey = nextScopeKey;\n this.domainScopeValue = createDomainScope();\n }\n\n return this.domainScopeValue;\n }\n\n /**\n * Tear down background work for the active domain scope: stop the reconciler\n * and force-stop the sync coordinator pump, then drop the coordinator from\n * its registry. Hosts call this from unmount/cleanup so a pump cannot outlive\n * the React tree that created it. A later access for the same scope rebuilds\n * fresh state.\n */\n dispose(): void {\n const domainScope = this.domainScope;\n this.disposeSecurityIncidents();\n this.retirePrincipalHistoryProtection();\n this.deviceFirst.dispose();\n disposeDomainSyncCoordinator(domainScope);\n }\n\n private loginAfterSessionExpired(): Promise<boolean> {\n if (!this.session.authToken || !this.identity.signingKeyPair) {\n this.session.logout();\n return Promise.resolve(false);\n }\n\n // The API client replays requests the expired session sent, so a login is\n // their renewal only when the loaded keys authenticate that known user.\n const expiredUserId = this.session.userId;\n this.expiredSessionLoginPromise ??= this.session\n .login()\n .then(\n (renewed) =>\n renewed &&\n expiredUserId !== null &&\n this.session.userId === expiredUserId,\n )\n .finally(() => {\n this.expiredSessionLoginPromise = null;\n });\n return this.expiredSessionLoginPromise;\n }\n\n private startAutomaticIdentityProvisioning(): void {\n let unsubscribe: (() => void) | null = null;\n const stopProvisioningListener = () => {\n unsubscribe?.();\n unsubscribe = null;\n };\n const maybeProvisionIdentity = () => {\n if (this.autoIdentityProvisioned || this.identity.signingKeyPair) {\n stopProvisioningListener();\n return;\n }\n\n if (\n this.autoIdentityProvisioningPromise ||\n this.database.status !== \"ready\"\n ) {\n return;\n }\n\n this.autoIdentityProvisioningPromise = this.identity\n .generate()\n .then(() => {\n this.autoIdentityProvisioned = true;\n stopProvisioningListener();\n })\n .catch((error: unknown) => {\n try {\n this.logError(\"Automatic identity provisioning failed\", error);\n } catch {\n // Keep background provisioning failures from surfacing as unhandled rejections.\n }\n })\n .finally(() => {\n this.autoIdentityProvisioningPromise = null;\n });\n };\n\n unsubscribe = this.database.subscribe(maybeProvisionIdentity);\n void Promise.resolve().then(maybeProvisionIdentity);\n }\n}\n"]}
1
+ {"version":3,"file":"Tearleads.js","sourceRoot":"","sources":["Tearleads.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiClient, ApiRequestMetrics } from \"@tearleads/api-client\";\nimport type { BlobStore } from \"../data/blobContracts\";\nimport {\n type DocumentProjectorRegistry,\n type DocumentProjectorRegistryInput,\n resolveDocumentProjectorRegistry,\n} from \"../data/documents/documentKinds\";\nimport { createDomainScope, type DomainScope } from \"../data/domainScope\";\nimport type { SecurityIncidentReporter } from \"../data/securityIncidents\";\nimport { disposeDomainSyncCoordinator } from \"../data/sync/syncCoordinator\";\nimport { resolveIdentityTrustDomain } from \"../data/trustedUserIdentity\";\nimport type { ProvisionedSystemContainerSpec } from \"../workflows/registration\";\nimport { ApiVersion } from \"./apiVersion\";\nimport { type BlobStoreFactory, Blobs } from \"./blobs\";\nimport {\n type ContainerContents,\n createContainerContents,\n} from \"./containerContents\";\nimport { Database, type DatabaseOptions } from \"./database\";\nimport { createDeviceFirst, type DeviceFirst } from \"./deviceFirst\";\nimport { createDocuments, type Documents } from \"./documents\";\nimport { Events } from \"./events\";\nimport {\n createIdentity,\n type Identity,\n type IdentityOptions,\n} from \"./identity\";\nimport { type Logger, logErrorToConsole } from \"./logger\";\nimport { Network } from \"./network\";\nimport { createOrganizations, type Organizations } from \"./organizations\";\nimport type { PrincipalHistoryKeyProvider } from \"./principalHistoryProtection\";\nimport { createRoot, type Root, rootRuntimeOf } from \"./root\";\nimport {\n createSecurityIncidentService,\n type SecurityIncidentListener,\n type SecurityIncidents,\n} from \"./securityIncidents\";\nimport { createSession } from \"./session\";\nimport type { Session } from \"./session/sessionTypes\";\nimport { SyncBillingGate } from \"./syncBillingGate\";\nimport { createUserIdentities, type UserIdentities } from \"./userIdentities\";\nimport {\n createRuntime,\n type InternalRuntime,\n type Runtime,\n} from \"./workflowRuntime\";\n\nfunction createClientSecurityIncidentService(input: {\n readonly apiBaseUrl: string;\n readonly database: Database;\n readonly logError: (message: string | Error, cause?: unknown) => void;\n readonly options: ClientOptions;\n}) {\n const identityTrustDomain = resolveIdentityTrustDomain({\n apiBaseUrl: input.apiBaseUrl,\n identityTrustDomain: input.options.identityTrustDomain,\n });\n return {\n identityTrustDomain,\n service: createSecurityIncidentService({\n database: input.database,\n logError: input.logError,\n onIncident: input.options.onSecurityIncident,\n trustDomain: identityTrustDomain,\n }),\n };\n}\n\nexport type ClientDatabaseOptions = Omit<DatabaseOptions, \"status\">;\n\nexport interface ClientOptions {\n apiBaseUrl?: string | undefined;\n /** Reuse a memory-only request counter across client lifetimes. */\n apiRequestMetrics?: ApiRequestMetrics | undefined;\n blobStore?: BlobStore | undefined;\n blobStoreFactory?: BlobStoreFactory | undefined;\n database?: ClientDatabaseOptions | undefined;\n documentProjectors?: DocumentProjectorRegistryInput | undefined;\n events?: ReadonlyArray<unknown> | undefined;\n identity?: IdentityOptions | undefined;\n /**\n * Absolute, host-controlled API namespace for durable user-identity pins.\n * Required only when apiBaseUrl is relative and no browser origin exists.\n */\n identityTrustDomain?: string | undefined;\n identityProvisioning?: \"auto\" | \"manual\" | undefined;\n logger?: Logger | undefined;\n online?: boolean | undefined;\n /** Called after a trust-boundary verification failure is durably recorded. */\n onSecurityIncident?: SecurityIncidentListener | undefined;\n /**\n * Per-pane discriminator so documents in distinct panes derive distinct Loro\n * peer ids (e.g. the pane's local identity namespace). Omit for single-pane.\n */\n peerScope?: string | undefined;\n /** Private host key for durable history progress; omitted uses disposable session keys. */\n principalHistoryKeyProvider?: PrincipalHistoryKeyProvider | undefined;\n /** Compound policy dispatch/recovery deadline in milliseconds; defaults to 60 seconds. */\n principalMutationTimeoutMs?: number | undefined;\n /**\n * App-owned system containers born with every new organization (both\n * registration and additional-org creation provision them atomically in the\n * same server call), e.g. a trash bin. The app owns these because their slot\n * namespaces are app concepts the SDK stays agnostic to.\n */\n provisionedSystemContainers?:\n | ReadonlyArray<ProvisionedSystemContainerSpec>\n | undefined;\n}\n\nexport class Tearleads {\n readonly apiVersion = new ApiVersion();\n readonly apiRequests: ApiRequestMetrics;\n readonly blobs: Blobs;\n readonly database: Database;\n readonly deviceFirst: DeviceFirst;\n readonly documents: Documents;\n readonly events: Events;\n readonly containerContents: ContainerContents;\n readonly identity: Identity;\n readonly network: Network;\n readonly organizations: Organizations;\n readonly root: Root;\n readonly runtime: Runtime;\n readonly securityIncidents: SecurityIncidents;\n readonly session: Session;\n readonly syncBillingGate: SyncBillingGate;\n readonly userIdentities: UserIdentities;\n\n private readonly apiClient: ApiClient;\n private readonly documentProjectors: DocumentProjectorRegistry;\n private readonly disposeSecurityIncidents: () => void;\n private retirePrincipalHistoryProtection = () => {};\n // Tracks the storage/identity pair that owns domain-scoped runtime state.\n private domainScopeKey: string | null = null;\n // Recreated when the storage database or signing identity changes.\n private domainScopeValue: DomainScope = createDomainScope();\n private readonly logErrorHandler: (\n message: string | Error,\n cause?: unknown,\n ) => void;\n private readonly logHandler: (message: string) => void;\n private autoIdentityProvisioned = false;\n private autoIdentityProvisioningPromise: Promise<void> | null = null;\n private expiredSessionLoginPromise: Promise<boolean> | null = null;\n // Rebound to the workflow runtime once it exists; the session is created first.\n private pinLocalUserIdentity: InternalRuntime[\"pinLocalUserIdentity\"] =\n async () => {\n throw new Error(\"Trusted user identity runtime is not initialized\");\n };\n private boundUserId: InternalRuntime[\"boundUserId\"] = async () => {\n throw new Error(\"Trusted user identity runtime is not initialized\");\n };\n\n constructor(options: ClientOptions = {}) {\n const apiBaseUrl = options.apiBaseUrl ?? \"\";\n this.apiRequests = options.apiRequestMetrics ?? new ApiRequestMetrics();\n this.apiClient = this.createApiClient(apiBaseUrl);\n this.blobs = new Blobs(options.blobStore, options.blobStoreFactory);\n this.database = new Database(options.database);\n this.documentProjectors = resolveDocumentProjectorRegistry(\n options.documentProjectors,\n );\n this.events = new Events(options.events, () =>\n this.apiClient.clearWriterProjectionCaches(),\n );\n this.logHandler = options.logger?.log ?? (() => undefined);\n this.logErrorHandler = options.logger?.logError ?? logErrorToConsole;\n const security = createClientSecurityIncidentService({\n apiBaseUrl,\n database: this.database,\n logError: this.logError,\n options,\n });\n this.securityIncidents = security.service.incidents;\n this.disposeSecurityIncidents = security.service.dispose;\n this.network = new Network(options.online);\n this.syncBillingGate = new SyncBillingGate();\n let session: Session | null = null;\n this.identity = createIdentity(\n options.identity,\n (signingFingerprint) =>\n this.blobs.updateIdentityNamespace(signingFingerprint),\n this.log,\n {\n bootstrapLocalRootContainer: async () => {\n if (this.database.status !== \"ready\") {\n throw new Error(\n \"identity.generate requires a ready SQLite database.\",\n );\n }\n if (!session) {\n throw new Error(\n \"identity.generate requires an initialized session.\",\n );\n }\n\n return session.bootstrapLocalRootContainer();\n },\n getUserId: () => session?.userId ?? null,\n },\n );\n session = createSession({\n api: this.apiClient,\n database: this.database,\n documentProjectors: this.documentProjectors,\n identity: this.identity,\n log: this.log,\n logError: this.logError,\n boundUserIdForSigningKey: (signingKeyFingerprint) =>\n this.boundUserId(signingKeyFingerprint),\n onUserIdentityAvailable: (userId, candidate) =>\n this.pinLocalUserIdentity(userId, candidate),\n provisionedSystemContainers: options.provisionedSystemContainers,\n reportSecurityIncident: security.service.report,\n });\n this.session = session;\n const runtime = this.createWorkflowRuntime(\n security.identityTrustDomain,\n options,\n security.service.report,\n );\n this.bindTrustedIdentityRuntime(runtime);\n this.runtime = runtime.publicRuntime;\n this.documents = createDocuments({\n getDefaultContainerId: () => this.session.containerId,\n runtime,\n });\n this.containerContents = createContainerContents(runtime);\n this.deviceFirst = createDeviceFirst(runtime, this.containerContents);\n this.organizations = createOrganizations(runtime, this.containerContents);\n this.root = createRoot(rootRuntimeOf(runtime, this.session));\n this.userIdentities = createUserIdentities({\n log: this.log,\n resolveTrustedUserIdentity: (userId) =>\n runtime.workflowInput().resolveTrustedUserIdentity(userId),\n });\n\n this.configureApiClientCallbacks();\n\n if (options.identityProvisioning === \"auto\") {\n this.startAutomaticIdentityProvisioning();\n }\n }\n\n private createApiClient(apiBaseUrl: string): ApiClient {\n return new ApiClient(apiBaseUrl, {\n metrics: this.apiRequests,\n getIdentity: () => this.identity.signingFingerprint,\n });\n }\n\n /** Rebinds the session's trust callbacks once the runtime exists. */\n private bindTrustedIdentityRuntime(runtime: InternalRuntime): void {\n this.retirePrincipalHistoryProtection =\n runtime.retirePrincipalHistoryProtection;\n this.pinLocalUserIdentity = (userId, candidate) =>\n runtime.pinLocalUserIdentity(userId, candidate);\n this.boundUserId = (signingKeyFingerprint) =>\n runtime.boundUserId(signingKeyFingerprint);\n }\n\n private configureApiClientCallbacks(): void {\n this.apiClient.setOnError((message) => this.logError(message));\n // An authoritative host source owns connectivity. Without one, request\n // outcomes remain reachability hints. Browser and native app bindings both\n // install authoritative sources so a backend outage cannot stop retries.\n this.apiClient.setOnNetworkError(() =>\n this.network.reportReachability(false),\n );\n this.apiClient.setOnNetworkSuccess(() =>\n this.network.reportReachability(true),\n );\n this.apiClient.setOnApiVersion((version) =>\n this.apiVersion.observe(version),\n );\n this.apiClient.setOnSessionExpired(() => this.loginAfterSessionExpired());\n this.apiClient.setOnPaymentRequired((organizationId) =>\n this.syncBillingGate.notifyPaymentRequired(organizationId),\n );\n }\n\n private createWorkflowRuntime(\n identityTrustDomain: string | null,\n options: ClientOptions,\n reportSecurityIncident: SecurityIncidentReporter,\n ): InternalRuntime {\n return createRuntime({\n api: this.apiClient,\n blobs: this.blobs,\n database: this.database,\n documentProjectors: this.documentProjectors,\n events: this.events,\n getDomainScope: () => this.domainScope,\n identity: this.identity,\n identityTrustDomain,\n log: this.log,\n logError: this.logError,\n network: this.network,\n peerScope: options.peerScope ?? null,\n principalHistoryKeyProvider: options.principalHistoryKeyProvider,\n principalMutationTimeoutMs: options.principalMutationTimeoutMs,\n reportSecurityIncident,\n session: this.session,\n syncBillingGate: this.syncBillingGate,\n });\n }\n\n log = (message: string): void => {\n this.logHandler(message);\n };\n\n // Preserve the host's return value so best-effort callers can also catch\n // rejected promises from async loggers accepted by the void callback type.\n logError = (message: string | Error, cause?: unknown): void =>\n this.logErrorHandler(message, cause);\n\n /**\n * A single-use ticket to authenticate the server-events websocket handshake\n * (which cannot carry the bearer header): the one login returned for the\n * first connect of that session, otherwise a freshly minted one. Returns\n * null when no session is active. The caller appends it to the websocket URL.\n */\n requestWebSocketTicket(): Promise<string | null> {\n return this.apiClient.requestWebSocketTicket();\n }\n\n get domainScope(): DomainScope {\n const nextScopeKey = JSON.stringify([\n this.database.id,\n this.identity.signingFingerprint,\n ]);\n if (this.domainScopeKey !== nextScopeKey) {\n this.domainScopeKey = nextScopeKey;\n this.domainScopeValue = createDomainScope();\n }\n\n return this.domainScopeValue;\n }\n\n /**\n * Tear down background work for the active domain scope: stop the reconciler\n * and force-stop the sync coordinator pump, then drop the coordinator from\n * its registry. Hosts call this from unmount/cleanup so a pump cannot outlive\n * the React tree that created it. A later access for the same scope rebuilds\n * fresh state.\n */\n dispose(): void {\n const domainScope = this.domainScope;\n this.disposeSecurityIncidents();\n this.retirePrincipalHistoryProtection();\n this.deviceFirst.dispose();\n disposeDomainSyncCoordinator(domainScope);\n }\n\n private loginAfterSessionExpired(): Promise<boolean> {\n if (!this.session.authToken || !this.identity.signingKeyPair) {\n this.session.logout();\n return Promise.resolve(false);\n }\n\n // The API client replays requests the expired session sent, so a login is\n // their renewal only when the loaded keys authenticate that known user.\n const expiredUserId = this.session.userId;\n this.expiredSessionLoginPromise ??= this.session\n .login()\n .then(\n (renewed) =>\n renewed &&\n expiredUserId !== null &&\n this.session.userId === expiredUserId,\n )\n .finally(() => {\n this.expiredSessionLoginPromise = null;\n });\n return this.expiredSessionLoginPromise;\n }\n\n private startAutomaticIdentityProvisioning(): void {\n let unsubscribe: (() => void) | null = null;\n const stopProvisioningListener = () => {\n unsubscribe?.();\n unsubscribe = null;\n };\n const maybeProvisionIdentity = () => {\n if (this.autoIdentityProvisioned || this.identity.signingKeyPair) {\n stopProvisioningListener();\n return;\n }\n\n if (\n this.autoIdentityProvisioningPromise ||\n this.database.status !== \"ready\"\n ) {\n return;\n }\n\n this.autoIdentityProvisioningPromise = this.identity\n .generate()\n .then(() => {\n this.autoIdentityProvisioned = true;\n stopProvisioningListener();\n })\n .catch((error: unknown) => {\n try {\n this.logError(\"Automatic identity provisioning failed\", error);\n } catch {\n // Keep background provisioning failures from surfacing as unhandled rejections.\n }\n })\n .finally(() => {\n this.autoIdentityProvisioningPromise = null;\n });\n };\n\n unsubscribe = this.database.subscribe(maybeProvisionIdentity);\n void Promise.resolve().then(maybeProvisionIdentity);\n }\n}\n"]}
@@ -29,7 +29,7 @@ export async function loadBoundedOrganizationGroupHistory(input) {
29
29
  ? {}
30
30
  : { beforeVersion: input.beforeVersion },
31
31
  });
32
- assertProjectionVerificationCurrent(input.stillCurrent);
32
+ assertProjectionVerificationCurrent(resolved.stillCurrent);
33
33
  if (!resolved.historyPage)
34
34
  throw new Error("Verified history page is missing");
35
35
  return buildOrganizationGroupPolicyHistoryPage({
@@ -1 +1 @@
1
- {"version":3,"file":"organizationGroupHistory.js","sourceRoot":"","sources":["organizationGroupHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,uCAAuC,EAAE,MAAM,sDAAsD,CAAC;AAC/G,OAAO,EAAE,2CAA2C,EAAE,MAAM,kDAAkD,CAAC;AAG/G,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,KAKzD;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,2CAA2C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5E,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,oCAAoC,CAC5C,+CAA+C,CAChD,CAAC;IACJ,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,oCAAoC,CAAC;QAC3D,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW,EAAE,KAAK,CAAC,OAAO;QAC1B,aAAa,EAAE,OAAO;KACvB,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS;QACT,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,WAAW,EACT,KAAK,CAAC,aAAa,KAAK,SAAS;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;KAC7C,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,CAAC,WAAW;QACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,OAAO,uCAAuC,CAAC;QAC7C,IAAI,EAAE,QAAQ,CAAC,WAAW;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { loadLocalOrganizationPolicyReference } from \"../../workflows/organizations\";\nimport { buildOrganizationGroupPolicyHistoryPage } from \"../../workflows/organizations/groupPolicyHistoryPage\";\nimport { createRuntimePrincipalPolicyCurrentResolver } from \"../../workflows/principals/runtimePolicyRecovery\";\nimport type { ActiveOrganizationDataRuntime } from \"./organizationWorkflowRuntime\";\n\n/** All group history reads use the private paged verifier. */\nexport async function loadBoundedOrganizationGroupHistory(input: {\n readonly active: ActiveOrganizationDataRuntime;\n readonly groupId: string;\n readonly beforeVersion?: number | undefined;\n readonly stillCurrent: () => boolean;\n}) {\n const { active } = input;\n const resolve = createRuntimePrincipalPolicyCurrentResolver(active.runtime);\n if (!resolve)\n throw new ProjectionDependencyUnavailableError(\n \"Group history requires private paged recovery\",\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n const reference = await loadLocalOrganizationPolicyReference({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n principalId: input.groupId,\n principalType: \"group\",\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!reference) return null;\n const resolved = await resolve({\n organizationId: active.organizationId,\n reference,\n preferLocalCurrent: true,\n stillCurrent: input.stillCurrent,\n historyPage:\n input.beforeVersion === undefined\n ? {}\n : { beforeVersion: input.beforeVersion },\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!resolved.historyPage)\n throw new Error(\"Verified history page is missing\");\n return buildOrganizationGroupPolicyHistoryPage({\n page: resolved.historyPage,\n groupId: input.groupId,\n organizationId: active.organizationId,\n });\n}\n"]}
1
+ {"version":3,"file":"organizationGroupHistory.js","sourceRoot":"","sources":["organizationGroupHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,uCAAuC,EAAE,MAAM,sDAAsD,CAAC;AAC/G,OAAO,EAAE,2CAA2C,EAAE,MAAM,kDAAkD,CAAC;AAG/G,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,KAKzD;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,2CAA2C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5E,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,oCAAoC,CAC5C,+CAA+C,CAChD,CAAC;IACJ,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,oCAAoC,CAAC;QAC3D,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW,EAAE,KAAK,CAAC,OAAO;QAC1B,aAAa,EAAE,OAAO;KACvB,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS;QACT,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,WAAW,EACT,KAAK,CAAC,aAAa,KAAK,SAAS;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;KAC7C,CAAC,CAAC;IACH,mCAAmC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC,QAAQ,CAAC,WAAW;QACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,OAAO,uCAAuC,CAAC;QAC7C,IAAI,EAAE,QAAQ,CAAC,WAAW;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { loadLocalOrganizationPolicyReference } from \"../../workflows/organizations\";\nimport { buildOrganizationGroupPolicyHistoryPage } from \"../../workflows/organizations/groupPolicyHistoryPage\";\nimport { createRuntimePrincipalPolicyCurrentResolver } from \"../../workflows/principals/runtimePolicyRecovery\";\nimport type { ActiveOrganizationDataRuntime } from \"./organizationWorkflowRuntime\";\n\n/** All group history reads use the private paged verifier. */\nexport async function loadBoundedOrganizationGroupHistory(input: {\n readonly active: ActiveOrganizationDataRuntime;\n readonly groupId: string;\n readonly beforeVersion?: number | undefined;\n readonly stillCurrent: () => boolean;\n}) {\n const { active } = input;\n const resolve = createRuntimePrincipalPolicyCurrentResolver(active.runtime);\n if (!resolve)\n throw new ProjectionDependencyUnavailableError(\n \"Group history requires private paged recovery\",\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n const reference = await loadLocalOrganizationPolicyReference({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n principalId: input.groupId,\n principalType: \"group\",\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!reference) return null;\n const resolved = await resolve({\n organizationId: active.organizationId,\n reference,\n preferLocalCurrent: true,\n stillCurrent: input.stillCurrent,\n historyPage:\n input.beforeVersion === undefined\n ? {}\n : { beforeVersion: input.beforeVersion },\n });\n assertProjectionVerificationCurrent(resolved.stillCurrent);\n if (!resolved.historyPage)\n throw new Error(\"Verified history page is missing\");\n return buildOrganizationGroupPolicyHistoryPage({\n page: resolved.historyPage,\n groupId: input.groupId,\n organizationId: active.organizationId,\n });\n}\n"]}
@@ -31,7 +31,7 @@ export async function loadBoundedOrganizationHistory(input) {
31
31
  ? {}
32
32
  : { beforeVersion: input.beforeVersion },
33
33
  });
34
- assertProjectionVerificationCurrent(stillCurrent);
34
+ assertProjectionVerificationCurrent(resolved.stillCurrent);
35
35
  const page = resolved.historyPage;
36
36
  if (!page)
37
37
  throw new Error("Verified organization history page is missing");
@@ -1 +1 @@
1
- {"version":3,"file":"organizationHistory.js","sourceRoot":"","sources":["organizationHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,uCAAuC,EAAE,MAAM,sDAAsD,CAAC;AAC/G,OAAO,EAAE,wBAAwB,EAAE,MAAM,wDAAwD,CAAC;AAClG,OAAO,EAAE,2CAA2C,EAAE,MAAM,kDAAkD,CAAC;AAC/G,OAAO,EAAE,qCAAqC,EAAE,MAAM,4DAA4D,CAAC;AAGnH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAIpD;IACC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IACvC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC3B,MAAM,OAAO,GAAG,2CAA2C,CAAC,OAAO,CAAC,CAAC;IACrE,MAAM,cAAc,GAAG,qCAAqC,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc;QAC7B,MAAM,IAAI,oCAAoC,CAC5C,sDAAsD,CACvD,CAAC;IACJ,MAAM,SAAS,GAAG,MAAM,oCAAoC,CAAC;QAC3D,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;QAC9B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW,EAAE,MAAM,CAAC,cAAc;QAClC,aAAa,EAAE,cAAc;KAC9B,CAAC,CAAC;IACH,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS;QACT,kBAAkB,EAAE,IAAI;QACxB,YAAY;QACZ,WAAW,EACT,KAAK,CAAC,aAAa,KAAK,SAAS;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;KAC7C,CAAC,CAAC;IACH,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC;IAClC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,uCAAuC,CAAC;QACpD,IAAI;QACJ,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,OAAO,EAAE,MAAM,CAAC,cAAc;KAC/B,CAAC,CAAC;IACH,OAAO,wBAAwB,CAAC;QAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW;QACtC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;QAC9B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,SAAS;QACf,IAAI;QACJ,OAAO,EAAE;YACP,WAAW,EAAE,MAAM,CAAC,cAAc;YAClC,aAAa,EAAE,cAAc;YAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;SAC1E;QACD,cAAc;QACd,YAAY;QACZ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;QAC5B,SAAS,EAAE,KAAK,CAAC,aAAa,KAAK,SAAS;QAC5C,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ;QAC/B,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB;KAC5D,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { loadLocalOrganizationPolicyReference } from \"../../workflows/organizations\";\nimport { buildOrganizationGroupPolicyHistoryPage } from \"../../workflows/organizations/groupPolicyHistoryPage\";\nimport { loadPolicyHistoryDetails } from \"../../workflows/organizations/loadPolicyHistoryDetails\";\nimport { createRuntimePrincipalPolicyCurrentResolver } from \"../../workflows/principals/runtimePolicyRecovery\";\nimport { createRuntimeProjectionPolicyResolver } from \"../../workflows/principals/runtimeProjectionPolicyRecovery\";\nimport type { ActiveOrganizationDataRuntime } from \"./organizationWorkflowRuntime\";\n\nexport async function loadBoundedOrganizationHistory(input: {\n readonly active: ActiveOrganizationDataRuntime;\n readonly beforeVersion?: number | undefined;\n readonly stillCurrent: () => boolean;\n}) {\n const { active, stillCurrent } = input;\n const { runtime } = active;\n const resolve = createRuntimePrincipalPolicyCurrentResolver(runtime);\n const resolveHistory = createRuntimeProjectionPolicyResolver(runtime);\n if (!resolve || !resolveHistory)\n throw new ProjectionDependencyUnavailableError(\n \"Organization history requires private paged recovery\",\n );\n const reference = await loadLocalOrganizationPolicyReference({\n currentUserId: active.userId,\n execSql: runtime.infra.execSql,\n organizationId: active.organizationId,\n principalId: active.organizationId,\n principalType: \"organization\",\n });\n assertProjectionVerificationCurrent(stillCurrent);\n if (!reference) return null;\n const resolved = await resolve({\n organizationId: active.organizationId,\n reference,\n preferLocalCurrent: true,\n stillCurrent,\n historyPage:\n input.beforeVersion === undefined\n ? {}\n : { beforeVersion: input.beforeVersion },\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const page = resolved.historyPage;\n if (!page) throw new Error(\"Verified organization history page is missing\");\n const basic = buildOrganizationGroupPolicyHistoryPage({\n page,\n organizationId: active.organizationId,\n groupId: active.organizationId,\n });\n return loadPolicyHistoryDetails({\n apiClient: runtime.apiClient,\n currentUserId: active.userId,\n domainScope: runtime.state.domainScope,\n execSql: runtime.infra.execSql,\n organizationId: active.organizationId,\n head: reference,\n page,\n history: {\n principalId: active.organizationId,\n principalType: \"organization\",\n organizationId: active.organizationId,\n nextBeforeVersion: page.nextBeforeVersion,\n entries: basic.entries.map((entry) => ({ ...entry, groupChanges: null })),\n },\n resolveHistory,\n stillCurrent,\n online: runtime.state.online,\n olderPage: input.beforeVersion !== undefined,\n logError: runtime.util.logError,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n });\n}\n"]}
1
+ {"version":3,"file":"organizationHistory.js","sourceRoot":"","sources":["organizationHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,uCAAuC,EAAE,MAAM,sDAAsD,CAAC;AAC/G,OAAO,EAAE,wBAAwB,EAAE,MAAM,wDAAwD,CAAC;AAClG,OAAO,EAAE,2CAA2C,EAAE,MAAM,kDAAkD,CAAC;AAC/G,OAAO,EAAE,qCAAqC,EAAE,MAAM,4DAA4D,CAAC;AAGnH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAIpD;IACC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;IACvC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC3B,MAAM,OAAO,GAAG,2CAA2C,CAAC,OAAO,CAAC,CAAC;IACrE,MAAM,cAAc,GAAG,qCAAqC,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc;QAC7B,MAAM,IAAI,oCAAoC,CAC5C,sDAAsD,CACvD,CAAC;IACJ,MAAM,SAAS,GAAG,MAAM,oCAAoC,CAAC;QAC3D,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;QAC9B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW,EAAE,MAAM,CAAC,cAAc;QAClC,aAAa,EAAE,cAAc;KAC9B,CAAC,CAAC;IACH,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS;QACT,kBAAkB,EAAE,IAAI;QACxB,YAAY;QACZ,WAAW,EACT,KAAK,CAAC,aAAa,KAAK,SAAS;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;KAC7C,CAAC,CAAC;IACH,mCAAmC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC;IAClC,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,uCAAuC,CAAC;QACpD,IAAI;QACJ,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,OAAO,EAAE,MAAM,CAAC,cAAc;KAC/B,CAAC,CAAC;IACH,OAAO,wBAAwB,CAAC;QAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW;QACtC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;QAC9B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,SAAS;QACf,IAAI;QACJ,OAAO,EAAE;YACP,WAAW,EAAE,MAAM,CAAC,cAAc;YAClC,aAAa,EAAE,cAAc;YAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;SAC1E;QACD,cAAc;QACd,YAAY;QACZ,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;QAC5B,SAAS,EAAE,KAAK,CAAC,aAAa,KAAK,SAAS;QAC5C,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ;QAC/B,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB;KAC5D,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { loadLocalOrganizationPolicyReference } from \"../../workflows/organizations\";\nimport { buildOrganizationGroupPolicyHistoryPage } from \"../../workflows/organizations/groupPolicyHistoryPage\";\nimport { loadPolicyHistoryDetails } from \"../../workflows/organizations/loadPolicyHistoryDetails\";\nimport { createRuntimePrincipalPolicyCurrentResolver } from \"../../workflows/principals/runtimePolicyRecovery\";\nimport { createRuntimeProjectionPolicyResolver } from \"../../workflows/principals/runtimeProjectionPolicyRecovery\";\nimport type { ActiveOrganizationDataRuntime } from \"./organizationWorkflowRuntime\";\n\nexport async function loadBoundedOrganizationHistory(input: {\n readonly active: ActiveOrganizationDataRuntime;\n readonly beforeVersion?: number | undefined;\n readonly stillCurrent: () => boolean;\n}) {\n const { active, stillCurrent } = input;\n const { runtime } = active;\n const resolve = createRuntimePrincipalPolicyCurrentResolver(runtime);\n const resolveHistory = createRuntimeProjectionPolicyResolver(runtime);\n if (!resolve || !resolveHistory)\n throw new ProjectionDependencyUnavailableError(\n \"Organization history requires private paged recovery\",\n );\n const reference = await loadLocalOrganizationPolicyReference({\n currentUserId: active.userId,\n execSql: runtime.infra.execSql,\n organizationId: active.organizationId,\n principalId: active.organizationId,\n principalType: \"organization\",\n });\n assertProjectionVerificationCurrent(stillCurrent);\n if (!reference) return null;\n const resolved = await resolve({\n organizationId: active.organizationId,\n reference,\n preferLocalCurrent: true,\n stillCurrent,\n historyPage:\n input.beforeVersion === undefined\n ? {}\n : { beforeVersion: input.beforeVersion },\n });\n assertProjectionVerificationCurrent(resolved.stillCurrent);\n const page = resolved.historyPage;\n if (!page) throw new Error(\"Verified organization history page is missing\");\n const basic = buildOrganizationGroupPolicyHistoryPage({\n page,\n organizationId: active.organizationId,\n groupId: active.organizationId,\n });\n return loadPolicyHistoryDetails({\n apiClient: runtime.apiClient,\n currentUserId: active.userId,\n domainScope: runtime.state.domainScope,\n execSql: runtime.infra.execSql,\n organizationId: active.organizationId,\n head: reference,\n page,\n history: {\n principalId: active.organizationId,\n principalType: \"organization\",\n organizationId: active.organizationId,\n nextBeforeVersion: page.nextBeforeVersion,\n entries: basic.entries.map((entry) => ({ ...entry, groupChanges: null })),\n },\n resolveHistory,\n stillCurrent,\n online: runtime.state.online,\n olderPage: input.beforeVersion !== undefined,\n logError: runtime.util.logError,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n });\n}\n"]}
@@ -238,9 +238,8 @@ export async function collectReferencedPrincipalPolicies(input) {
238
238
  assertProjectionVerificationCurrent(input.stillCurrent);
239
239
  }
240
240
  }
241
- const recoveryBatch = {};
241
+ // The warmer's operation shares one recovery view across its collections.
242
242
  return Promise.all(references.map((reference) => verifyReferencedPrincipalPolicy({
243
- recoveryBatch,
244
243
  checkpointContext: input.checkpointContext,
245
244
  organizationId: input.organizationId,
246
245
  principalPolicyCache: input.principalPolicyCache,
@@ -1 +1 @@
1
- {"version":3,"file":"principalPolicyVerification.js","sourceRoot":"","sources":["principalPolicyVerification.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAGvB,aAAa,EAEb,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,4CAA4C,CAAC;AAC3F,OAAO,EACL,kCAAkC,EAClC,sCAAsC,GACvC,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,EAAE,qCAAqC,EAAE,MAAM,oDAAoD,CAAC;AAC3G,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EACL,oCAAoC,EACpC,6BAA6B,EAC7B,4BAA4B,GAC7B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,kCAAkC,EAClC,kCAAkC,EAClC,6BAA6B,EAC7B,yDAAyD,GAC1D,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EACL,sBAAsB,GAEvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,0CAA0C,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EACL,uCAAuC,EACvC,4BAA4B,EAC5B,wCAAwC,GACzC,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAC;AAM7E,OAAO,EACL,mCAAmC,EACnC,sCAAsC,GACvC,MAAM,SAAS,CAAC;AAEjB,SAAS,6BAA6B,CACpC,SAAkC;IAElC,OAAO,GAAG,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;AACpF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IACtD,YAAY,cAAsB;QAChC,KAAK,CAAC,oBAAoB,cAAc,gBAAgB,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,UAAU,+BAA+B,CAAC,KAAc;IAC5D,OAAO,CACL,KAAK,YAAY,6BAA6B;QAC9C,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,+BAA+B,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,sCAAsC,CAAC,KAIrD;IACC,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAGlC,CAAC;IAEJ,KAAK,MAAM,KAAK,IAAI,2BAA2B,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,wBAAwB,EAAE,CAAC;QAC3E,IAAI,qBAAqB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxC,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACjE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,IAAI,oCAAoC,CAC5C,GAAG,KAAK,CAAC,KAAK,yCAAyC,KAAK,CAAC,YAAY,EAAE,CAC5E,CAAC;QACJ,CAAC;QAED,MAAM,qBAAqB,GAAG,MAAM,aAAa,CAC/C,SAAS,CAAC,gBAAgB,CAC3B,CAAC;QACF,IAAI,qBAAqB,KAAK,KAAK,CAAC,wBAAwB,EAAE,CAAC;YAC7D,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,GAAG,KAAK,CAAC,KAAK,kCAAkC,CACjD,CAAC;QACJ,CAAC;QAED,qBAAqB,CAAC,GAAG,CAAC,QAAQ,EAAE;YAClC,MAAM,EAAE,KAAK,CAAC,YAAY;YAC1B,qBAAqB;YACrB,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;SAC7C,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;AAC7C,CAAC;AASD,KAAK,UAAU,qCAAqC,CAClD,KAAmC;IAUnC,MAAM,OAAO,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC;IAChD,IAAI,MAAM,GAAG,MAAM,yBAAyB,CAC1C,OAAO,EACP,cAAc,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;IACF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,eAAe,GAAG,MAAM,6BAA6B,CACvD,OAAO,EACP,cAAc,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;IACF,IACE,CAAC,kCAAkC,CAAC,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC;QACzE,KAAK,CAAC,+BAA+B,EACrC,CAAC;QACD,MAAM,KAAK,CAAC,+BAA+B,CAAC;YAC1C,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,UAAU,EAAE,CAAC,kCAAkC,CAAC,MAAM,CAAC,CAAC;SACzD,CAAC,CAAC;QACH,MAAM,GAAG,MAAM,yBAAyB,CACtC,OAAO,EACP,cAAc,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;QACF,eAAe,GAAG,MAAM,6BAA6B,CACnD,OAAO,EACP,cAAc,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AACrC,CAAC;AAED,SAAS,+BAA+B,CACtC,MAA+B;IAE/B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACtE,IACE,OAAO,CAAC,IAAI,CACV,CAAC,KAAK,EAAE,EAAE,CACR,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;QAC7B,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAC7D,EACD,CAAC;QACD,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,6DAA6D,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,8BAA8B,CAAC,KAK7C;IACC,MAAM,WAAW,GAAG,MAAM,yBAAyB,CACjD,KAAK,CAAC,OAAO,EACb,OAAO,EACP,KAAK,CAAC,YAAY,CACnB,CAAC;IACF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IACE,CAAC,6BAA6B,CAC5B,kCAAkC,CAAC,WAAW,CAAC,EAC/C,KAAK,CAAC,YAAY,CACnB,EACD,CAAC;QACD,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,gEAAgE,CACjE,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,MAAM,6BAA6B,CACzD,KAAK,CAAC,OAAO,EACb,OAAO,EACP,KAAK,CAAC,YAAY,CACnB,CAAC;IACF,MAAM,gBAAgB,GAAG,MAAM,sCAAsC,CAAC;QACpE,MAAM,EAAE,WAAW;QACnB,KAAK,EAAE,iBAAiB,KAAK,CAAC,YAAY,EAAE;QAC5C,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,2BAA2B,CAAC;QACjD,MAAM,EAAE,WAAW;QACnB,iBAAiB,EAAE,KAAK,CAAC,YAAY;QACrC,eAAe,EAAE,eAAe;QAChC,gBAAgB;KACjB,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,QAAQ,CAAC,KAAK,CAAC;IACvB,CAAC;IACD,+BAA+B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,OAAO,QAAQ,CAAC,KAAK,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,iCAAiC,CAC9C,KAAmC;IAEnC,MAAM,kBAAkB,GAAG,MAAM,qCAAqC,CAAC,KAAK,CAAC,CAAC;IAC9E,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,MAAM,sCAAsC,CAAC;YACpE,MAAM,EAAE,kBAAkB,CAAC,MAAM;YACjC,KAAK,EAAE,uBAAuB,KAAK,CAAC,cAAc,EAAE;YACpD,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,6BAA6B,CAAC;YACnD,MAAM,EAAE,kBAAkB,CAAC,MAAM;YACjC,eAAe,EAAE,kBAAkB,CAAC,eAAe;YACnD,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,gBAAgB;SACjB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,QAAQ,CAAC,KAAK,CAAC;QACvB,CAAC;QACD,MAAM,UAAU,GAAG,oCAAoC,CACrD,kBAAkB,CAAC,MAAM,CAAC,cAAc,CAAC,UAAU,CACpD,CAAC;QACF,IAAI,UAAU,CAAC,cAAc,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;YACvD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,wDAAwD,CACzD,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,MAAM,8BAA8B,CAAC;YAC1D,YAAY,EAAE,UAAU,CAAC,YAAY;YACrC,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,OAAO;YACxC,YAAY,EAAE,4BAA4B,CACxC,UAAU,EACV,UAAU,CAAC,YAAY,CACxB;YACD,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,sBAAsB,CACpB,KAAK,CAAC,iBAAiB,EACvB,QAAQ,CAAC,KAAK,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;QACF,sBAAsB,CACpB,KAAK,CAAC,iBAAiB,EACvB,cAAc,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;QACF,OAAO,kCAAkC,CAAC,cAAc,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0CAA0C,CAAC,KAAK,CAAC,CAAC;QAClD,IAAI,KAAK,YAAY,uBAAuB,EAAE,CAAC;YAC7C,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,+BAA+B,CAAC,KAS9C;IACC,0EAA0E;IAC1E,2DAA2D;IAC3D,MAAM,SAAS,GAAG,MAAM,gCAAgC,CAAC,KAAK,CAAC,CAAC;IAChE,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,QAAQ,GAAG,4BAA4B,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC;IAChD,MAAM,eAAe,GAAG,MAAM,6BAA6B,CACzD,OAAO,EACP,KAAK,CAAC,SAAS,CAAC,aAAa,EAC7B,KAAK,CAAC,SAAS,CAAC,WAAW,CAC5B,CAAC;IACF,IAAI,YAAY,IAAI,CAAC,CAAC,iBAAiB,IAAI,YAAY,CAAC,EAAE,CAAC;QACzD,IACE,CAAC,wCAAwC,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,EACxE,CAAC;YACD,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,qEAAqE,CACtE,CAAC;QACJ,CAAC;QACD,IAAI,sCAAsC,CAAC,YAAY,EAAE,eAAe,CAAC,EAAE,CAAC;YAC1E,sBAAsB,CACpB,KAAK,CAAC,iBAAiB,EACvB,YAAY,EACZ,KAAK,CAAC,cAAc,CACrB,CAAC;YACF,OAAO,YAAY,CAAC;QACtB,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,6BAA6B,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACtE,IAAI,MAAM,GAAG,MAAM,qCAAqC,CACtD,OAAO,EACP,KAAK,CAAC,SAAS,EACf,eAAe,CAChB,CAAC;IACF,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,CAAC;QACrD,yEAAyE;QACzE,sEAAsE;QACtE,wEAAwE;QACxE,MAAM,KAAK,CAAC,+BAA+B,CAAC;YAC1C,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,UAAU,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC;SAC9B,CAAC,CAAC;QACH,MAAM,GAAG,MAAM,qCAAqC,CAClD,OAAO,EACP,KAAK,CAAC,SAAS,EACf,eAAe,CAChB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,6BAA6B,CAAC,cAAc,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,sCAAsC,CAAC;QACpE,MAAM;QACN,KAAK,EAAE,oBAAoB,cAAc,EAAE;QAC3C,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC,CAAC;IACH,MAAM,QAAQ,GACZ,MAAM,yDAAyD,CAAC;QAC9D,MAAM;QACN,iBAAiB,EAAE,KAAK,CAAC,SAAS;QAClC,qBAAqB,EAAE,GAAG,EAAE,CAC1B,iCAAiC,CAAC;YAChC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;YAC1C,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,+BAA+B,EAC7B,KAAK,CAAC,+BAA+B;SACxC,CAAC;QACJ,eAAe;QACf,gBAAgB;KACjB,CAAC,CAAC;IACL,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,QAAQ,CAAC,KAAK,CAAC;IACvB,CAAC;IAED,sBAAsB,CACpB,KAAK,CAAC,iBAAiB,EACvB,QAAQ,CAAC,KAAK,EACd,KAAK,CAAC,cAAc,CACrB,CAAC;IACF,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzD,OAAO,QAAQ,CAAC,KAAK,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CAAC,KAQxD;IACC,MAAM,+BAA+B,GACnC,sCAAsC,CACpC,KAAK,CAAC,+BAA+B,EACrC,KAAK,CAAC,YAAY,CACnB,CAAC;IACJ,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAmC,CAAC;IACpE,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACzC,gBAAgB,CAAC,GAAG,CAAC,4BAA4B,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;IAClD,2EAA2E;IAC3E,yEAAyE;IACzE,0CAA0C;IAC1C,IACE,+BAA+B;QAC/B,CAAC,+BAA+B,CAAC,gBAAgB,EACjD,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,uCAAuC,CAAC;YAC7D,OAAO,EAAE,KAAK,CAAC,iBAAiB,CAAC,OAAO;YACxC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;YAChD,UAAU;SACX,CAAC,CAAC;QACH,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACxD,MAAM,+BAA+B,CAAC;gBACpC,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,QAAQ;aACrB,CAAC,CAAC;YACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,MAAM,aAAa,GAAG,EAAE,CAAC;IACzB,OAAO,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAC3B,+BAA+B,CAAC;QAC9B,aAAa;QACb,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;QAChD,SAAS;QACT,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,+BAA+B;KAChC,CAAC,CACH,CACF,CAAC;AACJ,CAAC","sourcesContent":["import {\n KeyingVerificationError,\n type PrincipalPolicySignerPublicKey,\n type ReferencedPrincipalHead,\n toFingerprint,\n type VerifiedPrincipalPolicy,\n verifyPrincipalPolicyBundle,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { loadPrincipalPolicyCheckpoint } from \"../persistence/keyingCheckpointPersistence\";\nimport {\n principalPolicyHeadMeetsCheckpoint,\n verifiedPrincipalPolicyMeetsCheckpoint,\n} from \"../persistence/principalPolicyCheckpointSelection\";\nimport { loadPrincipalPolicyBundle } from \"../persistence/principalPolicyPersistence\";\nimport { loadPrincipalPolicyBundleForReference } from \"../persistence/principalPolicyReferencePersistence\";\nimport { principalPolicyBundleStates } from \"../principalPolicyStates\";\nimport {\n parseOrganizationAuthorityDescriptor,\n principalHeadMatchesReference,\n requireOrganizationGroupHead,\n} from \"../principals/organizationAuthorityDescriptor\";\nimport {\n organizationAdminExternalAuthority,\n principalPolicyReferenceFromBundle,\n verifyOrganizationAdminPolicy,\n verifyPrincipalPolicyBundleWithExternalOrganizationAdmins,\n} from \"../principals/principalPolicyAdminSigners\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../principals/principalPolicyEvidence\";\nimport {\n observePrincipalPolicy,\n type ProjectionCheckpointContext,\n} from \"./checkpointContext\";\nimport { ProjectionDependencyUnavailableError } from \"./dependencyUnavailable\";\nimport { rethrowProjectionVerificationBoundaryError } from \"./error\";\nimport {\n filterUncachedPrincipalPolicyReferences,\n referencedPrincipalPolicyKey,\n verifiedPrincipalPolicyContainsReference,\n} from \"./principalPolicyCache\";\nimport { resolveReferencedPrincipalPolicy } from \"./resolvedPrincipalPolicy\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"./types\";\nimport {\n assertProjectionVerificationCurrent,\n generationGuardedPrincipalPolicyWarmer,\n} from \"./types\";\n\nfunction principalPolicyReferenceLabel(\n reference: ReferencedPrincipalHead,\n): string {\n return `${reference.principalType}:${reference.principalId}@${reference.version}`;\n}\n\n/**\n * A referenced principal policy is not in the local store and warming could\n * not fetch it this pass — a transient cold-cache condition, typical for a\n * member whose access arrives via a group policy the device has not hydrated\n * yet. Sync passes discriminate on this type to defer the affected container\n * and retry on a later trigger, rather than failing the whole pass.\n */\nexport class PrincipalPolicyNotCachedError extends Error {\n constructor(referenceLabel: string) {\n super(`Principal policy ${referenceLabel} is not cached`);\n this.name = \"PrincipalPolicyNotCachedError\";\n }\n}\n\nexport function isPrincipalPolicyNotCachedError(error: unknown): boolean {\n return (\n error instanceof PrincipalPolicyNotCachedError ||\n (error instanceof Error && error.name === \"PrincipalPolicyNotCachedError\")\n );\n}\n\nasync function collectPrincipalPolicySignerPublicKeys(input: {\n bundle: PrincipalPolicyBundleResponse;\n label: string;\n resolveUserKey: ProjectionUserKeyResolver;\n}): Promise<PrincipalPolicySignerPublicKey[]> {\n const signerPublicKeysByKey = new Map<\n string,\n PrincipalPolicySignerPublicKey\n >();\n\n for (const state of principalPolicyBundleStates(input.bundle)) {\n const cacheKey = `${state.signerUserId}:${state.signerUserKeyFingerprint}`;\n if (signerPublicKeysByKey.has(cacheKey)) {\n continue;\n }\n\n const signerKey = await input.resolveUserKey(state.signerUserId);\n if (!signerKey) {\n throw new ProjectionDependencyUnavailableError(\n `${input.label} signer key could not be resolved for ${state.signerUserId}`,\n );\n }\n\n const signingKeyFingerprint = await toFingerprint(\n signerKey.signingPublicKey,\n );\n if (signingKeyFingerprint !== state.signerUserKeyFingerprint) {\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n `${input.label} signer key fingerprint mismatch`,\n );\n }\n\n signerPublicKeysByKey.set(cacheKey, {\n userId: state.signerUserId,\n signingKeyFingerprint,\n signingPublicKey: signerKey.signingPublicKey,\n });\n }\n\n return [...signerPublicKeysByKey.values()];\n}\n\ntype OrganizationAdminPolicyInput = {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n resolveUserKey: ProjectionUserKeyResolver;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n};\n\nasync function loadOrganizationPolicyForVerification(\n input: OrganizationAdminPolicyInput,\n): Promise<\n | {\n bundle: PrincipalPolicyBundleResponse;\n localCheckpoint: Awaited<\n ReturnType<typeof loadPrincipalPolicyCheckpoint>\n >;\n }\n | undefined\n> {\n const execSql = input.checkpointContext.execSql;\n let bundle = await loadPrincipalPolicyBundle(\n execSql,\n \"organization\",\n input.organizationId,\n );\n if (!bundle) {\n return undefined;\n }\n let localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n \"organization\",\n input.organizationId,\n );\n if (\n !principalPolicyHeadMeetsCheckpoint(bundle.currentState, localCheckpoint) &&\n input.warmReferencedPrincipalPolicies\n ) {\n await input.warmReferencedPrincipalPolicies({\n organizationId: input.organizationId,\n references: [principalPolicyReferenceFromBundle(bundle)],\n });\n bundle = await loadPrincipalPolicyBundle(\n execSql,\n \"organization\",\n input.organizationId,\n );\n localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n \"organization\",\n input.organizationId,\n );\n if (!bundle) {\n return undefined;\n }\n }\n\n return { bundle, localCheckpoint };\n}\n\nfunction assertReservedAdminsPolicyShape(\n policy: VerifiedPrincipalPolicy,\n): void {\n const history = policy.history ?? [{ projection: policy.projection }];\n if (\n history.some(\n (entry) =>\n entry.projection.length === 0 ||\n entry.projection.some((member) => member.role !== \"admin\"),\n )\n ) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"reserved Admins policy must contain only direct admin users\",\n );\n }\n}\n\nasync function verifyOrganizationAdminsPolicy(input: {\n adminGroupId: string;\n execSql: ProjectionCheckpointContext[\"execSql\"];\n expectedHead: ReferencedPrincipalHead;\n resolveUserKey: ProjectionUserKeyResolver;\n}): Promise<VerifiedPrincipalPolicy | undefined> {\n const adminBundle = await loadPrincipalPolicyBundle(\n input.execSql,\n \"group\",\n input.adminGroupId,\n );\n if (!adminBundle) {\n return undefined;\n }\n if (\n !principalHeadMatchesReference(\n principalPolicyReferenceFromBundle(adminBundle),\n input.expectedHead,\n )\n ) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n \"Admins policy does not match the signed organization directory\",\n );\n }\n const adminCheckpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n \"group\",\n input.adminGroupId,\n );\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle: adminBundle,\n label: `Admins policy ${input.adminGroupId}`,\n resolveUserKey: input.resolveUserKey,\n });\n const verified = await verifyPrincipalPolicyBundle({\n bundle: adminBundle,\n expectedReference: input.expectedHead,\n localCheckpoint: adminCheckpoint,\n signerPublicKeys,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n assertReservedAdminsPolicyShape(verified.value);\n return verified.value;\n}\n\nasync function loadOrganizationExternalAuthority(\n input: OrganizationAdminPolicyInput,\n): Promise<ReturnType<typeof organizationAdminExternalAuthority> | null> {\n const organizationPolicy = await loadOrganizationPolicyForVerification(input);\n if (!organizationPolicy) {\n return null;\n }\n\n try {\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle: organizationPolicy.bundle,\n label: `Organization policy ${input.organizationId}`,\n resolveUserKey: input.resolveUserKey,\n });\n const verified = await verifyOrganizationAdminPolicy({\n bundle: organizationPolicy.bundle,\n localCheckpoint: organizationPolicy.localCheckpoint,\n organizationId: input.organizationId,\n signerPublicKeys,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n const descriptor = parseOrganizationAuthorityDescriptor(\n organizationPolicy.bundle.currentPayload.ciphertext,\n );\n if (descriptor.organizationId !== input.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"organization authority descriptor scope does not match\",\n );\n }\n const verifiedAdmins = await verifyOrganizationAdminsPolicy({\n adminGroupId: descriptor.adminGroupId,\n execSql: input.checkpointContext.execSql,\n expectedHead: requireOrganizationGroupHead(\n descriptor,\n descriptor.adminGroupId,\n ),\n resolveUserKey: input.resolveUserKey,\n });\n if (!verifiedAdmins) {\n return null;\n }\n observePrincipalPolicy(\n input.checkpointContext,\n verified.value,\n input.organizationId,\n );\n observePrincipalPolicy(\n input.checkpointContext,\n verifiedAdmins,\n input.organizationId,\n );\n return organizationAdminExternalAuthority(verifiedAdmins);\n } catch (error) {\n rethrowProjectionVerificationBoundaryError(error);\n if (error instanceof KeyingVerificationError) {\n throw error;\n }\n return null;\n }\n}\n\nasync function verifyReferencedPrincipalPolicy(input: {\n recoveryBatch: object;\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n principalPolicyCache: PrincipalPolicyCache;\n reference: ReferencedPrincipalHead;\n stillCurrent?: (() => boolean) | undefined;\n resolveUserKey: ProjectionUserKeyResolver;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<PrincipalPolicyCurrentEvidence> {\n // Scoped recovery carries organization, dependency and lifetime bindings.\n // A bare policy cache entry cannot replace those bindings.\n const recovered = await resolveReferencedPrincipalPolicy(input);\n if (recovered) return recovered;\n const cacheKey = referencedPrincipalPolicyKey(input.reference);\n const cachedPolicy = input.principalPolicyCache.get(cacheKey);\n const execSql = input.checkpointContext.execSql;\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n input.reference.principalType,\n input.reference.principalId,\n );\n if (cachedPolicy && !(\"retainedHistory\" in cachedPolicy)) {\n if (\n !verifiedPrincipalPolicyContainsReference(cachedPolicy, input.reference)\n ) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n \"in-memory principal policy cache does not match its exact reference\",\n );\n }\n if (verifiedPrincipalPolicyMeetsCheckpoint(cachedPolicy, localCheckpoint)) {\n observePrincipalPolicy(\n input.checkpointContext,\n cachedPolicy,\n input.organizationId,\n );\n return cachedPolicy;\n }\n }\n\n const referenceLabel = principalPolicyReferenceLabel(input.reference);\n let bundle = await loadPrincipalPolicyBundleForReference(\n execSql,\n input.reference,\n localCheckpoint,\n );\n if (!bundle && input.warmReferencedPrincipalPolicies) {\n // The reference is not cached locally — the common case for a member who\n // gained access via another org's group grant and never hydrated that\n // group's policy. Fetch+verify+persist it, then re-read from the cache.\n await input.warmReferencedPrincipalPolicies({\n organizationId: input.organizationId,\n references: [input.reference],\n });\n bundle = await loadPrincipalPolicyBundleForReference(\n execSql,\n input.reference,\n localCheckpoint,\n );\n }\n if (!bundle) {\n throw new PrincipalPolicyNotCachedError(referenceLabel);\n }\n\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle,\n label: `Principal policy ${referenceLabel}`,\n resolveUserKey: input.resolveUserKey,\n });\n const verified =\n await verifyPrincipalPolicyBundleWithExternalOrganizationAdmins({\n bundle,\n expectedReference: input.reference,\n loadExternalAuthority: () =>\n loadOrganizationExternalAuthority({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies:\n input.warmReferencedPrincipalPolicies,\n }),\n localCheckpoint,\n signerPublicKeys,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n\n observePrincipalPolicy(\n input.checkpointContext,\n verified.value,\n input.organizationId,\n );\n input.principalPolicyCache.set(cacheKey, verified.value);\n return verified.value;\n}\n\nexport async function collectReferencedPrincipalPolicies(input: {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n principalPolicyCache: PrincipalPolicyCache;\n references: readonly ReferencedPrincipalHead[];\n resolveUserKey: ProjectionUserKeyResolver;\n stillCurrent?: (() => boolean) | undefined;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<PrincipalPolicyCurrentEvidence[]> {\n const warmReferencedPrincipalPolicies =\n generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n );\n const uniqueReferences = new Map<string, ReferencedPrincipalHead>();\n for (const reference of input.references) {\n uniqueReferences.set(referencedPrincipalPolicyKey(reference), reference);\n }\n\n const references = [...uniqueReferences.values()];\n // Warm every missing reference in one batched fetch before verifying, so a\n // path that references several uncached policies makes a single round of\n // requests rather than one per reference.\n if (\n warmReferencedPrincipalPolicies &&\n !warmReferencedPrincipalPolicies.resolveReference\n ) {\n const uncached = await filterUncachedPrincipalPolicyReferences({\n execSql: input.checkpointContext.execSql,\n principalPolicyCache: input.principalPolicyCache,\n references,\n });\n if (uncached.length > 0) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n await warmReferencedPrincipalPolicies({\n organizationId: input.organizationId,\n references: uncached,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n }\n }\n\n const recoveryBatch = {};\n return Promise.all(\n references.map((reference) =>\n verifyReferencedPrincipalPolicy({\n recoveryBatch,\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n reference,\n stillCurrent: input.stillCurrent,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies,\n }),\n ),\n );\n}\n"]}
1
+ {"version":3,"file":"principalPolicyVerification.js","sourceRoot":"","sources":["principalPolicyVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type PrincipalPolicySignerPublicKey,\n type ReferencedPrincipalHead,\n toFingerprint,\n type VerifiedPrincipalPolicy,\n verifyPrincipalPolicyBundle,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport { loadPrincipalPolicyCheckpoint } from \"../persistence/keyingCheckpointPersistence\";\nimport {\n principalPolicyHeadMeetsCheckpoint,\n verifiedPrincipalPolicyMeetsCheckpoint,\n} from \"../persistence/principalPolicyCheckpointSelection\";\nimport { loadPrincipalPolicyBundle } from \"../persistence/principalPolicyPersistence\";\nimport { loadPrincipalPolicyBundleForReference } from \"../persistence/principalPolicyReferencePersistence\";\nimport { principalPolicyBundleStates } from \"../principalPolicyStates\";\nimport {\n parseOrganizationAuthorityDescriptor,\n principalHeadMatchesReference,\n requireOrganizationGroupHead,\n} from \"../principals/organizationAuthorityDescriptor\";\nimport {\n organizationAdminExternalAuthority,\n principalPolicyReferenceFromBundle,\n verifyOrganizationAdminPolicy,\n verifyPrincipalPolicyBundleWithExternalOrganizationAdmins,\n} from \"../principals/principalPolicyAdminSigners\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../principals/principalPolicyEvidence\";\nimport {\n observePrincipalPolicy,\n type ProjectionCheckpointContext,\n} from \"./checkpointContext\";\nimport { ProjectionDependencyUnavailableError } from \"./dependencyUnavailable\";\nimport { rethrowProjectionVerificationBoundaryError } from \"./error\";\nimport {\n filterUncachedPrincipalPolicyReferences,\n referencedPrincipalPolicyKey,\n verifiedPrincipalPolicyContainsReference,\n} from \"./principalPolicyCache\";\nimport { resolveReferencedPrincipalPolicy } from \"./resolvedPrincipalPolicy\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"./types\";\nimport {\n assertProjectionVerificationCurrent,\n generationGuardedPrincipalPolicyWarmer,\n} from \"./types\";\n\nfunction principalPolicyReferenceLabel(\n reference: ReferencedPrincipalHead,\n): string {\n return `${reference.principalType}:${reference.principalId}@${reference.version}`;\n}\n\n/**\n * A referenced principal policy is not in the local store and warming could\n * not fetch it this pass — a transient cold-cache condition, typical for a\n * member whose access arrives via a group policy the device has not hydrated\n * yet. Sync passes discriminate on this type to defer the affected container\n * and retry on a later trigger, rather than failing the whole pass.\n */\nexport class PrincipalPolicyNotCachedError extends Error {\n constructor(referenceLabel: string) {\n super(`Principal policy ${referenceLabel} is not cached`);\n this.name = \"PrincipalPolicyNotCachedError\";\n }\n}\n\nexport function isPrincipalPolicyNotCachedError(error: unknown): boolean {\n return (\n error instanceof PrincipalPolicyNotCachedError ||\n (error instanceof Error && error.name === \"PrincipalPolicyNotCachedError\")\n );\n}\n\nasync function collectPrincipalPolicySignerPublicKeys(input: {\n bundle: PrincipalPolicyBundleResponse;\n label: string;\n resolveUserKey: ProjectionUserKeyResolver;\n}): Promise<PrincipalPolicySignerPublicKey[]> {\n const signerPublicKeysByKey = new Map<\n string,\n PrincipalPolicySignerPublicKey\n >();\n\n for (const state of principalPolicyBundleStates(input.bundle)) {\n const cacheKey = `${state.signerUserId}:${state.signerUserKeyFingerprint}`;\n if (signerPublicKeysByKey.has(cacheKey)) {\n continue;\n }\n\n const signerKey = await input.resolveUserKey(state.signerUserId);\n if (!signerKey) {\n throw new ProjectionDependencyUnavailableError(\n `${input.label} signer key could not be resolved for ${state.signerUserId}`,\n );\n }\n\n const signingKeyFingerprint = await toFingerprint(\n signerKey.signingPublicKey,\n );\n if (signingKeyFingerprint !== state.signerUserKeyFingerprint) {\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n `${input.label} signer key fingerprint mismatch`,\n );\n }\n\n signerPublicKeysByKey.set(cacheKey, {\n userId: state.signerUserId,\n signingKeyFingerprint,\n signingPublicKey: signerKey.signingPublicKey,\n });\n }\n\n return [...signerPublicKeysByKey.values()];\n}\n\ntype OrganizationAdminPolicyInput = {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n resolveUserKey: ProjectionUserKeyResolver;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n};\n\nasync function loadOrganizationPolicyForVerification(\n input: OrganizationAdminPolicyInput,\n): Promise<\n | {\n bundle: PrincipalPolicyBundleResponse;\n localCheckpoint: Awaited<\n ReturnType<typeof loadPrincipalPolicyCheckpoint>\n >;\n }\n | undefined\n> {\n const execSql = input.checkpointContext.execSql;\n let bundle = await loadPrincipalPolicyBundle(\n execSql,\n \"organization\",\n input.organizationId,\n );\n if (!bundle) {\n return undefined;\n }\n let localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n \"organization\",\n input.organizationId,\n );\n if (\n !principalPolicyHeadMeetsCheckpoint(bundle.currentState, localCheckpoint) &&\n input.warmReferencedPrincipalPolicies\n ) {\n await input.warmReferencedPrincipalPolicies({\n organizationId: input.organizationId,\n references: [principalPolicyReferenceFromBundle(bundle)],\n });\n bundle = await loadPrincipalPolicyBundle(\n execSql,\n \"organization\",\n input.organizationId,\n );\n localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n \"organization\",\n input.organizationId,\n );\n if (!bundle) {\n return undefined;\n }\n }\n\n return { bundle, localCheckpoint };\n}\n\nfunction assertReservedAdminsPolicyShape(\n policy: VerifiedPrincipalPolicy,\n): void {\n const history = policy.history ?? [{ projection: policy.projection }];\n if (\n history.some(\n (entry) =>\n entry.projection.length === 0 ||\n entry.projection.some((member) => member.role !== \"admin\"),\n )\n ) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"reserved Admins policy must contain only direct admin users\",\n );\n }\n}\n\nasync function verifyOrganizationAdminsPolicy(input: {\n adminGroupId: string;\n execSql: ProjectionCheckpointContext[\"execSql\"];\n expectedHead: ReferencedPrincipalHead;\n resolveUserKey: ProjectionUserKeyResolver;\n}): Promise<VerifiedPrincipalPolicy | undefined> {\n const adminBundle = await loadPrincipalPolicyBundle(\n input.execSql,\n \"group\",\n input.adminGroupId,\n );\n if (!adminBundle) {\n return undefined;\n }\n if (\n !principalHeadMatchesReference(\n principalPolicyReferenceFromBundle(adminBundle),\n input.expectedHead,\n )\n ) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n \"Admins policy does not match the signed organization directory\",\n );\n }\n const adminCheckpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n \"group\",\n input.adminGroupId,\n );\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle: adminBundle,\n label: `Admins policy ${input.adminGroupId}`,\n resolveUserKey: input.resolveUserKey,\n });\n const verified = await verifyPrincipalPolicyBundle({\n bundle: adminBundle,\n expectedReference: input.expectedHead,\n localCheckpoint: adminCheckpoint,\n signerPublicKeys,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n assertReservedAdminsPolicyShape(verified.value);\n return verified.value;\n}\n\nasync function loadOrganizationExternalAuthority(\n input: OrganizationAdminPolicyInput,\n): Promise<ReturnType<typeof organizationAdminExternalAuthority> | null> {\n const organizationPolicy = await loadOrganizationPolicyForVerification(input);\n if (!organizationPolicy) {\n return null;\n }\n\n try {\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle: organizationPolicy.bundle,\n label: `Organization policy ${input.organizationId}`,\n resolveUserKey: input.resolveUserKey,\n });\n const verified = await verifyOrganizationAdminPolicy({\n bundle: organizationPolicy.bundle,\n localCheckpoint: organizationPolicy.localCheckpoint,\n organizationId: input.organizationId,\n signerPublicKeys,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n const descriptor = parseOrganizationAuthorityDescriptor(\n organizationPolicy.bundle.currentPayload.ciphertext,\n );\n if (descriptor.organizationId !== input.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"organization authority descriptor scope does not match\",\n );\n }\n const verifiedAdmins = await verifyOrganizationAdminsPolicy({\n adminGroupId: descriptor.adminGroupId,\n execSql: input.checkpointContext.execSql,\n expectedHead: requireOrganizationGroupHead(\n descriptor,\n descriptor.adminGroupId,\n ),\n resolveUserKey: input.resolveUserKey,\n });\n if (!verifiedAdmins) {\n return null;\n }\n observePrincipalPolicy(\n input.checkpointContext,\n verified.value,\n input.organizationId,\n );\n observePrincipalPolicy(\n input.checkpointContext,\n verifiedAdmins,\n input.organizationId,\n );\n return organizationAdminExternalAuthority(verifiedAdmins);\n } catch (error) {\n rethrowProjectionVerificationBoundaryError(error);\n if (error instanceof KeyingVerificationError) {\n throw error;\n }\n return null;\n }\n}\n\nasync function verifyReferencedPrincipalPolicy(input: {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n principalPolicyCache: PrincipalPolicyCache;\n reference: ReferencedPrincipalHead;\n stillCurrent?: (() => boolean) | undefined;\n resolveUserKey: ProjectionUserKeyResolver;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<PrincipalPolicyCurrentEvidence> {\n // Scoped recovery carries organization, dependency and lifetime bindings.\n // A bare policy cache entry cannot replace those bindings.\n const recovered = await resolveReferencedPrincipalPolicy(input);\n if (recovered) return recovered;\n const cacheKey = referencedPrincipalPolicyKey(input.reference);\n const cachedPolicy = input.principalPolicyCache.get(cacheKey);\n const execSql = input.checkpointContext.execSql;\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n execSql,\n input.reference.principalType,\n input.reference.principalId,\n );\n if (cachedPolicy && !(\"retainedHistory\" in cachedPolicy)) {\n if (\n !verifiedPrincipalPolicyContainsReference(cachedPolicy, input.reference)\n ) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n \"in-memory principal policy cache does not match its exact reference\",\n );\n }\n if (verifiedPrincipalPolicyMeetsCheckpoint(cachedPolicy, localCheckpoint)) {\n observePrincipalPolicy(\n input.checkpointContext,\n cachedPolicy,\n input.organizationId,\n );\n return cachedPolicy;\n }\n }\n\n const referenceLabel = principalPolicyReferenceLabel(input.reference);\n let bundle = await loadPrincipalPolicyBundleForReference(\n execSql,\n input.reference,\n localCheckpoint,\n );\n if (!bundle && input.warmReferencedPrincipalPolicies) {\n // The reference is not cached locally — the common case for a member who\n // gained access via another org's group grant and never hydrated that\n // group's policy. Fetch+verify+persist it, then re-read from the cache.\n await input.warmReferencedPrincipalPolicies({\n organizationId: input.organizationId,\n references: [input.reference],\n });\n bundle = await loadPrincipalPolicyBundleForReference(\n execSql,\n input.reference,\n localCheckpoint,\n );\n }\n if (!bundle) {\n throw new PrincipalPolicyNotCachedError(referenceLabel);\n }\n\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle,\n label: `Principal policy ${referenceLabel}`,\n resolveUserKey: input.resolveUserKey,\n });\n const verified =\n await verifyPrincipalPolicyBundleWithExternalOrganizationAdmins({\n bundle,\n expectedReference: input.reference,\n loadExternalAuthority: () =>\n loadOrganizationExternalAuthority({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies:\n input.warmReferencedPrincipalPolicies,\n }),\n localCheckpoint,\n signerPublicKeys,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n\n observePrincipalPolicy(\n input.checkpointContext,\n verified.value,\n input.organizationId,\n );\n input.principalPolicyCache.set(cacheKey, verified.value);\n return verified.value;\n}\n\nexport async function collectReferencedPrincipalPolicies(input: {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n principalPolicyCache: PrincipalPolicyCache;\n references: readonly ReferencedPrincipalHead[];\n resolveUserKey: ProjectionUserKeyResolver;\n stillCurrent?: (() => boolean) | undefined;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<PrincipalPolicyCurrentEvidence[]> {\n const warmReferencedPrincipalPolicies =\n generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n );\n const uniqueReferences = new Map<string, ReferencedPrincipalHead>();\n for (const reference of input.references) {\n uniqueReferences.set(referencedPrincipalPolicyKey(reference), reference);\n }\n\n const references = [...uniqueReferences.values()];\n // Warm every missing reference in one batched fetch before verifying, so a\n // path that references several uncached policies makes a single round of\n // requests rather than one per reference.\n if (\n warmReferencedPrincipalPolicies &&\n !warmReferencedPrincipalPolicies.resolveReference\n ) {\n const uncached = await filterUncachedPrincipalPolicyReferences({\n execSql: input.checkpointContext.execSql,\n principalPolicyCache: input.principalPolicyCache,\n references,\n });\n if (uncached.length > 0) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n await warmReferencedPrincipalPolicies({\n organizationId: input.organizationId,\n references: uncached,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n }\n }\n\n // The warmer's operation shares one recovery view across its collections.\n return Promise.all(\n references.map((reference) =>\n verifyReferencedPrincipalPolicy({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n reference,\n stillCurrent: input.stillCurrent,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies,\n }),\n ),\n );\n}\n"]}
@@ -3,12 +3,12 @@ import { loadPrincipalPolicyCheckpoint } from "../persistence/keyingCheckpointPe
3
3
  import { verifiedPrincipalPolicyMeetsCheckpoint } from "../persistence/principalPolicyCheckpointSelection.js";
4
4
  import { observePrincipalPolicy, } from "./checkpointContext.js";
5
5
  import { referencedPrincipalPolicyKey, verifiedPrincipalPolicyContainsReference, } from "./principalPolicyCache.js";
6
+ import { observeProjectionLifetime } from "./projectionLifetimes.js";
6
7
  import { assertProjectionVerificationCurrent, } from "./types.js";
7
- // Sparse cache hits must carry the organization binding and every dependency
8
- // into each new admission batch; a bare current-policy capability is insufficient.
9
- // The caller owns this cache. Cross-generation reuse is deliberately disabled by
10
- // the saved guard; a new lifetime restores authenticated persistent evidence.
11
- const recoveredByCache = new WeakMap();
8
+ // Scoped evidence is always resolved through the warmer: its operation memo is
9
+ // the only reuse of recovered directory and Admins evidence, with one set of
10
+ // validity rules. The caller's policy cache keeps bare verified policies; it
11
+ // never stands in for organization, dependency or lifetime bindings.
12
12
  async function meetsCheckpoints(context, result, refreshMissing) {
13
13
  for (const policy of [...result.dependencies, result.policy]) {
14
14
  const checkpoint = await loadPrincipalPolicyCheckpoint(context.execSql, policy.principalType, policy.principalId);
@@ -23,61 +23,49 @@ async function meetsCheckpoints(context, result, refreshMissing) {
23
23
  }
24
24
  return true;
25
25
  }
26
+ async function recoverEvidence(input, resolve) {
27
+ const read = async (recoveryBatch) => {
28
+ assertProjectionVerificationCurrent(input.stillCurrent);
29
+ const recovered = await resolve({
30
+ recoveryBatch,
31
+ organizationId: input.organizationId,
32
+ reference: input.reference,
33
+ stillCurrent: input.stillCurrent,
34
+ });
35
+ assertProjectionVerificationCurrent(input.stillCurrent);
36
+ assertProjectionVerificationCurrent(recovered.stillCurrent);
37
+ return recovered;
38
+ };
39
+ let result = await read();
40
+ // A concurrent admission may advance a pin after recovery verified it.
41
+ // Refresh once outside the operation's directory view; the fresh
42
+ // recovery and final checkpoint check still reject rollback/equivocation.
43
+ if (!(await meetsCheckpoints(input.checkpointContext, result, true))) {
44
+ assertProjectionVerificationCurrent(result.stillCurrent);
45
+ result = await read({});
46
+ await meetsCheckpoints(input.checkpointContext, result, false);
47
+ }
48
+ return result;
49
+ }
26
50
  export async function resolveReferencedPrincipalPolicy(input) {
27
51
  assertProjectionVerificationCurrent(input.stillCurrent);
28
52
  const key = referencedPrincipalPolicyKey(input.reference);
29
- const remembered = recoveredByCache.get(input.principalPolicyCache)?.get(key);
30
- let result = remembered?.organizationId === input.organizationId &&
31
- remembered.policy === input.principalPolicyCache.get(key) &&
32
- remembered.stillCurrent()
33
- ? remembered
34
- : undefined;
35
- if (result &&
36
- !(await meetsCheckpoints(input.checkpointContext, result, true)))
37
- result = undefined;
38
- if (!result) {
39
- const resolve = input.warmReferencedPrincipalPolicies?.resolveReference;
40
- if (!resolve)
41
- return null;
42
- const read = async (recoveryBatch) => {
43
- assertProjectionVerificationCurrent(input.stillCurrent);
44
- const recovered = await resolve({
45
- recoveryBatch,
46
- organizationId: input.organizationId,
47
- reference: input.reference,
48
- stillCurrent: input.stillCurrent,
49
- });
50
- assertProjectionVerificationCurrent(input.stillCurrent);
51
- assertProjectionVerificationCurrent(recovered.stillCurrent);
52
- return recovered;
53
- };
54
- result = await read(input.recoveryBatch);
55
- // A concurrent admission may advance a pin after recovery verified it.
56
- // Refresh once outside the old batch's pinned directory view; the fresh
57
- // recovery and final checkpoint check still reject rollback/equivocation.
58
- if (!(await meetsCheckpoints(input.checkpointContext, result, true))) {
59
- assertProjectionVerificationCurrent(result.stillCurrent);
60
- result = await read({});
61
- await meetsCheckpoints(input.checkpointContext, result, false);
62
- }
63
- }
64
- assertProjectionVerificationCurrent(input.stillCurrent);
65
- assertProjectionVerificationCurrent(result.stillCurrent);
53
+ const resolve = input.warmReferencedPrincipalPolicies?.resolveReference;
54
+ if (!resolve)
55
+ return null;
56
+ const result = await recoverEvidence(input, resolve);
57
+ const evidenceCurrent = result.stillCurrent;
58
+ // The consumer's and every producer's lifetime guard the evidence where it
59
+ // is used: projection admission rechecks them through the context.
60
+ const lifetime = () => input.stillCurrent?.() !== false && evidenceCurrent();
61
+ assertProjectionVerificationCurrent(lifetime);
62
+ observeProjectionLifetime(input.checkpointContext, lifetime);
66
63
  if (result.organizationId !== input.organizationId)
67
64
  throw new KeyingVerificationError("object_mismatch", "Recovered principal evidence belongs to another organization");
68
65
  if (!verifiedPrincipalPolicyContainsReference(result.policy, input.reference))
69
66
  throw new KeyingVerificationError("object_mismatch", "Recovered principal evidence does not contain the exact citation");
70
67
  for (const policy of [...result.dependencies, result.policy])
71
68
  observePrincipalPolicy(input.checkpointContext, policy, input.organizationId);
72
- let rememberedPolicies = recoveredByCache.get(input.principalPolicyCache);
73
- if (!rememberedPolicies) {
74
- rememberedPolicies = new Map();
75
- recoveredByCache.set(input.principalPolicyCache, rememberedPolicies);
76
- }
77
- rememberedPolicies.set(key, {
78
- ...result,
79
- dependencies: [...result.dependencies],
80
- });
81
69
  input.principalPolicyCache.set(key, result.policy);
82
70
  return result.policy;
83
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"resolvedPrincipalPolicy.js","sourceRoot":"","sources":["resolvedPrincipalPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { loadPrincipalPolicyCheckpoint } from \"../persistence/keyingCheckpointPersistence\";\nimport { verifiedPrincipalPolicyMeetsCheckpoint } from \"../persistence/principalPolicyCheckpointSelection\";\nimport {\n observePrincipalPolicy,\n type ProjectionCheckpointContext,\n} from \"./checkpointContext\";\nimport {\n referencedPrincipalPolicyKey,\n verifiedPrincipalPolicyContainsReference,\n} from \"./principalPolicyCache\";\nimport {\n assertProjectionVerificationCurrent,\n type PrincipalPolicyCache,\n type ReferencedPrincipalPolicyWarmer,\n type ResolvedPrincipalPolicyEvidence,\n} from \"./types\";\n\n// Sparse cache hits must carry the organization binding and every dependency\n// into each new admission batch; a bare current-policy capability is insufficient.\n// The caller owns this cache. Cross-generation reuse is deliberately disabled by\n// the saved guard; a new lifetime restores authenticated persistent evidence.\nconst recoveredByCache = new WeakMap<\n PrincipalPolicyCache,\n Map<string, ResolvedPrincipalPolicyEvidence>\n>();\n\nasync function meetsCheckpoints(\n context: ProjectionCheckpointContext,\n result: ResolvedPrincipalPolicyEvidence,\n refreshMissing: boolean,\n): Promise<boolean> {\n for (const policy of [...result.dependencies, result.policy]) {\n const checkpoint = await loadPrincipalPolicyCheckpoint(\n context.execSql,\n policy.principalType,\n policy.principalId,\n );\n if (\n refreshMissing &&\n checkpoint &&\n (policy.version < checkpoint.version ||\n (policy.version > checkpoint.version &&\n !policy.retainedHistory.some(\n (entry) => entry.state.version === checkpoint.version,\n )))\n )\n return false;\n if (!verifiedPrincipalPolicyMeetsCheckpoint(policy, checkpoint))\n throw new KeyingVerificationError(\n \"rollback\",\n \"Recovered principal evidence predates the durable checkpoint\",\n );\n }\n return true;\n}\n\nexport async function resolveReferencedPrincipalPolicy(input: {\n readonly recoveryBatch?: object | undefined;\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly organizationId: string;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly reference: ReferencedPrincipalHead;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<VerifiedPrincipalPolicyCurrent | null> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const key = referencedPrincipalPolicyKey(input.reference);\n const remembered = recoveredByCache.get(input.principalPolicyCache)?.get(key);\n let result =\n remembered?.organizationId === input.organizationId &&\n remembered.policy === input.principalPolicyCache.get(key) &&\n remembered.stillCurrent()\n ? remembered\n : undefined;\n if (\n result &&\n !(await meetsCheckpoints(input.checkpointContext, result, true))\n )\n result = undefined;\n if (!result) {\n const resolve = input.warmReferencedPrincipalPolicies?.resolveReference;\n if (!resolve) return null;\n const read = async (recoveryBatch: object | undefined) => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const recovered = await resolve({\n recoveryBatch,\n organizationId: input.organizationId,\n reference: input.reference,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n assertProjectionVerificationCurrent(recovered.stillCurrent);\n return recovered;\n };\n result = await read(input.recoveryBatch);\n // A concurrent admission may advance a pin after recovery verified it.\n // Refresh once outside the old batch's pinned directory view; the fresh\n // recovery and final checkpoint check still reject rollback/equivocation.\n if (!(await meetsCheckpoints(input.checkpointContext, result, true))) {\n assertProjectionVerificationCurrent(result.stillCurrent);\n result = await read({});\n await meetsCheckpoints(input.checkpointContext, result, false);\n }\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n assertProjectionVerificationCurrent(result.stillCurrent);\n if (result.organizationId !== input.organizationId)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Recovered principal evidence belongs to another organization\",\n );\n if (!verifiedPrincipalPolicyContainsReference(result.policy, input.reference))\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Recovered principal evidence does not contain the exact citation\",\n );\n for (const policy of [...result.dependencies, result.policy])\n observePrincipalPolicy(\n input.checkpointContext,\n policy,\n input.organizationId,\n );\n let rememberedPolicies = recoveredByCache.get(input.principalPolicyCache);\n if (!rememberedPolicies) {\n rememberedPolicies = new Map();\n recoveredByCache.set(input.principalPolicyCache, rememberedPolicies);\n }\n rememberedPolicies.set(key, {\n ...result,\n dependencies: [...result.dependencies],\n });\n input.principalPolicyCache.set(key, result.policy);\n return result.policy;\n}\n"]}
1
+ {"version":3,"file":"resolvedPrincipalPolicy.js","sourceRoot":"","sources":["resolvedPrincipalPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { loadPrincipalPolicyCheckpoint } from \"../persistence/keyingCheckpointPersistence\";\nimport { verifiedPrincipalPolicyMeetsCheckpoint } from \"../persistence/principalPolicyCheckpointSelection\";\nimport {\n observePrincipalPolicy,\n type ProjectionCheckpointContext,\n} from \"./checkpointContext\";\nimport {\n referencedPrincipalPolicyKey,\n verifiedPrincipalPolicyContainsReference,\n} from \"./principalPolicyCache\";\nimport { observeProjectionLifetime } from \"./projectionLifetimes\";\nimport {\n assertProjectionVerificationCurrent,\n type PrincipalPolicyCache,\n type ReferencedPrincipalPolicyWarmer,\n type ResolvedPrincipalPolicyEvidence,\n} from \"./types\";\n\n// Scoped evidence is always resolved through the warmer: its operation memo is\n// the only reuse of recovered directory and Admins evidence, with one set of\n// validity rules. The caller's policy cache keeps bare verified policies; it\n// never stands in for organization, dependency or lifetime bindings.\nasync function meetsCheckpoints(\n context: ProjectionCheckpointContext,\n result: ResolvedPrincipalPolicyEvidence,\n refreshMissing: boolean,\n): Promise<boolean> {\n for (const policy of [...result.dependencies, result.policy]) {\n const checkpoint = await loadPrincipalPolicyCheckpoint(\n context.execSql,\n policy.principalType,\n policy.principalId,\n );\n if (\n refreshMissing &&\n checkpoint &&\n (policy.version < checkpoint.version ||\n (policy.version > checkpoint.version &&\n !policy.retainedHistory.some(\n (entry) => entry.state.version === checkpoint.version,\n )))\n )\n return false;\n if (!verifiedPrincipalPolicyMeetsCheckpoint(policy, checkpoint))\n throw new KeyingVerificationError(\n \"rollback\",\n \"Recovered principal evidence predates the durable checkpoint\",\n );\n }\n return true;\n}\n\ninterface ResolveReferencedPrincipalPolicyInput {\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly organizationId: string;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly reference: ReferencedPrincipalHead;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\nasync function recoverEvidence(\n input: ResolveReferencedPrincipalPolicyInput,\n resolve: NonNullable<ReferencedPrincipalPolicyWarmer[\"resolveReference\"]>,\n): Promise<ResolvedPrincipalPolicyEvidence> {\n const read = async (recoveryBatch?: object) => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const recovered = await resolve({\n recoveryBatch,\n organizationId: input.organizationId,\n reference: input.reference,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n assertProjectionVerificationCurrent(recovered.stillCurrent);\n return recovered;\n };\n let result = await read();\n // A concurrent admission may advance a pin after recovery verified it.\n // Refresh once outside the operation's directory view; the fresh\n // recovery and final checkpoint check still reject rollback/equivocation.\n if (!(await meetsCheckpoints(input.checkpointContext, result, true))) {\n assertProjectionVerificationCurrent(result.stillCurrent);\n result = await read({});\n await meetsCheckpoints(input.checkpointContext, result, false);\n }\n return result;\n}\n\nexport async function resolveReferencedPrincipalPolicy(\n input: ResolveReferencedPrincipalPolicyInput,\n): Promise<VerifiedPrincipalPolicyCurrent | null> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const key = referencedPrincipalPolicyKey(input.reference);\n const resolve = input.warmReferencedPrincipalPolicies?.resolveReference;\n if (!resolve) return null;\n const result = await recoverEvidence(input, resolve);\n const evidenceCurrent = result.stillCurrent;\n // The consumer's and every producer's lifetime guard the evidence where it\n // is used: projection admission rechecks them through the context.\n const lifetime = () => input.stillCurrent?.() !== false && evidenceCurrent();\n assertProjectionVerificationCurrent(lifetime);\n observeProjectionLifetime(input.checkpointContext, lifetime);\n if (result.organizationId !== input.organizationId)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Recovered principal evidence belongs to another organization\",\n );\n if (!verifiedPrincipalPolicyContainsReference(result.policy, input.reference))\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Recovered principal evidence does not contain the exact citation\",\n );\n for (const policy of [...result.dependencies, result.policy])\n observePrincipalPolicy(\n input.checkpointContext,\n policy,\n input.organizationId,\n );\n input.principalPolicyCache.set(key, result.policy);\n return result.policy;\n}\n"]}
@@ -8,7 +8,7 @@ export type PrincipalPolicyCache = Map<string, PrincipalPolicyCurrentEvidence>;
8
8
  export interface PrincipalPolicyResolveRequest {
9
9
  /** Reuse authenticated local ancestry before an authorized online recovery. */
10
10
  readonly preferLocalHistory?: boolean | undefined;
11
- /** Identity of one projection collection, never caller-supplied evidence. */
11
+ /** One recovery view: the warmer's operation unless a caller supplies its own. */
12
12
  readonly recoveryBatch?: object | undefined;
13
13
  readonly organizationId: string;
14
14
  readonly reference: ReferencedPrincipalHead;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyCurrent,\n VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport type { ProjectionPolicyEvidenceResponse } from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../principals/principalPolicyEvidence\";\nimport type { TrustedUserIdentity } from \"../trustedUserIdentity\";\n\nexport type ProjectionUserKey = TrustedUserIdentity;\n\nexport type ProjectionUserKeyResolver = (\n userId: string,\n) => Promise<ProjectionUserKey | null>;\n\nexport type PrincipalPolicyCache = Map<string, PrincipalPolicyCurrentEvidence>;\n\nexport interface PrincipalPolicyResolveRequest {\n /** Reuse authenticated local ancestry before an authorized online recovery. */\n readonly preferLocalHistory?: boolean | undefined;\n /** Identity of one projection collection, never caller-supplied evidence. */\n readonly recoveryBatch?: object | undefined;\n readonly organizationId: string;\n readonly reference: ReferencedPrincipalHead;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ResolvedPrincipalPolicyEvidence {\n readonly stillCurrent: () => boolean;\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicyCurrent;\n readonly dependencies: readonly VerifiedPrincipalPolicyCurrent[];\n}\n\nexport interface ReferencedPrincipalPolicyWarmRequest {\n readonly organizationId: string;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ProjectionPolicyHistoryResolveRequest {\n /** Authenticate terminal evidence first; its consumer must validate durable currency. */\n readonly historicalProof?: boolean | undefined;\n readonly organizationId: string;\n readonly evidence: ProjectionPolicyEvidenceResponse;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ResolvedProjectionPolicyHistory {\n readonly policies: readonly VerifiedPrincipalPolicySelection[];\n readonly stillCurrent: () => boolean;\n}\n\nexport type ReferencedPrincipalPolicyWarmer = ((\n input: ReferencedPrincipalPolicyWarmRequest,\n) => Promise<void>) & {\n readonly resolveProjectionHistory?:\n | ((\n input: ProjectionPolicyHistoryResolveRequest,\n ) => Promise<ResolvedProjectionPolicyHistory>)\n | undefined;\n readonly resolveReference?:\n | ((\n input: PrincipalPolicyResolveRequest,\n ) => Promise<ResolvedPrincipalPolicyEvidence>)\n | undefined;\n};\n\nexport class ProjectionVerificationCancelledError extends Error {\n constructor() {\n super(\"Projection verification generation expired\");\n this.name = \"ProjectionVerificationCancelledError\";\n }\n}\n\nconst projectionVerificationCancellation =\n new ProjectionVerificationCancelledError();\n\nexport function isProjectionVerificationCancelledError(\n error: unknown,\n): error is ProjectionVerificationCancelledError {\n return error === projectionVerificationCancellation;\n}\n\nexport function rethrowProjectionVerificationCancelled(error: unknown): void {\n if (isProjectionVerificationCancelledError(error)) throw error;\n}\n\nexport async function nullOnProjectionVerificationCancellation<T>(\n operation: () => Promise<T>,\n): Promise<T | null> {\n try {\n return await operation();\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return null;\n throw error;\n }\n}\n\nexport function assertProjectionVerificationCurrent(\n stillCurrent: (() => boolean) | undefined,\n): void {\n if (stillCurrent?.() === false) {\n throw projectionVerificationCancellation;\n }\n}\n\nexport function generationGuardedPrincipalPolicyWarmer(\n warmer: ReferencedPrincipalPolicyWarmer | undefined,\n stillCurrent: (() => boolean) | undefined,\n): ReferencedPrincipalPolicyWarmer | undefined {\n if (!warmer || !stillCurrent) return warmer;\n const guard =\n (operation: ReferencedPrincipalPolicyWarmer) =>\n async (input: ReferencedPrincipalPolicyWarmRequest) => {\n assertProjectionVerificationCurrent(stillCurrent);\n await operation({ ...input, stillCurrent });\n assertProjectionVerificationCurrent(stillCurrent);\n };\n const guardWithCapabilities = (\n operation: ReferencedPrincipalPolicyWarmer,\n ): ReferencedPrincipalPolicyWarmer => {\n const guarded = guard(operation);\n const resolve = operation.resolveReference;\n const resolveProjectionHistory = operation.resolveProjectionHistory;\n return Object.assign(guarded, {\n ...(resolveProjectionHistory\n ? {\n resolveProjectionHistory: async (\n input: ProjectionPolicyHistoryResolveRequest,\n ) => {\n const current = () =>\n stillCurrent() && input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(current);\n const result = await resolveProjectionHistory({\n ...input,\n stillCurrent: current,\n });\n assertProjectionVerificationCurrent(current);\n return result;\n },\n }\n : {}),\n ...(resolve\n ? {\n resolveReference: async (input: PrincipalPolicyResolveRequest) => {\n const current = () =>\n stillCurrent() && input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(current);\n const result = await resolve({ ...input, stillCurrent: current });\n assertProjectionVerificationCurrent(current);\n return result;\n },\n }\n : {}),\n });\n };\n return guardWithCapabilities(warmer);\n}\n\nexport function withGenerationGuardedPolicyWarmer<\n Input extends {\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n },\n>(input: Input): Input {\n return {\n ...input,\n warmReferencedPrincipalPolicies: generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n ),\n };\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyCurrent,\n VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport type { ProjectionPolicyEvidenceResponse } from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../principals/principalPolicyEvidence\";\nimport type { TrustedUserIdentity } from \"../trustedUserIdentity\";\n\nexport type ProjectionUserKey = TrustedUserIdentity;\n\nexport type ProjectionUserKeyResolver = (\n userId: string,\n) => Promise<ProjectionUserKey | null>;\n\nexport type PrincipalPolicyCache = Map<string, PrincipalPolicyCurrentEvidence>;\n\nexport interface PrincipalPolicyResolveRequest {\n /** Reuse authenticated local ancestry before an authorized online recovery. */\n readonly preferLocalHistory?: boolean | undefined;\n /** One recovery view: the warmer's operation unless a caller supplies its own. */\n readonly recoveryBatch?: object | undefined;\n readonly organizationId: string;\n readonly reference: ReferencedPrincipalHead;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ResolvedPrincipalPolicyEvidence {\n readonly stillCurrent: () => boolean;\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicyCurrent;\n readonly dependencies: readonly VerifiedPrincipalPolicyCurrent[];\n}\n\nexport interface ReferencedPrincipalPolicyWarmRequest {\n readonly organizationId: string;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ProjectionPolicyHistoryResolveRequest {\n /** Authenticate terminal evidence first; its consumer must validate durable currency. */\n readonly historicalProof?: boolean | undefined;\n readonly organizationId: string;\n readonly evidence: ProjectionPolicyEvidenceResponse;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ResolvedProjectionPolicyHistory {\n readonly policies: readonly VerifiedPrincipalPolicySelection[];\n readonly stillCurrent: () => boolean;\n}\n\nexport type ReferencedPrincipalPolicyWarmer = ((\n input: ReferencedPrincipalPolicyWarmRequest,\n) => Promise<void>) & {\n readonly resolveProjectionHistory?:\n | ((\n input: ProjectionPolicyHistoryResolveRequest,\n ) => Promise<ResolvedProjectionPolicyHistory>)\n | undefined;\n readonly resolveReference?:\n | ((\n input: PrincipalPolicyResolveRequest,\n ) => Promise<ResolvedPrincipalPolicyEvidence>)\n | undefined;\n};\n\nexport class ProjectionVerificationCancelledError extends Error {\n constructor() {\n super(\"Projection verification generation expired\");\n this.name = \"ProjectionVerificationCancelledError\";\n }\n}\n\nconst projectionVerificationCancellation =\n new ProjectionVerificationCancelledError();\n\nexport function isProjectionVerificationCancelledError(\n error: unknown,\n): error is ProjectionVerificationCancelledError {\n return error === projectionVerificationCancellation;\n}\n\nexport function rethrowProjectionVerificationCancelled(error: unknown): void {\n if (isProjectionVerificationCancelledError(error)) throw error;\n}\n\nexport async function nullOnProjectionVerificationCancellation<T>(\n operation: () => Promise<T>,\n): Promise<T | null> {\n try {\n return await operation();\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return null;\n throw error;\n }\n}\n\nexport function assertProjectionVerificationCurrent(\n stillCurrent: (() => boolean) | undefined,\n): void {\n if (stillCurrent?.() === false) {\n throw projectionVerificationCancellation;\n }\n}\n\nexport function generationGuardedPrincipalPolicyWarmer(\n warmer: ReferencedPrincipalPolicyWarmer | undefined,\n stillCurrent: (() => boolean) | undefined,\n): ReferencedPrincipalPolicyWarmer | undefined {\n if (!warmer || !stillCurrent) return warmer;\n const guard =\n (operation: ReferencedPrincipalPolicyWarmer) =>\n async (input: ReferencedPrincipalPolicyWarmRequest) => {\n assertProjectionVerificationCurrent(stillCurrent);\n await operation({ ...input, stillCurrent });\n assertProjectionVerificationCurrent(stillCurrent);\n };\n const guardWithCapabilities = (\n operation: ReferencedPrincipalPolicyWarmer,\n ): ReferencedPrincipalPolicyWarmer => {\n const guarded = guard(operation);\n const resolve = operation.resolveReference;\n const resolveProjectionHistory = operation.resolveProjectionHistory;\n return Object.assign(guarded, {\n ...(resolveProjectionHistory\n ? {\n resolveProjectionHistory: async (\n input: ProjectionPolicyHistoryResolveRequest,\n ) => {\n const current = () =>\n stillCurrent() && input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(current);\n const result = await resolveProjectionHistory({\n ...input,\n stillCurrent: current,\n });\n assertProjectionVerificationCurrent(current);\n return result;\n },\n }\n : {}),\n ...(resolve\n ? {\n resolveReference: async (input: PrincipalPolicyResolveRequest) => {\n const current = () =>\n stillCurrent() && input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(current);\n const result = await resolve({ ...input, stillCurrent: current });\n assertProjectionVerificationCurrent(current);\n return result;\n },\n }\n : {}),\n });\n };\n return guardWithCapabilities(warmer);\n}\n\nexport function withGenerationGuardedPolicyWarmer<\n Input extends {\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n },\n>(input: Input): Input {\n return {\n ...input,\n warmReferencedPrincipalPolicies: generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n ),\n };\n}\n"]}