@tearleads/client-sdk 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/index.d.ts +1 -1
- package/client/index.js.map +1 -1
- package/client/organizations/currentPrincipalMutations.js +96 -0
- package/client/organizations/currentPrincipalMutations.js.map +1 -0
- package/client/organizations/index.d.ts +1 -1
- package/client/organizations/index.js +4 -3
- package/client/organizations/index.js.map +1 -1
- package/client/organizations/organizationGroupHistory.js +44 -0
- package/client/organizations/organizationGroupHistory.js.map +1 -0
- package/client/organizations/organizationGroupNameHydration.js +7 -1
- package/client/organizations/organizationGroupNameHydration.js.map +1 -1
- package/client/organizations/organizationGroupPresentation.d.ts +1 -0
- package/client/organizations/organizationGroupPresentation.js +16 -2
- package/client/organizations/organizationGroupPresentation.js.map +1 -1
- package/client/organizations/organizationReadModels.d.ts +1 -1
- package/client/organizations/organizationReadModels.js +11 -1
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/client/organizations/organizationsTypes.d.ts +8 -5
- package/client/organizations/organizationsTypes.js.map +1 -1
- package/client/organizations/principalContainerMutations.js +2 -0
- package/client/organizations/principalContainerMutations.js.map +1 -1
- package/client/organizations/principalMutations.d.ts +4 -308
- package/client/organizations/principalMutations.js +165 -87
- package/client/organizations/principalMutations.js.map +1 -1
- package/client/principalMutationApi.d.ts +1 -1
- package/client/principalMutationApi.js +5 -13
- package/client/principalMutationApi.js.map +1 -1
- package/client/principalMutationDispatch.js +54 -0
- package/client/principalMutationDispatch.js.map +1 -0
- package/data/persistence/principalCurrentAcknowledgementPersistence.d.ts +2 -2
- package/data/persistence/principalCurrentAcknowledgementPersistence.js +21 -14
- package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -1
- package/data/principals/currentPolicyReferenceResolver.js +2 -0
- package/data/principals/currentPolicyReferenceResolver.js.map +1 -0
- package/data/principals/principalHistoryScopeProtection.js +23 -0
- package/data/principals/principalHistoryScopeProtection.js.map +1 -0
- package/data/principals/principalMutationJournal.d.ts +2 -5
- package/data/principals/principalMutationJournal.js +3 -20
- package/data/principals/principalMutationJournal.js.map +1 -1
- package/data/principals/principalMutationJournalShape.d.ts +26 -0
- package/data/principals/principalMutationJournalShape.js +46 -0
- package/data/principals/principalMutationJournalShape.js.map +1 -0
- package/data/principals/principalPolicyAdminSigners.js.map +1 -1
- package/index.d.ts +2 -2
- package/index.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +267 -3
- package/internal/api-client/ApiClient.js +11 -29
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/principalPolicyRequests.d.ts +266 -1
- package/internal/api-client/principalPolicyRequests.js +43 -1
- package/internal/api-client/principalPolicyRequests.js.map +1 -1
- package/internal/crypto/index.d.ts +1 -1
- package/internal/crypto/index.js +1 -1
- package/internal/crypto/index.js.map +1 -1
- package/internal/crypto/keying/index.d.ts +1 -0
- package/internal/crypto/keying/index.js +1 -0
- package/internal/crypto/keying/index.js.map +1 -1
- package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.d.ts +8 -0
- package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.js +46 -0
- package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.js.map +1 -0
- package/internal/validators/operation/organizations.d.ts +54 -0
- package/internal/validators/operation/organizations.js +19 -4
- package/internal/validators/operation/organizations.js.map +1 -1
- package/package.json +1 -1
- package/workflows/containers/child/carriedDescendantRekeys.js +9 -1
- package/workflows/containers/child/carriedDescendantRekeys.js.map +1 -1
- package/workflows/containers/child/replacementPrincipalPolicyReferences.js +19 -0
- package/workflows/containers/child/replacementPrincipalPolicyReferences.js.map +1 -0
- package/workflows/organizations/commitCurrentGroupPolicyMutation.js +72 -0
- package/workflows/organizations/commitCurrentGroupPolicyMutation.js.map +1 -0
- package/workflows/organizations/createCurrentOrganizationGroup.js +85 -0
- package/workflows/organizations/createCurrentOrganizationGroup.js.map +1 -0
- package/workflows/organizations/currentGroupMetadataAuthority.js +24 -3
- package/workflows/organizations/currentGroupMetadataAuthority.js.map +1 -1
- package/workflows/organizations/currentGroupMutationReferences.js +35 -0
- package/workflows/organizations/currentGroupMutationReferences.js.map +1 -0
- package/workflows/organizations/currentGroupPolicyMutationContext.js +79 -0
- package/workflows/organizations/currentGroupPolicyMutationContext.js.map +1 -0
- package/workflows/organizations/currentOrganizationGroupNames.js +5 -1
- package/workflows/organizations/currentOrganizationGroupNames.js.map +1 -1
- package/workflows/organizations/currentOrganizationMutationAuthority.js +16 -0
- package/workflows/organizations/currentOrganizationMutationAuthority.js.map +1 -0
- package/workflows/organizations/currentOrganizationMutationRetention.js +53 -0
- package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -0
- package/workflows/organizations/currentPrincipalMutationLease.js +38 -0
- package/workflows/organizations/currentPrincipalMutationLease.js.map +1 -0
- package/workflows/organizations/deleteCurrentOrganizationGroup.js +35 -0
- package/workflows/organizations/deleteCurrentOrganizationGroup.js.map +1 -0
- package/workflows/organizations/deleteOrganizationGroup.d.ts +1 -0
- package/workflows/organizations/deleteOrganizationGroup.js +10 -0
- package/workflows/organizations/deleteOrganizationGroup.js.map +1 -1
- package/workflows/organizations/groupCreation.d.ts +1 -0
- package/workflows/organizations/groupCreation.js +8 -0
- package/workflows/organizations/groupCreation.js.map +1 -1
- package/workflows/organizations/groupMembershipName.d.ts +1 -1
- package/workflows/organizations/groupMembershipName.js.map +1 -1
- package/workflows/organizations/groupMetadataRuntime.js +14 -9
- package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
- package/workflows/organizations/groupNameUniqueness.js +1 -1
- package/workflows/organizations/groupNameUniqueness.js.map +1 -1
- package/workflows/organizations/groupPolicyHistoryPage.js +31 -0
- package/workflows/organizations/groupPolicyHistoryPage.js.map +1 -0
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js +1 -0
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +1 -1
- package/workflows/organizations/groupPolicyMutationContext.d.ts +18 -0
- package/workflows/organizations/groupPolicyMutationContext.js +1 -1
- package/workflows/organizations/groupPolicyMutationContext.js.map +1 -1
- package/workflows/organizations/index.d.ts +1 -0
- package/workflows/organizations/index.js.map +1 -1
- package/workflows/organizations/initialPrincipalCurrentPublication.js +83 -0
- package/workflows/organizations/initialPrincipalCurrentPublication.js.map +1 -0
- package/workflows/organizations/organizationGroupDirectory.js +6 -0
- package/workflows/organizations/organizationGroupDirectory.js.map +1 -1
- package/workflows/organizations/organizationGroupNames.js.map +1 -1
- package/workflows/organizations/policyHistoryTypes.d.ts +2 -0
- package/workflows/organizations/policyHistoryTypes.js.map +1 -1
- package/workflows/organizations/principalContainerRematerialization.js +12 -2
- package/workflows/organizations/principalContainerRematerialization.js.map +1 -1
- package/workflows/organizations/principalContainerRematerializationPlanning.js +1 -0
- package/workflows/organizations/principalContainerRematerializationPlanning.js.map +1 -1
- package/workflows/organizations/principalContainerRematerializationTargets.js.map +1 -1
- package/workflows/organizations/principalMutationJournalSession.d.ts +3 -3
- package/workflows/organizations/principalMutationJournalSession.js +2 -2
- package/workflows/organizations/principalMutationJournalSession.js.map +1 -1
- package/workflows/organizations/principalMutationReceipt.js +13 -12
- package/workflows/organizations/principalMutationReceipt.js.map +1 -1
- package/workflows/organizations/principalOperationReceipt.d.ts +5 -0
- package/workflows/organizations/principalOperationReceipt.js +36 -0
- package/workflows/organizations/principalOperationReceipt.js.map +1 -0
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +2 -0
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +5 -1
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -1
- package/workflows/organizations/runtimeCurrentGroupMutation.js +85 -0
- package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -0
- package/workflows/organizations/runtimeCurrentOrganizationMutation.js +48 -0
- package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +1 -0
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.d.ts +11 -0
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.js +120 -0
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/principalHistoryRecoveryReferences.js +8 -0
- package/workflows/principals/principalHistoryRecoveryReferences.js.map +1 -1
- package/workflows/principals/principalRecoveryDirectory.js +3 -8
- package/workflows/principals/principalRecoveryDirectory.js.map +1 -1
- package/workflows/principals/principalRecoveryLocalPreference.js +3 -2
- package/workflows/principals/principalRecoveryLocalPreference.js.map +1 -1
- package/workflows/principals/recoverCurrentOrganizationPolicy.js.map +1 -1
- package/workflows/principals/recoverPrincipalHistoryPage.js +30 -0
- package/workflows/principals/recoverPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/recoverPrincipalPolicyHistory.d.ts +2 -0
- package/workflows/principals/recoverPrincipalPolicyHistory.js +14 -2
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.d.ts +6 -0
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +31 -19
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js +25 -4
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimePolicyWarmer.js +2 -2
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupPolicyMutationContext.js","sourceRoot":"","sources":["groupPolicyMutationContext.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RequestFailureKind } from \"@tearleads/api-client\";\nimport type {\n PrincipalPolicyCheckpoint,\n PrincipalPolicyExternalAuthority,\n ReferencedPrincipalHead,\n SigningKeyPair,\n} from \"@tearleads/crypto\";\nimport type {\n CommitOrganizationGroupPolicyRequest,\n ContainerMutationRequest,\n CreateOrganizationGroupWithPolicyRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type CommitOrganizationGroupPolicyResponse,\n type CreateOrganizationGroupResponse,\n type CurrentPrincipalMemberEnvelopesResponse,\n type PrincipalPolicyBundleResponse,\n type PrincipalPolicyMutationResponse,\n} from \"@tearleads/validators/response\";\nimport { persistVerifiedPrincipalPolicyBundlesAtomically } from \"../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { retainLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport { requireOrganizationGroupHead } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport {\n externalAdminPolicyPersistenceEntries,\n loadOrganizationExternalAdminPolicy,\n type VerifiedExternalAdminPolicy,\n} from \"../principals/externalAdminPolicy\";\nimport { assertGroupMetadataBinding } from \"./groupMetadataBinding\";\nimport { requireSignerCanManageGroup } from \"./groupMutationAuthorization\";\nimport {\n acknowledgeGroupPolicyState,\n assertGroupPolicyEnvelopesMatchAcknowledgement,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { FullGroupMembershipMutationInput } from \"./groupPolicyMutationEvidence\";\nimport {\n assertPrincipalPolicyCurrentStateMatchesHead,\n groupPolicyMutationHead,\n} from \"./groupPolicyMutationHead\";\nimport {\n collectGroupPolicySignerPublicKeys,\n prepareGroupPolicyVerification,\n verifyGroupPolicy,\n verifyGroupPolicyWithExternalOrganizationAdmins,\n} from \"./groupPolicyVerification\";\n\nexport interface PrincipalPolicyReadApi {\n /** Resolve authored work before reading the state for a new mutation. */\n readonly recoverPendingPrincipalMutation?:\n | ((organizationId: string) => Promise<void>)\n | undefined;\n getCurrentPrincipalPolicy: (\n principalType: \"group\" | \"organization\",\n principalId: string,\n ) => Promise<PrincipalPolicyBundleResponse | null>;\n}\n\nexport interface PrincipalPolicyReadWriteApi extends PrincipalPolicyReadApi {\n commitOrganizationGroupPolicy: (\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n ) => Promise<CommitOrganizationGroupPolicyResponse | null>;\n /**\n * Optional status-bearing variant. A rematerialized rotation the server\n * refuses for stranding a granted path names the descendant rekeys the batch\n * must carry; without this the refusal is a plain failure.\n */\n commitOrganizationGroupPolicyResult?: (\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n options?: { readonly reportErrors?: boolean | undefined },\n ) => Promise<\n | {\n readonly ok: true;\n readonly data: CommitOrganizationGroupPolicyResponse;\n }\n | {\n readonly ok: false;\n readonly kind?: RequestFailureKind | undefined;\n readonly message?: string | undefined;\n readonly code?: string | undefined;\n readonly report?: (() => void) | undefined;\n readonly requiredContainerIds?: readonly string[] | undefined;\n readonly status: number | null;\n }\n >;\n}\n\nexport interface OrganizationPrincipalPolicyApi extends PrincipalPolicyReadApi {\n createOrganizationGroup: (\n organizationId: string,\n input: CreateOrganizationGroupWithPolicyRequest,\n ) => Promise<CreateOrganizationGroupResponse | null>;\n}\n\ninterface LoadedGroupPolicyMutationContext\n extends FullGroupMembershipMutationInput {\n readonly adminGroupId: string;\n readonly adminPolicyBundle: PrincipalPolicyBundleResponse;\n readonly currentOrgAdminUserIds: readonly string[];\n readonly organizationDescriptor: VerifiedExternalAdminPolicy[\"descriptor\"];\n readonly organizationPolicyBundle: PrincipalPolicyBundleResponse;\n readonly memberGroupId: string;\n}\n\nexport async function cacheGroupPolicy(input: {\n readonly acknowledgedMemberEnvelopes?:\n | CurrentPrincipalMemberEnvelopesResponse\n | undefined;\n readonly apiClient: PrincipalPolicyReadApi;\n readonly externalAuthority?: PrincipalPolicyExternalAuthority | undefined;\n readonly execSql: ExecSql;\n readonly expectedCurrentHead?: ReferencedPrincipalHead | undefined;\n readonly groupId: string;\n readonly localPolicyCheckpoint?: PrincipalPolicyCheckpoint | null;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<PrincipalPolicyBundleResponse> {\n const bundle = await input.apiClient.getCurrentPrincipalPolicy(\n \"group\",\n input.groupId,\n );\n\n if (!bundle) {\n throw new Error(\"Updated group policy could not be loaded\");\n }\n\n const signerPublicKeys = await collectGroupPolicySignerPublicKeys({\n bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const verified = await verifyGroupPolicy({\n currentPolicy: bundle,\n ...(input.externalAuthority\n ? { externalAuthority: input.externalAuthority }\n : {}),\n localPolicyCheckpoint: input.localPolicyCheckpoint ?? null,\n signerPublicKeys,\n });\n if (input.expectedCurrentHead) {\n assertPrincipalPolicyCurrentStateMatchesHead(\n bundle.currentState,\n input.expectedCurrentHead,\n );\n }\n if (input.acknowledgedMemberEnvelopes) {\n assertGroupPolicyEnvelopesMatchAcknowledgement(\n input.acknowledgedMemberEnvelopes,\n bundle.currentMemberEnvelopes,\n );\n }\n await persistVerifiedPrincipalPolicyBundlesAtomically({\n entries: [{ bundle, policy: verified }],\n execSql: input.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n updatedAt: new Date().toISOString(),\n });\n return bundle;\n}\n\nexport async function loadGroupPolicyMutationContext(input: {\n readonly apiClient: PrincipalPolicyReadApi;\n readonly execSql: ExecSql;\n readonly groupId: string;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<LoadedGroupPolicyMutationContext> {\n await input.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);\n const adminPolicy = await loadOrganizationExternalAdminPolicy({\n execSql: input.execSql,\n getCurrentPrincipalPolicy: (principalType, principalId) =>\n input.apiClient.getCurrentPrincipalPolicy(principalType, principalId),\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (!adminPolicy) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n const expectedGroupHead = requireOrganizationGroupHead(\n adminPolicy.descriptor,\n input.groupId,\n );\n const currentPolicy =\n input.groupId === adminPolicy.adminGroupId\n ? adminPolicy.adminBundle\n : await input.apiClient.getCurrentPrincipalPolicy(\"group\", input.groupId);\n if (!currentPolicy) {\n throw new Error(\"Group policy could not be loaded\");\n }\n assertPrincipalPolicyCurrentStateMatchesHead(\n currentPolicy.currentState,\n expectedGroupHead,\n );\n const verification = await prepareGroupPolicyVerification({\n currentPolicy,\n execSql: input.execSql,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const isOrganizationAdminsGroup = adminPolicy.adminGroupId === input.groupId;\n const currentOrgAdminUserIds = adminPolicy.signerUserIds;\n const externalAuthority = adminPolicy.externalAuthority;\n if (!currentOrgAdminUserIds.includes(input.signerUserId)) {\n throw new Error(\"Organization admin authority is required\");\n }\n const verified = isOrganizationAdminsGroup\n ? await verifyGroupPolicy({\n currentPolicy,\n localPolicyCheckpoint: verification.localPolicyCheckpoint,\n signerPublicKeys: verification.currentPolicySignerPublicKeys,\n })\n : await verifyGroupPolicyWithExternalOrganizationAdmins({\n currentPolicy,\n loadExternalAuthority: async () => externalAuthority,\n localPolicyCheckpoint: verification.localPolicyCheckpoint,\n signerPublicKeys: verification.currentPolicySignerPublicKeys,\n });\n assertGroupMetadataBinding(currentPolicy, adminPolicy.descriptor);\n requireSignerCanManageGroup(\n currentPolicy,\n currentOrgAdminUserIds,\n input.signerUserId,\n );\n await persistVerifiedPrincipalPolicyBundlesAtomically({\n entries: [\n ...externalAdminPolicyPersistenceEntries(adminPolicy).filter(\n (entry) =>\n entry.policy.principalType !== verified.principalType ||\n entry.policy.principalId !== verified.principalId,\n ),\n { bundle: currentPolicy, policy: verified },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n });\n\n return {\n adminGroupId: adminPolicy.adminGroupId,\n adminPolicyBundle: adminPolicy.adminBundle,\n currentPolicy,\n currentOrgAdminUserIds,\n externalAuthority,\n isOrganizationAdminsGroup,\n memberGroupId: adminPolicy.memberGroupId,\n organizationDescriptor: adminPolicy.descriptor,\n organizationPolicyBundle: adminPolicy.bundle,\n ...verification,\n localPolicyCheckpoint: verified.checkpoint,\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n };\n}\n\n/**\n * Commit, answering one refusal: a rematerialized rekey or revoke that would\n * strand a level above a directly granted container is refused with the\n * descendant rekeys it must carry. The refused attempt rolled back whole, so\n * the served heads still stand; the batch is signed again with the named\n * levels woven in, replaces the container mutations, and the commit is retried\n * once. A second refusal means the tree moved underneath, and the caller's own\n * retry starts from a fresh policy.\n */\nasync function submitGroupPolicyCommit(input: {\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly carryDescendantRekeys?:\n | ((\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n readonly groupId: string;\n readonly organizationId: string;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly request: PutPrincipalPolicyRequest;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<CommitOrganizationGroupPolicyResponse | null> {\n const body = () => ({\n groupPolicy: input.request,\n organizationPolicy: input.organizationRequest,\n });\n const { commitOrganizationGroupPolicyResult } = input.apiClient;\n if (!commitOrganizationGroupPolicyResult) {\n return input.apiClient.commitOrganizationGroupPolicy(\n input.organizationId,\n input.groupId,\n body(),\n );\n }\n const first = await commitOrganizationGroupPolicyResult.call(\n input.apiClient,\n input.organizationId,\n input.groupId,\n body(),\n { reportErrors: false },\n );\n if (first.ok) return first.data;\n if (first.kind === \"cancelled\") return null;\n if (first.kind === \"outcome-unknown\")\n throw new Error(\n first.message ??\n \"Policy request may have committed; refresh before retrying\",\n );\n if (\n !input.carryDescendantRekeys ||\n first.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !first.requiredContainerIds?.length\n ) {\n first.report?.();\n return null;\n }\n let carried: readonly ContainerMutationRequest[];\n try {\n carried = await input.carryDescendantRekeys(first.requiredContainerIds);\n } catch (error) {\n // The refusal was answerable, and the answer failed: surface both. Once\n // the generation that owned the attempt is gone, only the failure is\n // surfaced; a superseded refusal is not an error.\n if (input.stillCurrent?.() !== false) first.report?.();\n throw error;\n }\n if (input.stillCurrent?.() === false) return null;\n // Nothing signed means the same refusal again; report the one already had.\n if (carried.length === 0) {\n first.report?.();\n return null;\n }\n input.request.containerMutations = [...carried];\n const second = await commitOrganizationGroupPolicyResult.call(\n input.apiClient,\n input.organizationId,\n input.groupId,\n body(),\n { reportErrors: false },\n );\n if (!second.ok) {\n if (second.kind === \"cancelled\") return null;\n if (second.kind === \"outcome-unknown\")\n throw new Error(\n second.message ??\n \"Policy request may have committed; refresh before retrying\",\n );\n second.report?.();\n return null;\n }\n return second.data;\n}\n\nexport async function commitGroupPolicyMutation(input: {\n readonly retiredContainerIds?: (() => readonly string[]) | undefined;\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly execSql: ExecSql;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly groupId: string;\n readonly organizationId: string;\n readonly organizationPolicy: PrincipalPolicyBundleResponse;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n /**\n * Re-sign the batch with the descendant rekeys a refusal named woven in; the\n * result replaces `containerMutations` and the commit is retried once.\n */\n readonly carryDescendantRekeys?:\n | ((\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n readonly request: PutPrincipalPolicyRequest;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<PrincipalPolicyBundleResponse & PrincipalPolicyMutationResponse> {\n const stored = await submitGroupPolicyCommit(input);\n if (!stored) {\n throw new Error(\"Group policy update failed\");\n }\n const storedPolicy = stored.groupPolicy;\n const acknowledgedPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: input.currentPolicy,\n expectedHead: input.expectedHead,\n request: input.request,\n response: storedPolicy.currentState,\n });\n const groupBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.currentPolicy,\n expectedHead: input.expectedHead,\n request: input.request,\n response: storedPolicy,\n });\n const organizationHead = await groupPolicyMutationHead(\n input.organizationRequest,\n );\n const acknowledgedOrganization = await acknowledgeGroupPolicyState({\n currentPolicy: input.organizationPolicy,\n expectedHead: organizationHead,\n request: input.organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.organizationPolicy,\n expectedHead: organizationHead,\n request: input.organizationRequest,\n response: stored.organizationPolicy,\n });\n await retainLocallyAcknowledgedPrincipalPolicyBundles({\n retiredContainers: {\n containerIds: input.retiredContainerIds?.() ?? [],\n organizationId: input.organizationId,\n policy: acknowledgedPolicy,\n },\n entries: [\n { bundle: groupBundle, policy: acknowledgedPolicy },\n {\n bundle: organizationBundle,\n policy: acknowledgedOrganization,\n },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n updatedAt: new Date().toISOString(),\n });\n return groupBundle;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"groupPolicyMutationContext.js","sourceRoot":"","sources":["groupPolicyMutationContext.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RequestFailureKind } from \"@tearleads/api-client\";\nimport type {\n PrincipalPolicyCheckpoint,\n PrincipalPolicyExternalAuthority,\n ReferencedPrincipalHead,\n SigningKeyPair,\n} from \"@tearleads/crypto\";\nimport type {\n CommitOrganizationGroupPolicyRequest,\n ContainerMutationRequest,\n CreateOrganizationGroupWithPolicyRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type CommitOrganizationGroupPolicyResponse,\n type CreateOrganizationGroupResponse,\n type CurrentPrincipalMemberEnvelopesResponse,\n type PrincipalPolicyBundleResponse,\n type PrincipalPolicyMutationResponse,\n} from \"@tearleads/validators/response\";\nimport { persistVerifiedPrincipalPolicyBundlesAtomically } from \"../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { retainLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport { requireOrganizationGroupHead } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport {\n externalAdminPolicyPersistenceEntries,\n loadOrganizationExternalAdminPolicy,\n type VerifiedExternalAdminPolicy,\n} from \"../principals/externalAdminPolicy\";\nimport { assertGroupMetadataBinding } from \"./groupMetadataBinding\";\nimport { requireSignerCanManageGroup } from \"./groupMutationAuthorization\";\nimport {\n acknowledgeGroupPolicyState,\n assertGroupPolicyEnvelopesMatchAcknowledgement,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { FullGroupMembershipMutationInput } from \"./groupPolicyMutationEvidence\";\nimport {\n assertPrincipalPolicyCurrentStateMatchesHead,\n groupPolicyMutationHead,\n} from \"./groupPolicyMutationHead\";\nimport {\n collectGroupPolicySignerPublicKeys,\n prepareGroupPolicyVerification,\n verifyGroupPolicy,\n verifyGroupPolicyWithExternalOrganizationAdmins,\n} from \"./groupPolicyVerification\";\n\nexport interface PrincipalPolicyReadApi {\n /** Resolve authored work before reading the state for a new mutation. */\n readonly recoverPendingPrincipalMutation?:\n | ((organizationId: string) => Promise<void>)\n | undefined;\n getCurrentPrincipalPolicy: (\n principalType: \"group\" | \"organization\",\n principalId: string,\n ) => Promise<PrincipalPolicyBundleResponse | null>;\n}\n\nexport interface PrincipalPolicyReadWriteApi extends PrincipalPolicyReadApi {\n commitOrganizationGroupPolicy: (\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n ) => Promise<CommitOrganizationGroupPolicyResponse | null>;\n /**\n * Optional status-bearing variant. A rematerialized rotation the server\n * refuses for stranding a granted path names the descendant rekeys the batch\n * must carry; without this the refusal is a plain failure.\n */\n commitOrganizationGroupPolicyResult?: (\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n options?: { readonly reportErrors?: boolean | undefined },\n ) => Promise<\n | {\n readonly ok: true;\n readonly data: CommitOrganizationGroupPolicyResponse;\n }\n | {\n readonly ok: false;\n readonly kind?: RequestFailureKind | undefined;\n readonly message?: string | undefined;\n readonly code?: string | undefined;\n readonly report?: (() => void) | undefined;\n readonly requiredContainerIds?: readonly string[] | undefined;\n readonly status: number | null;\n }\n >;\n}\n\nexport interface OrganizationPrincipalPolicyApi extends PrincipalPolicyReadApi {\n createOrganizationGroup: (\n organizationId: string,\n input: CreateOrganizationGroupWithPolicyRequest,\n ) => Promise<CreateOrganizationGroupResponse | null>;\n}\n\ninterface LoadedGroupPolicyMutationContext\n extends FullGroupMembershipMutationInput {\n readonly adminGroupId: string;\n readonly adminPolicyBundle: PrincipalPolicyBundleResponse;\n readonly currentOrgAdminUserIds: readonly string[];\n readonly organizationDescriptor: VerifiedExternalAdminPolicy[\"descriptor\"];\n readonly organizationPolicyBundle: PrincipalPolicyBundleResponse;\n readonly memberGroupId: string;\n}\n\nexport async function cacheGroupPolicy(input: {\n readonly acknowledgedMemberEnvelopes?:\n | CurrentPrincipalMemberEnvelopesResponse\n | undefined;\n readonly apiClient: PrincipalPolicyReadApi;\n readonly externalAuthority?: PrincipalPolicyExternalAuthority | undefined;\n readonly execSql: ExecSql;\n readonly expectedCurrentHead?: ReferencedPrincipalHead | undefined;\n readonly groupId: string;\n readonly localPolicyCheckpoint?: PrincipalPolicyCheckpoint | null;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<PrincipalPolicyBundleResponse> {\n const bundle = await input.apiClient.getCurrentPrincipalPolicy(\n \"group\",\n input.groupId,\n );\n\n if (!bundle) {\n throw new Error(\"Updated group policy could not be loaded\");\n }\n\n const signerPublicKeys = await collectGroupPolicySignerPublicKeys({\n bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const verified = await verifyGroupPolicy({\n currentPolicy: bundle,\n ...(input.externalAuthority\n ? { externalAuthority: input.externalAuthority }\n : {}),\n localPolicyCheckpoint: input.localPolicyCheckpoint ?? null,\n signerPublicKeys,\n });\n if (input.expectedCurrentHead) {\n assertPrincipalPolicyCurrentStateMatchesHead(\n bundle.currentState,\n input.expectedCurrentHead,\n );\n }\n if (input.acknowledgedMemberEnvelopes) {\n assertGroupPolicyEnvelopesMatchAcknowledgement(\n input.acknowledgedMemberEnvelopes,\n bundle.currentMemberEnvelopes,\n );\n }\n await persistVerifiedPrincipalPolicyBundlesAtomically({\n entries: [{ bundle, policy: verified }],\n execSql: input.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n updatedAt: new Date().toISOString(),\n });\n return bundle;\n}\n\nexport async function loadGroupPolicyMutationContext(input: {\n readonly apiClient: PrincipalPolicyReadApi;\n readonly execSql: ExecSql;\n readonly groupId: string;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<LoadedGroupPolicyMutationContext> {\n await input.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);\n const adminPolicy = await loadOrganizationExternalAdminPolicy({\n execSql: input.execSql,\n getCurrentPrincipalPolicy: (principalType, principalId) =>\n input.apiClient.getCurrentPrincipalPolicy(principalType, principalId),\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (!adminPolicy) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n const expectedGroupHead = requireOrganizationGroupHead(\n adminPolicy.descriptor,\n input.groupId,\n );\n const currentPolicy =\n input.groupId === adminPolicy.adminGroupId\n ? adminPolicy.adminBundle\n : await input.apiClient.getCurrentPrincipalPolicy(\"group\", input.groupId);\n if (!currentPolicy) {\n throw new Error(\"Group policy could not be loaded\");\n }\n assertPrincipalPolicyCurrentStateMatchesHead(\n currentPolicy.currentState,\n expectedGroupHead,\n );\n const verification = await prepareGroupPolicyVerification({\n currentPolicy,\n execSql: input.execSql,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const isOrganizationAdminsGroup = adminPolicy.adminGroupId === input.groupId;\n const currentOrgAdminUserIds = adminPolicy.signerUserIds;\n const externalAuthority = adminPolicy.externalAuthority;\n if (!currentOrgAdminUserIds.includes(input.signerUserId)) {\n throw new Error(\"Organization admin authority is required\");\n }\n const verified = isOrganizationAdminsGroup\n ? await verifyGroupPolicy({\n currentPolicy,\n localPolicyCheckpoint: verification.localPolicyCheckpoint,\n signerPublicKeys: verification.currentPolicySignerPublicKeys,\n })\n : await verifyGroupPolicyWithExternalOrganizationAdmins({\n currentPolicy,\n loadExternalAuthority: async () => externalAuthority,\n localPolicyCheckpoint: verification.localPolicyCheckpoint,\n signerPublicKeys: verification.currentPolicySignerPublicKeys,\n });\n assertGroupMetadataBinding(currentPolicy, adminPolicy.descriptor);\n requireSignerCanManageGroup(\n currentPolicy,\n currentOrgAdminUserIds,\n input.signerUserId,\n );\n await persistVerifiedPrincipalPolicyBundlesAtomically({\n entries: [\n ...externalAdminPolicyPersistenceEntries(adminPolicy).filter(\n (entry) =>\n entry.policy.principalType !== verified.principalType ||\n entry.policy.principalId !== verified.principalId,\n ),\n { bundle: currentPolicy, policy: verified },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n });\n\n return {\n adminGroupId: adminPolicy.adminGroupId,\n adminPolicyBundle: adminPolicy.adminBundle,\n currentPolicy,\n currentOrgAdminUserIds,\n externalAuthority,\n isOrganizationAdminsGroup,\n memberGroupId: adminPolicy.memberGroupId,\n organizationDescriptor: adminPolicy.descriptor,\n organizationPolicyBundle: adminPolicy.bundle,\n ...verification,\n localPolicyCheckpoint: verified.checkpoint,\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n };\n}\n\n/**\n * Commit, answering one refusal: a rematerialized rekey or revoke that would\n * strand a level above a directly granted container is refused with the\n * descendant rekeys it must carry. The refused attempt rolled back whole, so\n * the served heads still stand; the batch is signed again with the named\n * levels woven in, replaces the container mutations, and the commit is retried\n * once. A second refusal means the tree moved underneath, and the caller's own\n * retry starts from a fresh policy.\n */\nexport async function submitGroupPolicyCommit(input: {\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly carryDescendantRekeys?:\n | ((\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n readonly groupId: string;\n readonly organizationId: string;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly request: PutPrincipalPolicyRequest;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<CommitOrganizationGroupPolicyResponse | null> {\n const body = () => ({\n groupPolicy: input.request,\n organizationPolicy: input.organizationRequest,\n });\n const { commitOrganizationGroupPolicyResult } = input.apiClient;\n if (!commitOrganizationGroupPolicyResult) {\n return input.apiClient.commitOrganizationGroupPolicy(\n input.organizationId,\n input.groupId,\n body(),\n );\n }\n const first = await commitOrganizationGroupPolicyResult.call(\n input.apiClient,\n input.organizationId,\n input.groupId,\n body(),\n { reportErrors: false },\n );\n if (first.ok) return first.data;\n if (first.kind === \"cancelled\") return null;\n if (first.kind === \"outcome-unknown\")\n throw new Error(\n first.message ??\n \"Policy request may have committed; refresh before retrying\",\n );\n if (\n !input.carryDescendantRekeys ||\n first.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !first.requiredContainerIds?.length\n ) {\n first.report?.();\n return null;\n }\n let carried: readonly ContainerMutationRequest[];\n try {\n carried = await input.carryDescendantRekeys(first.requiredContainerIds);\n } catch (error) {\n // The refusal was answerable, and the answer failed: surface both. Once\n // the generation that owned the attempt is gone, only the failure is\n // surfaced; a superseded refusal is not an error.\n if (input.stillCurrent?.() !== false) first.report?.();\n throw error;\n }\n if (input.stillCurrent?.() === false) return null;\n // Nothing signed means the same refusal again; report the one already had.\n if (carried.length === 0) {\n first.report?.();\n return null;\n }\n input.request.containerMutations = [...carried];\n const second = await commitOrganizationGroupPolicyResult.call(\n input.apiClient,\n input.organizationId,\n input.groupId,\n body(),\n { reportErrors: false },\n );\n if (!second.ok) {\n if (second.kind === \"cancelled\") return null;\n if (second.kind === \"outcome-unknown\")\n throw new Error(\n second.message ??\n \"Policy request may have committed; refresh before retrying\",\n );\n second.report?.();\n return null;\n }\n return second.data;\n}\n\nexport async function commitGroupPolicyMutation(input: {\n readonly retiredContainerIds?: (() => readonly string[]) | undefined;\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly execSql: ExecSql;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly groupId: string;\n readonly organizationId: string;\n readonly organizationPolicy: PrincipalPolicyBundleResponse;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n /**\n * Re-sign the batch with the descendant rekeys a refusal named woven in; the\n * result replaces `containerMutations` and the commit is retried once.\n */\n readonly carryDescendantRekeys?:\n | ((\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n readonly request: PutPrincipalPolicyRequest;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<PrincipalPolicyBundleResponse & PrincipalPolicyMutationResponse> {\n const stored = await submitGroupPolicyCommit(input);\n if (!stored) {\n throw new Error(\"Group policy update failed\");\n }\n const storedPolicy = stored.groupPolicy;\n const acknowledgedPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: input.currentPolicy,\n expectedHead: input.expectedHead,\n request: input.request,\n response: storedPolicy.currentState,\n });\n const groupBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.currentPolicy,\n expectedHead: input.expectedHead,\n request: input.request,\n response: storedPolicy,\n });\n const organizationHead = await groupPolicyMutationHead(\n input.organizationRequest,\n );\n const acknowledgedOrganization = await acknowledgeGroupPolicyState({\n currentPolicy: input.organizationPolicy,\n expectedHead: organizationHead,\n request: input.organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.organizationPolicy,\n expectedHead: organizationHead,\n request: input.organizationRequest,\n response: stored.organizationPolicy,\n });\n await retainLocallyAcknowledgedPrincipalPolicyBundles({\n retiredContainers: {\n containerIds: input.retiredContainerIds?.() ?? [],\n organizationId: input.organizationId,\n policy: acknowledgedPolicy,\n },\n entries: [\n { bundle: groupBundle, policy: acknowledgedPolicy },\n {\n bundle: organizationBundle,\n policy: acknowledgedOrganization,\n },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n updatedAt: new Date().toISOString(),\n });\n return groupBundle;\n}\n"]}
|
|
@@ -14,6 +14,7 @@ export { buildOrganizationProfileDocumentPatch, createInitializedOrganizationPro
|
|
|
14
14
|
export { type ImportedOrganizationUser, importOrganizationUser, } from "./organizationUserImport.js";
|
|
15
15
|
export { abandonJournaledPrincipalMutation, discardUnreadableJournaledPrincipalMutation, readJournaledPrincipalMutation, } from "./principalMutationJournalManagement.js";
|
|
16
16
|
export { type PrincipalMutationJournalContext, PrincipalMutationOutcomeUnknownError, recoverJournaledPrincipalMutation, submitJournaledPrincipalMutation, } from "./principalMutationJournalSession.js";
|
|
17
|
+
export type { PrincipalMutationResponse } from "./principalOperationReceipt.js";
|
|
17
18
|
export { addOrganizationGroupUser, buildInitialGroupPolicyRequest, buildInitialMemberGroupPolicyRequest, createOrganizationGroup, removeOrganizationGroupUser, rotateOrganizationGroupForAccessSetShrink, } from "./principalPolicy.js";
|
|
18
19
|
export { buildOrganizationGroupPolicyHistory, type OrganizationContainerGrant, type OrganizationContainerGrants, type OrganizationDirectory, type OrganizationDirectoryAndGroups, type OrganizationDirectoryUser, type OrganizationGroupContainer, type OrganizationGroupContainers, type OrganizationGroupDetails, type OrganizationGroupMember, type OrganizationGroupMembers, type OrganizationGroupPolicyHistory, type OrganizationGroupPolicyHistoryEntry, type OrganizationGroupSummary, type OrganizationPolicyGrantChange, type OrganizationPolicyGroupChange, type OrganizationPolicyHistory, type OrganizationPolicyHistoryEntry, type OrganizationPrincipalMemberChange, type OrganizationPrincipalMemberChangeType, type OrganizationPrincipalPolicyHistory, type OrganizationPrincipalPolicyHistoryEntry, type OrganizationProfile, type OrganizationUserDetail, updateOrganizationProfile, updateOrganizationRosterEntry, } from "./readModel.js";
|
|
19
20
|
export { loadLocalOrganizationDirectoryAndGroups, loadLocalOrganizationGroupMembers, type ReconcileOrganizationDirectoryAndGroupsInput, reconcileOrganizationDirectoryAndGroups, } from "./readModelProjection.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0CAA0C,GAC3C,MAAM,wEAAwE,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,4DAA4D,CAAC;AAK3G,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AACxG,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,uBAAuB,EACvB,8BAA8B,EAC9B,oCAAoC,EACpC,yBAAyB,EAOzB,8BAA8B,EAG9B,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAGL,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,8BAA8B,EAG9B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,kCAAkC,EAClC,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,qCAAqC,EACrC,4CAA4C,EAC5C,0CAA0C,EAC1C,qCAAqC,EACrC,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,2CAA2C,EAC3C,8BAA8B,GAC/B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAEL,oCAAoC,EACpC,iCAAiC,EACjC,gCAAgC,GACjC,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0CAA0C,GAC3C,MAAM,wEAAwE,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,4DAA4D,CAAC;AAK3G,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AACxG,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,uBAAuB,EACvB,8BAA8B,EAC9B,oCAAoC,EACpC,yBAAyB,EAOzB,8BAA8B,EAG9B,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAGL,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,8BAA8B,EAG9B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,kCAAkC,EAClC,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,qCAAqC,EACrC,4CAA4C,EAC5C,0CAA0C,EAC1C,qCAAqC,EACrC,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,2CAA2C,EAC3C,8BAA8B,GAC/B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAEL,oCAAoC,EACpC,iCAAiC,EACjC,gCAAgC,GACjC,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,oCAAoC,EACpC,uBAAuB,EACvB,2BAA2B,EAC3B,yCAAyC,GAC1C,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mCAAmC,EAwBnC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uCAAuC,EACvC,iCAAiC,EAEjC,uCAAuC,GACxC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,+BAA+B,EAC/B,sCAAsC,EACtC,6CAA6C,EAC7C,kDAAkD,EAClD,+BAA+B,EAC/B,oCAAoC,EACpC,0CAA0C,EAC1C,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC","sourcesContent":["export {\n type OrganizationReadModelInvalidationListener,\n subscribeOrganizationReadModelInvalidation,\n} from \"../../data/persistence/organizations/organizationReadModelInvalidation\";\nexport { PendingPrincipalMutationError } from \"../../data/persistence/principalMutationJournalPersistence\";\nexport type {\n AuthoredPrincipalMutation,\n PrincipalMutationJournalScope,\n} from \"../../data/principals/principalMutationJournal\";\nexport { UnreadablePrincipalMutationError } from \"../../data/principals/principalMutationJournalRecord\";\nexport {\n cancelStripeSubscription,\n checkNativePurchaseEligibility,\n claimNativeOrganizationSubscription,\n createStripeCheckout,\n createStripeCheckoutSession,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n loadStripeCheckoutOptions,\n type OrganizationBilling,\n type OrganizationBillingHistory,\n type OrganizationBillingHistoryEntry,\n type OrganizationBillingManagementUrl,\n type OrganizationBillingView,\n type OrganizationNativePurchaseEligibility,\n resolveOrganizationBillingView,\n type StripeCheckoutIntent,\n type StripeCheckoutOptions,\n startOrganizationTrial,\n} from \"./billing\";\nexport { revokeOrganizationContainerGrant } from \"./containerGrantRevocation\";\nexport {\n type CreateOrganizationApi,\n type CreateOrganizationInput,\n createOrganization,\n} from \"./createOrganization\";\nexport {\n loadLocalOrganizationDataUsage,\n type OrganizationDataUsage,\n type ReconcileOrganizationDataUsageInput,\n reconcileOrganizationDataUsage,\n} from \"./dataUsageReadModel\";\nexport { deleteOrganizationGroup } from \"./deleteOrganizationGroup\";\nexport { GroupMembershipNameMismatchError } from \"./groupMembershipName\";\nexport {\n type LocalOrganizationSummary,\n listLocalOrganizations,\n} from \"./listLocalOrganizations\";\nexport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupPolicyHistory,\n loadLocalOrganizationPolicyHistory,\n loadLocalOrganizationPolicyReference,\n loadLocalOrganizationUserDetail,\n} from \"./localReadModelDetails\";\nexport {\n buildOrganizationProfileDocumentPatch,\n createInitializedOrganizationProfileDocument,\n DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME,\n getOrganizationProfileDocumentLocalId,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n readOrganizationProfileName,\n} from \"./organizationProfile\";\nexport {\n type ImportedOrganizationUser,\n importOrganizationUser,\n} from \"./organizationUserImport\";\nexport {\n abandonJournaledPrincipalMutation,\n discardUnreadableJournaledPrincipalMutation,\n readJournaledPrincipalMutation,\n} from \"./principalMutationJournalManagement\";\nexport {\n type PrincipalMutationJournalContext,\n PrincipalMutationOutcomeUnknownError,\n recoverJournaledPrincipalMutation,\n submitJournaledPrincipalMutation,\n} from \"./principalMutationJournalSession\";\nexport type { PrincipalMutationResponse } from \"./principalOperationReceipt\";\nexport {\n addOrganizationGroupUser,\n buildInitialGroupPolicyRequest,\n buildInitialMemberGroupPolicyRequest,\n createOrganizationGroup,\n removeOrganizationGroupUser,\n rotateOrganizationGroupForAccessSetShrink,\n} from \"./principalPolicy\";\nexport {\n buildOrganizationGroupPolicyHistory,\n type OrganizationContainerGrant,\n type OrganizationContainerGrants,\n type OrganizationDirectory,\n type OrganizationDirectoryAndGroups,\n type OrganizationDirectoryUser,\n type OrganizationGroupContainer,\n type OrganizationGroupContainers,\n type OrganizationGroupDetails,\n type OrganizationGroupMember,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationGroupPolicyHistoryEntry,\n type OrganizationGroupSummary,\n type OrganizationPolicyGrantChange,\n type OrganizationPolicyGroupChange,\n type OrganizationPolicyHistory,\n type OrganizationPolicyHistoryEntry,\n type OrganizationPrincipalMemberChange,\n type OrganizationPrincipalMemberChangeType,\n type OrganizationPrincipalPolicyHistory,\n type OrganizationPrincipalPolicyHistoryEntry,\n type OrganizationProfile,\n type OrganizationUserDetail,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n} from \"./readModel\";\nexport {\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupMembers,\n type ReconcileOrganizationDirectoryAndGroupsInput,\n reconcileOrganizationDirectoryAndGroups,\n} from \"./readModelProjection\";\nexport {\n type AcknowledgedPrincipalCurrentInput,\n type AcknowledgedPrincipalCurrentRetirement,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\nexport {\n buildRosterProfileDocumentPatch,\n createInitializedRosterProfileDocument,\n deriveOrganizationMetadataContainerSystemSlot,\n deriveOrganizationRosterProfileContainerSystemSlot,\n getRosterProfileDocumentLocalId,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n ROSTER_PROFILE_DOCUMENT_KIND,\n} from \"./rosterProfileContainer\";\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createPrincipalPolicyHistoryVerifier, KeyingVerificationError, verifyPrincipalPolicyCurrent, } from "../../internal/crypto/index.js";
|
|
2
|
+
import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
|
|
3
|
+
import { preparePrincipalHistoryEvidencePage } from "../../data/persistence/principalHistoryEvidencePersistence.js";
|
|
4
|
+
import { principalHeadMatchesReference } from "../../data/principals/organizationAuthorityDescriptor.js";
|
|
5
|
+
import { principalHistoryEvidenceScopeId } from "../../data/principals/principalHistoryPrefixProtection.js";
|
|
6
|
+
import { collectPrincipalPolicySignerPublicKeys } from "../principals/policyVerification.js";
|
|
7
|
+
import { assertPrincipalHistoryVerificationMode, principalHistoryVerificationContext, } from "../principals/principalHistoryRecoveryVerification.js";
|
|
8
|
+
import { groupPolicyMutationHead } from "./groupPolicyMutationHead.js";
|
|
9
|
+
import { sealPrincipalCurrentPublication } from "./principalCurrentPublicationSeal.js";
|
|
10
|
+
import { assertPrincipalPolicyReceiptArtifacts } from "./principalPolicyReceiptArtifacts.js";
|
|
11
|
+
/** Verify a newly authored group from genesis before its atomic directory publication. */
|
|
12
|
+
export async function prepareInitialGroupCurrentPublication(input, request, response) {
|
|
13
|
+
const current = () => !input.signal?.aborted && input.stillCurrent();
|
|
14
|
+
assertProjectionVerificationCurrent(current);
|
|
15
|
+
const expectedHead = await groupPolicyMutationHead(request);
|
|
16
|
+
if (request.state.principalType !== "group" ||
|
|
17
|
+
request.state.version !== 1 ||
|
|
18
|
+
request.state.prevStateHash !== null ||
|
|
19
|
+
!principalHeadMatchesReference(expectedHead, input.expectedHead))
|
|
20
|
+
throw new KeyingVerificationError("object_mismatch", "Initial group publication must begin at its exact genesis");
|
|
21
|
+
assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });
|
|
22
|
+
const keys = await collectPrincipalPolicySignerPublicKeys({
|
|
23
|
+
bundle: { currentState: response.currentState, previousStates: [] },
|
|
24
|
+
resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,
|
|
25
|
+
});
|
|
26
|
+
if ("error" in keys)
|
|
27
|
+
throw new KeyingVerificationError("signer_mismatch", "Initial group signer could not be authenticated");
|
|
28
|
+
const externalAuthority = await input.loadExternalAuthority?.(request.state.externalAuthority ? [request.state.externalAuthority] : []);
|
|
29
|
+
assertProjectionVerificationCurrent(current);
|
|
30
|
+
const verifier = createPrincipalPolicyHistoryVerifier({
|
|
31
|
+
principalType: "group",
|
|
32
|
+
principalId: expectedHead.principalId,
|
|
33
|
+
});
|
|
34
|
+
const entry = {
|
|
35
|
+
state: response.currentState,
|
|
36
|
+
projection: response.currentProjection,
|
|
37
|
+
grants: response.currentGrants,
|
|
38
|
+
};
|
|
39
|
+
assertPrincipalHistoryVerificationMode(input, [entry]);
|
|
40
|
+
const appended = await verifier.append({
|
|
41
|
+
entries: [entry],
|
|
42
|
+
signerPublicKeys: keys.signerPublicKeys,
|
|
43
|
+
...(externalAuthority ? { externalAuthority } : {}),
|
|
44
|
+
});
|
|
45
|
+
if (!appended.ok)
|
|
46
|
+
throw appended.error;
|
|
47
|
+
const history = verifier.finish(expectedHead);
|
|
48
|
+
if (!history.ok)
|
|
49
|
+
throw history.error;
|
|
50
|
+
const policy = await verifyPrincipalPolicyCurrent({
|
|
51
|
+
current: response,
|
|
52
|
+
history: history.value,
|
|
53
|
+
});
|
|
54
|
+
if (!policy.ok)
|
|
55
|
+
throw policy.error;
|
|
56
|
+
const options = {
|
|
57
|
+
...input,
|
|
58
|
+
protection: {
|
|
59
|
+
...input.protection,
|
|
60
|
+
context: principalHistoryVerificationContext(input),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const scopeId = await principalHistoryEvidenceScopeId({
|
|
64
|
+
organizationId: input.organizationId,
|
|
65
|
+
head: expectedHead,
|
|
66
|
+
protection: options.protection,
|
|
67
|
+
});
|
|
68
|
+
const sealed = await sealPrincipalCurrentPublication(options, scopeId, expectedHead, verifier, response);
|
|
69
|
+
assertProjectionVerificationCurrent(current);
|
|
70
|
+
return {
|
|
71
|
+
...sealed,
|
|
72
|
+
policy: policy.value,
|
|
73
|
+
predecessorStage: null,
|
|
74
|
+
previousPrefixProgress: null,
|
|
75
|
+
evidence: await preparePrincipalHistoryEvidencePage({
|
|
76
|
+
scopeId,
|
|
77
|
+
organizationId: input.organizationId,
|
|
78
|
+
entries: [entry],
|
|
79
|
+
nodes: appended.value.indexNodes,
|
|
80
|
+
}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=initialPrincipalCurrentPublication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialPrincipalCurrentPublication.js","sourceRoot":"","sources":["initialPrincipalCurrentPublication.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createPrincipalPolicyHistoryVerifier,\n KeyingVerificationError,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { AcknowledgedPrincipalCurrentPublication } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { preparePrincipalHistoryEvidencePage } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport { principalHeadMatchesReference } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { principalHistoryEvidenceScopeId } from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"../principals/policyVerification\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport {\n assertPrincipalHistoryVerificationMode,\n principalHistoryVerificationContext,\n} from \"../principals/principalHistoryRecoveryVerification\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { sealPrincipalCurrentPublication } from \"./principalCurrentPublicationSeal\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\n/** Verify a newly authored group from genesis before its atomic directory publication. */\nexport async function prepareInitialGroupCurrentPublication(\n input: RecoverPrincipalPolicyHistoryOptions,\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n): Promise<AcknowledgedPrincipalCurrentPublication> {\n const current = () => !input.signal?.aborted && input.stillCurrent();\n assertProjectionVerificationCurrent(current);\n const expectedHead = await groupPolicyMutationHead(request);\n if (\n request.state.principalType !== \"group\" ||\n request.state.version !== 1 ||\n request.state.prevStateHash !== null ||\n !principalHeadMatchesReference(expectedHead, input.expectedHead)\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Initial group publication must begin at its exact genesis\",\n );\n assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });\n const keys = await collectPrincipalPolicySignerPublicKeys({\n bundle: { currentState: response.currentState, previousStates: [] },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in keys)\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"Initial group signer could not be authenticated\",\n );\n const externalAuthority = await input.loadExternalAuthority?.(\n request.state.externalAuthority ? [request.state.externalAuthority] : [],\n );\n assertProjectionVerificationCurrent(current);\n const verifier = createPrincipalPolicyHistoryVerifier({\n principalType: \"group\",\n principalId: expectedHead.principalId,\n });\n const entry = {\n state: response.currentState,\n projection: response.currentProjection,\n grants: response.currentGrants,\n };\n assertPrincipalHistoryVerificationMode(input, [entry]);\n const appended = await verifier.append({\n entries: [entry],\n signerPublicKeys: keys.signerPublicKeys,\n ...(externalAuthority ? { externalAuthority } : {}),\n });\n if (!appended.ok) throw appended.error;\n const history = verifier.finish(expectedHead);\n if (!history.ok) throw history.error;\n const policy = await verifyPrincipalPolicyCurrent({\n current: response,\n history: history.value,\n });\n if (!policy.ok) throw policy.error;\n const options = {\n ...input,\n protection: {\n ...input.protection,\n context: principalHistoryVerificationContext(input),\n },\n };\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: input.organizationId,\n head: expectedHead,\n protection: options.protection,\n });\n const sealed = await sealPrincipalCurrentPublication(\n options,\n scopeId,\n expectedHead,\n verifier,\n response,\n );\n assertProjectionVerificationCurrent(current);\n return {\n ...sealed,\n policy: policy.value,\n predecessorStage: null,\n previousPrefixProgress: null,\n evidence: await preparePrincipalHistoryEvidencePage({\n scopeId,\n organizationId: input.organizationId,\n entries: [entry],\n nodes: appended.value.indexNodes,\n }),\n };\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { buildPrincipalStateSigningInput, generateKemSeedAndKeyPair, normalizePrincipalProjectionMembers, signPrincipalState, toFingerprint, } from "../../internal/crypto/index.js";
|
|
2
2
|
import { bytesToBase64 } from "../../internal/encoding/index.js";
|
|
3
|
+
import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
|
|
3
4
|
import { persistLocallyAcknowledgedPrincipalPolicyBundles } from "../../data/persistence/locallyAcknowledgedCheckpointPersistence.js";
|
|
4
5
|
import { encodeOrganizationAuthorityDescriptor, normalizeOrganizationGroupHeads, } from "../../data/principals/organizationAuthorityDescriptor.js";
|
|
5
6
|
import { assertGroupNameUniqueInDirectory } from "./groupNameUniqueness.js";
|
|
@@ -78,6 +79,7 @@ export async function buildOrganizationGroupDirectoryPolicyRequest(input) {
|
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
export async function commitCreatedGroupToDirectory(input) {
|
|
82
|
+
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
81
83
|
// Signed group names are unique per organization; refuse a collision before
|
|
82
84
|
// anything reaches the server.
|
|
83
85
|
await assertGroupNameUniqueInDirectory({
|
|
@@ -110,7 +112,9 @@ export async function commitCreatedGroupToDirectory(input) {
|
|
|
110
112
|
signingFingerprint: input.signingFingerprint,
|
|
111
113
|
signingKeyPair: input.signingKeyPair,
|
|
112
114
|
});
|
|
115
|
+
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
113
116
|
const stored = await input.apiClient.createOrganizationGroup(input.organizationId, { ...input.request, organizationPolicy: organizationRequest });
|
|
117
|
+
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
114
118
|
if (!stored) {
|
|
115
119
|
throw new Error("Group could not be created");
|
|
116
120
|
}
|
|
@@ -141,7 +145,9 @@ export async function commitCreatedGroupToDirectory(input) {
|
|
|
141
145
|
execSql: input.execSql,
|
|
142
146
|
organizationId: input.organizationId,
|
|
143
147
|
updatedAt: new Date().toISOString(),
|
|
148
|
+
stillCurrent: input.stillCurrent,
|
|
144
149
|
});
|
|
150
|
+
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
145
151
|
return { group: stored.group, head: expectedHead };
|
|
146
152
|
}
|
|
147
153
|
//# sourceMappingURL=organizationGroupDirectory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationGroupDirectory.js","sourceRoot":"","sources":["organizationGroupDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildPrincipalStateSigningInput,\n generateKemSeedAndKeyPair,\n normalizePrincipalProjectionMembers,\n type ReferencedPrincipalHead,\n type SigningKeyPair,\n signPrincipalState,\n toFingerprint,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n PrincipalProjectionMemberRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationGroupSummaryResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport { persistLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport {\n encodeOrganizationAuthorityDescriptor,\n normalizeOrganizationGroupHeads,\n type OrganizationAuthorityDescriptor,\n type OrganizationGroupHead,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type {\n TrustedUserIdentity,\n TrustedUserIdentityResolver,\n} from \"../../data/trustedUserIdentity\";\nimport type { loadOrganizationExternalAdminPolicy } from \"../principals/externalAdminPolicy\";\nimport { assertGroupNameUniqueInDirectory } from \"./groupNameUniqueness\";\nimport {\n acknowledgeGroupPolicyState,\n acknowledgeInitialGroupPolicy,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { OrganizationPrincipalPolicyApi } from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { rewrapProjectionMemberEnvelopes } from \"./principalPolicyRecipients\";\nimport type {\n buildInitialGroupPolicyRequest,\n GroupPolicyNameReader,\n} from \"./principalPolicyRequest\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"./trustedOrganizationUsers\";\n\nfunction organizationGroupHead(\n head: ReferencedPrincipalHead,\n): OrganizationGroupHead {\n if (head.principalType !== \"group\") {\n throw new Error(\"Organization directory can contain only group heads\");\n }\n return { ...head, principalType: \"group\" };\n}\n\nexport function replaceOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly nextHead: ReferencedPrincipalHead;\n}): OrganizationGroupHead[] {\n const nextHead = organizationGroupHead(input.nextHead);\n return normalizeOrganizationGroupHeads([\n ...input.descriptor.groupHeads.filter(\n (head) => head.principalId !== nextHead.principalId,\n ),\n nextHead,\n ]);\n}\n\nexport function removeOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupId: string;\n}): OrganizationGroupHead[] {\n if (\n input.groupId === input.descriptor.adminGroupId ||\n input.groupId === input.descriptor.memberGroupId\n ) {\n throw new Error(\"Built-in groups cannot be removed from the directory\");\n }\n const groupHeads = input.descriptor.groupHeads.filter(\n (head) => head.principalId !== input.groupId,\n );\n if (groupHeads.length === input.descriptor.groupHeads.length) {\n throw new Error(\"Organization directory does not commit the deleted group\");\n }\n return normalizeOrganizationGroupHeads(groupHeads);\n}\n\nexport async function buildOrganizationGroupDirectoryPolicyRequest(input: {\n readonly adminProjection: readonly PrincipalProjectionMemberRequest[];\n readonly adminUsers: readonly TrustedUserIdentity[];\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupHeads: readonly OrganizationGroupHead[];\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<PutPrincipalPolicyRequest> {\n const projection = normalizePrincipalProjectionMembers(input.adminProjection);\n if (\n projection.length === 0 ||\n projection.some((member) => member.role !== \"admin\")\n ) {\n throw new Error(\"Organization policy must mirror the Admins projection\");\n }\n const organizationKem = generateKemSeedAndKeyPair();\n const memberEnvelopes = await rewrapProjectionMemberEnvelopes({\n projection,\n secretKey: organizationKem.secretKey,\n users: input.adminUsers,\n });\n const payloadCiphertext = encodeOrganizationAuthorityDescriptor({\n ...input.descriptor,\n groupHeads: input.groupHeads,\n });\n const state = await signPrincipalState(\n await buildPrincipalStateSigningInput({\n principalType: \"organization\",\n principalId: input.descriptor.organizationId,\n version: input.currentPolicy.currentState.version + 1,\n prevStateHash: input.currentPolicy.currentState.stateHash,\n keyEpoch: input.currentPolicy.currentState.keyEpoch + 1,\n encapsulationPublicKey: bytesToBase64(organizationKem.publicKey),\n keyFingerprint: await toFingerprint(organizationKem.publicKey),\n members: projection.map((member) => ({ userId: member.userId })),\n memberEnvelopes,\n projection,\n grants: [],\n payloadCiphertext,\n externalAuthority: null,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signerUserKeyFingerprint: input.signingFingerprint,\n }),\n input.signingKeyPair.signingPrivateKey,\n );\n\n return {\n encryptedPayload: {\n cipherSuite: \"aes-256-gcm\",\n ciphertext: payloadCiphertext,\n ciphertextHash: state.payloadCiphertextHash,\n },\n grants: [],\n memberEnvelopes,\n projection,\n state,\n };\n}\n\nexport async function commitCreatedGroupToDirectory(input: {\n readonly name: string;\n readonly readEncryptedName?: GroupPolicyNameReader;\n readonly apiClient: OrganizationPrincipalPolicyApi;\n readonly execSql: ExecSql;\n readonly externalAdminPolicy: NonNullable<\n Awaited<ReturnType<typeof loadOrganizationExternalAdminPolicy>>\n >;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly request: Awaited<ReturnType<typeof buildInitialGroupPolicyRequest>>;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<{\n readonly group: OrganizationGroupSummaryResponse;\n readonly head: ReferencedPrincipalHead;\n}> {\n // Signed group names are unique per organization; refuse a collision before\n // anything reaches the server.\n await assertGroupNameUniqueInDirectory({\n apiClient: input.apiClient,\n descriptor: input.externalAdminPolicy.descriptor,\n execSql: input.execSql,\n externalAuthority: input.externalAdminPolicy.externalAuthority,\n name: input.name,\n readEncryptedName: input.readEncryptedName,\n organizationId: input.organizationId,\n reportSecurityIncident: input.reportSecurityIncident,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const expectedHead = await groupPolicyMutationHead(\n input.request.initialGroupPolicy,\n );\n const adminProjection =\n input.externalAdminPolicy.adminBundle.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n const organizationRequest =\n await buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: input.externalAdminPolicy.bundle,\n descriptor: input.externalAdminPolicy.descriptor,\n groupHeads: [\n ...input.externalAdminPolicy.descriptor.groupHeads,\n organizationGroupHead(expectedHead),\n ],\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n const stored = await input.apiClient.createOrganizationGroup(\n input.organizationId,\n { ...input.request, organizationPolicy: organizationRequest },\n );\n if (!stored) {\n throw new Error(\"Group could not be created\");\n }\n const acknowledged = await acknowledgeInitialGroupPolicy({\n organizationId: input.organizationId,\n request: input.request,\n response: stored.group,\n stateHash: expectedHead.stateHash,\n });\n const organizationHead = await groupPolicyMutationHead(organizationRequest);\n const organizationPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy,\n });\n await persistLocallyAcknowledgedPrincipalPolicyBundles({\n entries: [\n { bundle: acknowledged.bundle, policy: acknowledged.policy },\n { bundle: organizationBundle, policy: organizationPolicy },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n });\n return { group: stored.group, head: expectedHead };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"organizationGroupDirectory.js","sourceRoot":"","sources":["organizationGroupDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildPrincipalStateSigningInput,\n generateKemSeedAndKeyPair,\n normalizePrincipalProjectionMembers,\n type ReferencedPrincipalHead,\n type SigningKeyPair,\n signPrincipalState,\n toFingerprint,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n PrincipalProjectionMemberRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationGroupSummaryResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { persistLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport {\n encodeOrganizationAuthorityDescriptor,\n normalizeOrganizationGroupHeads,\n type OrganizationAuthorityDescriptor,\n type OrganizationGroupHead,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type {\n TrustedUserIdentity,\n TrustedUserIdentityResolver,\n} from \"../../data/trustedUserIdentity\";\nimport type { loadOrganizationExternalAdminPolicy } from \"../principals/externalAdminPolicy\";\nimport { assertGroupNameUniqueInDirectory } from \"./groupNameUniqueness\";\nimport {\n acknowledgeGroupPolicyState,\n acknowledgeInitialGroupPolicy,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { OrganizationPrincipalPolicyApi } from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { rewrapProjectionMemberEnvelopes } from \"./principalPolicyRecipients\";\nimport type {\n buildInitialGroupPolicyRequest,\n GroupPolicyNameReader,\n} from \"./principalPolicyRequest\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"./trustedOrganizationUsers\";\n\nfunction organizationGroupHead(\n head: ReferencedPrincipalHead,\n): OrganizationGroupHead {\n if (head.principalType !== \"group\") {\n throw new Error(\"Organization directory can contain only group heads\");\n }\n return { ...head, principalType: \"group\" };\n}\n\nexport function replaceOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly nextHead: ReferencedPrincipalHead;\n}): OrganizationGroupHead[] {\n const nextHead = organizationGroupHead(input.nextHead);\n return normalizeOrganizationGroupHeads([\n ...input.descriptor.groupHeads.filter(\n (head) => head.principalId !== nextHead.principalId,\n ),\n nextHead,\n ]);\n}\n\nexport function removeOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupId: string;\n}): OrganizationGroupHead[] {\n if (\n input.groupId === input.descriptor.adminGroupId ||\n input.groupId === input.descriptor.memberGroupId\n ) {\n throw new Error(\"Built-in groups cannot be removed from the directory\");\n }\n const groupHeads = input.descriptor.groupHeads.filter(\n (head) => head.principalId !== input.groupId,\n );\n if (groupHeads.length === input.descriptor.groupHeads.length) {\n throw new Error(\"Organization directory does not commit the deleted group\");\n }\n return normalizeOrganizationGroupHeads(groupHeads);\n}\n\nexport async function buildOrganizationGroupDirectoryPolicyRequest(input: {\n readonly adminProjection: readonly PrincipalProjectionMemberRequest[];\n readonly adminUsers: readonly TrustedUserIdentity[];\n readonly currentPolicy: Pick<PrincipalPolicyBundleResponse, \"currentState\">;\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupHeads: readonly OrganizationGroupHead[];\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<PutPrincipalPolicyRequest> {\n const projection = normalizePrincipalProjectionMembers(input.adminProjection);\n if (\n projection.length === 0 ||\n projection.some((member) => member.role !== \"admin\")\n ) {\n throw new Error(\"Organization policy must mirror the Admins projection\");\n }\n const organizationKem = generateKemSeedAndKeyPair();\n const memberEnvelopes = await rewrapProjectionMemberEnvelopes({\n projection,\n secretKey: organizationKem.secretKey,\n users: input.adminUsers,\n });\n const payloadCiphertext = encodeOrganizationAuthorityDescriptor({\n ...input.descriptor,\n groupHeads: input.groupHeads,\n });\n const state = await signPrincipalState(\n await buildPrincipalStateSigningInput({\n principalType: \"organization\",\n principalId: input.descriptor.organizationId,\n version: input.currentPolicy.currentState.version + 1,\n prevStateHash: input.currentPolicy.currentState.stateHash,\n keyEpoch: input.currentPolicy.currentState.keyEpoch + 1,\n encapsulationPublicKey: bytesToBase64(organizationKem.publicKey),\n keyFingerprint: await toFingerprint(organizationKem.publicKey),\n members: projection.map((member) => ({ userId: member.userId })),\n memberEnvelopes,\n projection,\n grants: [],\n payloadCiphertext,\n externalAuthority: null,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signerUserKeyFingerprint: input.signingFingerprint,\n }),\n input.signingKeyPair.signingPrivateKey,\n );\n\n return {\n encryptedPayload: {\n cipherSuite: \"aes-256-gcm\",\n ciphertext: payloadCiphertext,\n ciphertextHash: state.payloadCiphertextHash,\n },\n grants: [],\n memberEnvelopes,\n projection,\n state,\n };\n}\n\nexport async function commitCreatedGroupToDirectory(input: {\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly name: string;\n readonly readEncryptedName?: GroupPolicyNameReader;\n readonly apiClient: OrganizationPrincipalPolicyApi;\n readonly execSql: ExecSql;\n readonly externalAdminPolicy: NonNullable<\n Awaited<ReturnType<typeof loadOrganizationExternalAdminPolicy>>\n >;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly request: Awaited<ReturnType<typeof buildInitialGroupPolicyRequest>>;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<{\n readonly group: OrganizationGroupSummaryResponse;\n readonly head: ReferencedPrincipalHead;\n}> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n // Signed group names are unique per organization; refuse a collision before\n // anything reaches the server.\n await assertGroupNameUniqueInDirectory({\n apiClient: input.apiClient,\n descriptor: input.externalAdminPolicy.descriptor,\n execSql: input.execSql,\n externalAuthority: input.externalAdminPolicy.externalAuthority,\n name: input.name,\n readEncryptedName: input.readEncryptedName,\n organizationId: input.organizationId,\n reportSecurityIncident: input.reportSecurityIncident,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const expectedHead = await groupPolicyMutationHead(\n input.request.initialGroupPolicy,\n );\n const adminProjection =\n input.externalAdminPolicy.adminBundle.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n const organizationRequest =\n await buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: input.externalAdminPolicy.bundle,\n descriptor: input.externalAdminPolicy.descriptor,\n groupHeads: [\n ...input.externalAdminPolicy.descriptor.groupHeads,\n organizationGroupHead(expectedHead),\n ],\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n const stored = await input.apiClient.createOrganizationGroup(\n input.organizationId,\n { ...input.request, organizationPolicy: organizationRequest },\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!stored) {\n throw new Error(\"Group could not be created\");\n }\n const acknowledged = await acknowledgeInitialGroupPolicy({\n organizationId: input.organizationId,\n request: input.request,\n response: stored.group,\n stateHash: expectedHead.stateHash,\n });\n const organizationHead = await groupPolicyMutationHead(organizationRequest);\n const organizationPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy,\n });\n await persistLocallyAcknowledgedPrincipalPolicyBundles({\n entries: [\n { bundle: acknowledged.bundle, policy: acknowledged.policy },\n { bundle: organizationBundle, policy: organizationPolicy },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { group: stored.group, head: expectedHead };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationGroupNames.js","sourceRoot":"","sources":["organizationGroupNames.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iCAAiC,EAAE,MAAM,uEAAuE,CAAC;AAC1H,OAAO,EAAE,mCAAmC,EAAE,MAAM,oEAAoE,CAAC;AACzH,OAAO,EAAE,oCAAoC,EAAE,MAAM,iCAAiC,CAAC;AACvF,OAAO,EAEL,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,+BAA+B,EAAE,MAAM,iCAAiC,CAAC;AAGlF,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,
|
|
1
|
+
{"version":3,"file":"organizationGroupNames.js","sourceRoot":"","sources":["organizationGroupNames.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReferencedPrincipalHead } from \"@tearleads/crypto\";\nimport { saveOrganizationGroupDisplayNames } from \"../../data/persistence/organizations/organizationGroupNamePersistence\";\nimport { retainVerifiedPrincipalPolicyBundle } from \"../../data/persistence/verifiedPrincipalPolicyRetentionPersistence\";\nimport { hydrateCurrentOrganizationGroupNames } from \"./currentOrganizationGroupNames\";\nimport {\n type DirectoryGroupWalkInput,\n verifyDirectoryGroup,\n} from \"./groupNameUniqueness\";\nimport { loadGroupNameDirectoryAuthority } from \"./organizationGroupNamePolicies\";\nimport type { OrganizationDirectoryAndGroups } from \"./readModel\";\n\n/** Verify names against the signed directory before projecting decrypted labels. */\nexport async function hydrateOrganizationGroupNames(\n input: Omit<DirectoryGroupWalkInput, \"descriptor\" | \"externalAuthority\"> & {\n readonly directory: OrganizationDirectoryAndGroups;\n readonly organizationPolicyReference?: ReferencedPrincipalHead | null;\n readonly recoveryBatch?: object | undefined;\n readonly stillCurrent: () => boolean;\n readonly createCurrentNameReader?: Parameters<\n typeof hydrateCurrentOrganizationGroupNames\n >[0][\"createCurrentNameReader\"];\n readonly resolveCurrentPolicy?:\n | Parameters<\n typeof hydrateCurrentOrganizationGroupNames\n >[0][\"resolveCurrentPolicy\"]\n | undefined;\n },\n): Promise<OrganizationDirectoryAndGroups> {\n if (input.resolveCurrentPolicy)\n return hydrateCurrentOrganizationGroupNames({\n ...input,\n organizationReference: input.organizationPolicyReference,\n resolveCurrentPolicy: input.resolveCurrentPolicy,\n });\n const authority = await loadGroupNameDirectoryAuthority(input);\n if (!authority) throw new Error(\"Group directory authority is unavailable\");\n const names: { groupId: string; name: string; stateHash: string }[] = [];\n const unreadableGroupIds = new Set<string>();\n for (const group of input.directory.groups) {\n const head = authority.descriptor.groupHeads.find(\n (head) => head.principalId === group.groupId,\n );\n if (!head || head.stateHash !== group.currentState?.stateHash)\n throw new Error(\"Group listing does not match the signed directory\");\n const verified = await verifyDirectoryGroup(\n {\n ...input,\n descriptor: authority.descriptor,\n externalAuthority: authority.externalAuthority,\n },\n head,\n );\n // An undecryptable name stays blank for its group alone, and is flagged so\n // the group is never offered for selection by name.\n if (verified.name === null) {\n unreadableGroupIds.add(group.groupId);\n } else {\n names.push({\n groupId: group.groupId,\n name: verified.name,\n stateHash: head.stateHash,\n });\n }\n await retainVerifiedPrincipalPolicyBundle({\n ...input,\n bundle: verified.bundle,\n policy: verified.policy,\n updatedAt: new Date().toISOString(),\n });\n }\n if (!input.stillCurrent()) throw new Error(\"Group directory access changed\");\n await saveOrganizationGroupDisplayNames({ ...input, names });\n const byId = new Map(names.map((entry) => [entry.groupId, entry.name]));\n return {\n ...input.directory,\n groups: input.directory.groups.map((group) => ({\n ...group,\n name: byId.get(group.groupId) ?? \"\",\n nameUnreadable: unreadableGroupIds.has(group.groupId),\n })),\n };\n}\n"]}
|
|
@@ -24,6 +24,8 @@ export interface OrganizationPrincipalPolicyHistory {
|
|
|
24
24
|
readonly principalType: PrincipalStateResponse["principalType"];
|
|
25
25
|
}
|
|
26
26
|
export interface OrganizationGroupPolicyHistory extends OrganizationPrincipalPolicyHistory {
|
|
27
|
+
/** Exclusive cursor for older entries; absent on a legacy complete history. */
|
|
28
|
+
readonly nextBeforeVersion?: number | null;
|
|
27
29
|
readonly groupId: string;
|
|
28
30
|
readonly organizationId: string;
|
|
29
31
|
readonly principalType: "group";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policyHistoryTypes.js","sourceRoot":"","sources":["policyHistoryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n PrincipalContainerGrantResponse,\n PrincipalProjectionMemberResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\n\nexport type OrganizationPrincipalMemberChangeType =\n | \"added\"\n | \"removed\"\n | \"role_changed\";\nexport interface OrganizationPrincipalMemberChange {\n readonly changeType: OrganizationPrincipalMemberChangeType;\n readonly userId: string;\n readonly nextRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n readonly previousRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n}\nexport interface OrganizationPrincipalPolicyHistoryEntry {\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly createdAt: string;\n readonly keyEpoch: number;\n readonly memberCount: number;\n readonly signedAt: string;\n readonly signerUserId: string;\n readonly signerUserKeyFingerprint: string;\n readonly stateHash: string;\n readonly version: number;\n}\nexport type OrganizationGroupPolicyHistoryEntry =\n OrganizationPrincipalPolicyHistoryEntry;\nexport interface OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPrincipalPolicyHistoryEntry[];\n readonly principalId: string;\n readonly principalType: PrincipalStateResponse[\"principalType\"];\n}\nexport interface OrganizationGroupPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n readonly groupId: string;\n readonly organizationId: string;\n readonly principalType: \"group\";\n}\nexport interface OrganizationPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPolicyHistoryEntry[];\n readonly organizationId: string;\n readonly principalType: \"organization\";\n}\n\nexport interface OrganizationPolicyHistoryEntry\n extends OrganizationPrincipalPolicyHistoryEntry {\n /** Null when the additional signed evidence has not been loaded. */\n readonly groupChanges: OrganizationPolicyGroupChange[] | null;\n}\n\nexport interface OrganizationPolicyGrantChange {\n readonly containerId: string;\n readonly previousAccess:\n | PrincipalContainerGrantResponse[\"accessLevel\"]\n | null;\n readonly nextAccess: PrincipalContainerGrantResponse[\"accessLevel\"] | null;\n}\n\nexport interface OrganizationPolicyGroupChange {\n readonly groupId: string;\n readonly changeType: \"created\" | \"updated\" | \"deleted\";\n readonly previousVersion: number | null;\n readonly version: number;\n readonly previousKeyEpoch: number | null;\n readonly keyEpoch: number;\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly grantChanges: OrganizationPolicyGrantChange[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"policyHistoryTypes.js","sourceRoot":"","sources":["policyHistoryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n PrincipalContainerGrantResponse,\n PrincipalProjectionMemberResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\n\nexport type OrganizationPrincipalMemberChangeType =\n | \"added\"\n | \"removed\"\n | \"role_changed\";\nexport interface OrganizationPrincipalMemberChange {\n readonly changeType: OrganizationPrincipalMemberChangeType;\n readonly userId: string;\n readonly nextRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n readonly previousRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n}\nexport interface OrganizationPrincipalPolicyHistoryEntry {\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly createdAt: string;\n readonly keyEpoch: number;\n readonly memberCount: number;\n readonly signedAt: string;\n readonly signerUserId: string;\n readonly signerUserKeyFingerprint: string;\n readonly stateHash: string;\n readonly version: number;\n}\nexport type OrganizationGroupPolicyHistoryEntry =\n OrganizationPrincipalPolicyHistoryEntry;\nexport interface OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPrincipalPolicyHistoryEntry[];\n readonly principalId: string;\n readonly principalType: PrincipalStateResponse[\"principalType\"];\n}\nexport interface OrganizationGroupPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n /** Exclusive cursor for older entries; absent on a legacy complete history. */\n readonly nextBeforeVersion?: number | null;\n readonly groupId: string;\n readonly organizationId: string;\n readonly principalType: \"group\";\n}\nexport interface OrganizationPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPolicyHistoryEntry[];\n readonly organizationId: string;\n readonly principalType: \"organization\";\n}\n\nexport interface OrganizationPolicyHistoryEntry\n extends OrganizationPrincipalPolicyHistoryEntry {\n /** Null when the additional signed evidence has not been loaded. */\n readonly groupChanges: OrganizationPolicyGroupChange[] | null;\n}\n\nexport interface OrganizationPolicyGrantChange {\n readonly containerId: string;\n readonly previousAccess:\n | PrincipalContainerGrantResponse[\"accessLevel\"]\n | null;\n readonly nextAccess: PrincipalContainerGrantResponse[\"accessLevel\"] | null;\n}\n\nexport interface OrganizationPolicyGroupChange {\n readonly groupId: string;\n readonly changeType: \"created\" | \"updated\" | \"deleted\";\n readonly previousVersion: number | null;\n readonly version: number;\n readonly previousKeyEpoch: number | null;\n readonly keyEpoch: number;\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly grantChanges: OrganizationPolicyGrantChange[];\n}\n"]}
|
|
@@ -8,6 +8,7 @@ import { rebaseOnDeepestAncestor } from "../containers/child/carriedDescendantRe
|
|
|
8
8
|
import { scheduleHeldDescendantRecitations } from "../containers/child/recite.js";
|
|
9
9
|
import { buildMaterializedContainerRekeyPlan } from "../containers/child/rekey.js";
|
|
10
10
|
import { isSpeculativeContainerWriterProjection } from "../containers/child/rekeyProjection.js";
|
|
11
|
+
import { selectReplacementPrincipalPolicyReferences } from "../containers/child/replacementPrincipalPolicyReferences.js";
|
|
11
12
|
import { buildMaterializedContainerRevokePlan } from "../containers/child/revoke.js";
|
|
12
13
|
import { buildMaterializedContainerSharePlan } from "../containers/child/shareMaterialization.js";
|
|
13
14
|
import { addPlan, carryLevel, staleLevelsAbove, } from "./principalContainerRematerializationPlanning.js";
|
|
@@ -60,7 +61,16 @@ function authoredMutationHead(planned) {
|
|
|
60
61
|
return planned.plan;
|
|
61
62
|
}
|
|
62
63
|
async function buildPrincipalContainerRematerializationPlan(input) {
|
|
63
|
-
const { grantRow
|
|
64
|
+
const { grantRow } = input;
|
|
65
|
+
const rematerialization = {
|
|
66
|
+
...input.rematerialization,
|
|
67
|
+
nextPolicy: await selectReplacementPrincipalPolicyReferences({
|
|
68
|
+
policy: input.rematerialization.nextPolicy,
|
|
69
|
+
projection: input.projection,
|
|
70
|
+
principalPolicyCache: input.principalPolicyCache,
|
|
71
|
+
resolveAuthoredPolicyReferences: input.rematerialization.resolveAuthoredPolicyReferences,
|
|
72
|
+
}),
|
|
73
|
+
};
|
|
64
74
|
const { grant, projection, referencedKeyEpoch } = await loadGrantedContainerContext(rematerialization, grantRow, input.projection, input.principalPolicyCache);
|
|
65
75
|
const nextGrant = rematerialization.nextPolicy.grants.find((candidate) => candidate.containerId === grantRow.containerId);
|
|
66
76
|
const author = {
|
|
@@ -269,7 +279,7 @@ export async function preparePrincipalContainerRematerializationBatch(input) {
|
|
|
269
279
|
author: { ...input.author, organizationId },
|
|
270
280
|
execSql: input.execSql,
|
|
271
281
|
plans: organizationPlans,
|
|
272
|
-
stillCurrent: isCurrent,
|
|
282
|
+
stillCurrent: input.recitationStillCurrent ?? isCurrent,
|
|
273
283
|
reportSecurityIncident: input.reportSecurityIncident,
|
|
274
284
|
});
|
|
275
285
|
}
|