@tearleads/client-sdk 0.1.103 → 0.1.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/data/keyingProjectionVerification/checkpoints/checkpointContext.js +4 -1
  2. package/data/keyingProjectionVerification/checkpoints/checkpointContext.js.map +1 -1
  3. package/data/keyingProjectionVerification/checkpoints/verifiedBundleBytes.js +27 -0
  4. package/data/keyingProjectionVerification/checkpoints/verifiedBundleBytes.js.map +1 -0
  5. package/data/keyingProjectionVerification/container/containerManifestVerification.js +2 -0
  6. package/data/keyingProjectionVerification/container/containerManifestVerification.js.map +1 -1
  7. package/data/keyingProjectionVerification/document/documentManifestVerification.js +2 -0
  8. package/data/keyingProjectionVerification/document/documentManifestVerification.js.map +1 -1
  9. package/data/persistence/container-contents/containerContentsPersistence.js +3 -1
  10. package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
  11. package/data/persistence/container-contents/containerMetadataRows.js +9 -0
  12. package/data/persistence/container-contents/containerMetadataRows.js.map +1 -1
  13. package/data/principals/principalPolicyAdminSigners.js +50 -0
  14. package/data/principals/principalPolicyAdminSigners.js.map +1 -1
  15. package/internal/validators/operation/containerMutations.d.ts +16 -16
  16. package/internal/validators/operation/principals.d.ts +24 -0
  17. package/internal/validators/response/containerMutationError.d.ts +3 -3
  18. package/internal/validators/response/containerMutationError.js +2 -1
  19. package/internal/validators/response/containerMutationError.js.map +1 -1
  20. package/internal/validators/response/containerMutationStateStaleError.js +3 -0
  21. package/internal/validators/response/containerMutationStateStaleError.js.map +1 -0
  22. package/internal/validators/response/principal.d.ts +12 -0
  23. package/internal/validators/response/principal.js +5 -0
  24. package/internal/validators/response/principal.js.map +1 -1
  25. package/package.json +1 -1
  26. package/workflows/containers/rematerialization/acknowledgePrincipalContainerRematerialization.js +45 -0
  27. package/workflows/containers/rematerialization/acknowledgePrincipalContainerRematerialization.js.map +1 -0
  28. package/workflows/containers/rematerialization/principalContainerRematerialization.js +17 -47
  29. package/workflows/containers/rematerialization/principalContainerRematerialization.js.map +1 -1
  30. package/workflows/organizations/groupPolicy/commitCurrentGroupPolicyMutation.js +3 -0
  31. package/workflows/organizations/groupPolicy/commitCurrentGroupPolicyMutation.js.map +1 -1
  32. package/workflows/organizations/groupPolicy/submitGroupPolicyCommit.d.ts +6 -11
  33. package/workflows/organizations/groupPolicy/submitGroupPolicyCommit.js +58 -45
  34. package/workflows/organizations/groupPolicy/submitGroupPolicyCommit.js.map +1 -1
  35. package/workflows/principals/policyCache/principalPolicyCacheValidation.js +20 -2
  36. package/workflows/principals/policyCache/principalPolicyCacheValidation.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"principalContainerRematerialization.js","sourceRoot":"","sources":["principalContainerRematerialization.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerDirectGrant,\n PrincipalContainerGrant,\n} from \"@tearleads/crypto\";\nimport type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport type { AuthoredContainerMutationHead } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { acknowledgeContainerMutationBatch } from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport {\n getTargetContainerContext,\n readContainerState,\n} from \"../../../data/containers/shared/projection\";\nimport {\n type PrincipalPolicyCache,\n verifyContainerWriterProjection,\n} from \"../../../data/keyingProjectionVerification\";\nimport { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport { scheduleHeldDescendantRecitations } from \"../child/recite\";\nimport { buildMaterializedContainerRekeyPlan } from \"../child/rekey\";\nimport { rebaseOnDeepestAncestor } from \"../child/rekey/carriedDescendantRekeys\";\nimport {\n containerWriterProjectionFromRotationPlan,\n containerWriterProjectionFromSharePlan,\n isSpeculativeContainerWriterProjection,\n} from \"../child/rekey/rekeyProjection\";\nimport { buildMaterializedContainerRevokePlan } from \"../child/revoke\";\nimport { selectReplacementPrincipalPolicyReferences } from \"../child/rotation/replacementPrincipalPolicyReferences\";\nimport { buildMaterializedContainerSharePlan } from \"../child/share/shareMaterialization\";\nimport { withPrecedingRematerialization } from \"./precedingPrincipalRematerialization\";\nimport {\n addPlan,\n assertNamedContainersRotated,\n type BatchPlanning,\n carryLevel,\n type PrincipalContainerRematerializationInput,\n type PrincipalRematerializationPredecessor,\n planOnceMoreAfterRollback,\n rerootOnAuthoredPaths,\n staleLevelsAbove,\n} from \"./principalContainerRematerializationPlanning\";\nimport {\n loadRematerializationTargets,\n loadServedProjection,\n type MaterializedPrincipalContainerMutationPlan,\n type PlannedRematerialization,\n type RematerializationTarget,\n seededPrincipalPolicyCache,\n} from \"./principalContainerRematerializationTargets\";\n\nfunction matchingGroupGrant(input: {\n readonly directGrants: readonly ContainerDirectGrant[];\n readonly groupId: string;\n}): ContainerDirectGrant | null {\n return (\n input.directGrants.find(\n (grant) =>\n grant.subjectType === \"group\" && grant.subjectId === input.groupId,\n ) ?? null\n );\n}\n\nfunction referencedGroupKeyEpoch(input: {\n readonly groupId: string;\n readonly referencedPrincipalHeads: ReturnType<\n typeof readContainerState\n >[\"referencedPrincipalHeads\"];\n}): number | null {\n return (\n input.referencedPrincipalHeads.find(\n (head) =>\n head.principalType === \"group\" && head.principalId === input.groupId,\n )?.keyEpoch ?? null\n );\n}\n\nasync function loadGrantedContainerContext(\n input: PrincipalContainerRematerializationInput,\n grantRow: PrincipalContainerGrant,\n projection: ContainerWriterProjectionResponse,\n principalPolicyCache: PrincipalPolicyCache,\n) {\n // A projection re-rooted on a rotation this batch has yet to commit must\n // not pin anything: its heads are speculative until acknowledged, and a\n // pin past the group's served head would refuse the other served paths.\n await verifyContainerWriterProjection({\n execSql: input.execSql,\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n principalPolicyCache,\n projection,\n resolveUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const state = readContainerState(\n getTargetContainerContext(projection).manifest,\n );\n const grant = matchingGroupGrant({\n directGrants: state.directGrants,\n groupId: input.groupId,\n });\n if (grant && grant.accessLevel !== grantRow.accessLevel) {\n const nextGrant = input.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n if (!nextGrant || nextGrant.accessLevel !== grantRow.accessLevel) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the expected group grant`,\n );\n }\n }\n const referencedKeyEpoch = referencedGroupKeyEpoch({\n groupId: input.groupId,\n referencedPrincipalHeads: state.referencedPrincipalHeads,\n });\n if (grant && referencedKeyEpoch === null) {\n throw new Error(\n `Container ${grantRow.containerId} is missing its group reference`,\n );\n }\n return { grant, projection, referencedKeyEpoch };\n}\n\nexport async function buildPrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<ContainerMutationRequest[]> {\n return (\n await buildPrincipalContainerRematerializationPlans(input)\n ).entries.map((entry) => entry.planned.plan.request);\n}\n\nexport interface PreparedPrincipalContainerRematerializationBatch {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly retiredContainerIds: readonly string[];\n readonly acknowledge: (\n responses: readonly ContainerMutationResponse[],\n stillCurrent?: (() => boolean) | undefined,\n ) => Promise<void>;\n /**\n * Re-sign the batch with the descendant rekeys the server named for its\n * rotations woven in, parent-first, each against the path the batch will\n * leave behind. A named container the batch already rotates is re-planned\n * under what is carried above it, so no container rotates twice. Returns the\n * whole request list, which replaces `requests`; `acknowledge` then expects\n * the responses in that order.\n */\n readonly carry: (\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>;\n readonly plans: readonly MaterializedPrincipalContainerMutationPlan[];\n readonly requests: readonly ContainerMutationRequest[];\n}\n\nfunction authoredMutationHead(\n planned: MaterializedPrincipalContainerMutationPlan,\n): AuthoredContainerMutationHead {\n return planned.plan;\n}\n\nasync function buildPrincipalContainerRematerializationPlan(input: {\n readonly grantRow: PrincipalContainerGrant;\n /** Keys the batch minted above this container; see `BatchPlanning`. */\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n /** Holds the policy this batch commits, which rebased paths already cite. */\n readonly principalPolicyCache: PrincipalPolicyCache;\n /** The served projection, re-rooted on any rotation planned above it. */\n readonly projection: ContainerWriterProjectionResponse;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n}): Promise<MaterializedPrincipalContainerMutationPlan> {\n const { grantRow } = input;\n const rematerialization = {\n ...input.rematerialization,\n nextPolicy: await selectReplacementPrincipalPolicyReferences({\n policy: input.rematerialization.nextPolicy,\n projection: input.projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveAuthoredPolicyReferences:\n input.rematerialization.resolveAuthoredPolicyReferences,\n }),\n };\n const { grant, projection, referencedKeyEpoch } =\n await loadGrantedContainerContext(\n rematerialization,\n grantRow,\n input.projection,\n input.principalPolicyCache,\n );\n const nextGrant = rematerialization.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n const author = {\n ...rematerialization.author,\n organizationId: projection.organizationId,\n };\n const sharedInput = {\n author,\n execSql: rematerialization.execSql,\n knownContainerKeks: input.knownContainerKeks,\n // Planning against a path this batch has yet to commit pins nothing; the\n // acknowledgement advances every head at once. The rekey planner applies\n // this rule itself; revoke and grant planning take it from here.\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n previousProjection: projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n };\n if (grantRow.containerId === rematerialization.revokedContainerId) {\n if (!grant) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the revoked group grant`,\n );\n }\n return buildMaterializedContainerRevokePlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n revokedSubject: {\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (!grant || grant.accessLevel !== nextGrant?.accessLevel) {\n if (!nextGrant) {\n throw new Error(\n `Container ${grantRow.containerId} is absent from the next group grant set`,\n );\n }\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: nextGrant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (referencedKeyEpoch === rematerialization.nextPolicy.keyEpoch) {\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: grant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n return buildMaterializedContainerRekeyPlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n });\n}\n\n/**\n * Plan one target against the paths already planned above it. A grant's\n * rematerialization extends the served head; a rotation's, and every carried\n * rekey, extends the epoch the batch mints above it.\n */\nasync function planRematerializationTarget(\n batch: BatchPlanning,\n target: RematerializationTarget,\n): Promise<void> {\n const { rematerialization } = batch;\n const rebased = rebaseOnDeepestAncestor(\n target.projection,\n batch.rotatedAbove,\n );\n const stale = rebased\n ? staleLevelsAbove(\n rebased.projection,\n rebased.ancestor.containerKeks.at(-1)?.containerId ?? \"\",\n )\n : [];\n for (const containerId of stale) {\n await carryLevel(\n batch,\n await loadServedProjection(rematerialization.apiClient, containerId),\n );\n }\n if (!target.grantRow) {\n await carryLevel(batch, target.projection);\n return;\n }\n // Each level carried above re-roots the target one step deeper.\n const previousProjection = await rerootOnAuthoredPaths(\n batch,\n target.projection,\n );\n const planned = await buildPrincipalContainerRematerializationPlan({\n grantRow: target.grantRow,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n projection: previousProjection,\n rematerialization,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n });\n const nextProjection =\n \"keyring\" in planned.plan\n ? await containerWriterProjectionFromRotationPlan({\n plan: planned.plan,\n previousProjection,\n })\n : await containerWriterProjectionFromSharePlan({\n plan: planned.plan,\n previousProjection,\n });\n addPlan(batch, {\n carried: false,\n planned,\n rotated: \"keyring\" in planned.plan ? nextProjection : null,\n nextProjection,\n });\n}\n\n/**\n * Sign the batch parent-first. `carriedContainerIds` are the descendant rekeys\n * a refused attempt was told to carry; woven in by depth, each sits under the\n * rotation it rides, and a named container the batch rematerializes anyway is\n * re-planned there rather than rotated twice.\n */\nfunction buildPrincipalContainerRematerializationPlans(\n input: PrincipalContainerRematerializationInput,\n carriedContainerIds: readonly string[] = [],\n) {\n return planOnceMoreAfterRollback(\n input.apiClient,\n [...input.grants.map((grant) => grant.containerId), ...carriedContainerIds],\n () => planRematerializationBatch(input, carriedContainerIds),\n );\n}\n\nasync function planRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n carriedContainerIds: readonly string[],\n): Promise<{\n entries: PlannedRematerialization[];\n retiredContainerIds: readonly string[];\n preceding: PrincipalRematerializationPredecessor;\n}> {\n input = withPrecedingRematerialization(input);\n if (\n input.revokedContainerId &&\n !input.grants.some(\n (grant) => grant.containerId === input.revokedContainerId,\n )\n ) {\n throw new Error(\"Revoked container is not granted to the group\");\n }\n const { targets, retiredContainerIds } = await loadRematerializationTargets({\n apiClient: input.apiClient,\n carriedContainerIds,\n grants: input.grants,\n });\n const batch: BatchPlanning = {\n knownContainerKeks: new Map(input.preceding?.knownContainerKeks),\n plans: [],\n // A rotation planned above cites the group at the head this batch commits,\n // which no store holds yet; the cache is what lets a rebased path verify.\n principalPolicyCache: new Map([\n ...(input.preceding?.policies ?? []).flatMap((policy) => [\n ...seededPrincipalPolicyCache(policy),\n ]),\n ...seededPrincipalPolicyCache(input.nextPolicy),\n ]),\n rematerialization: input,\n resolveProjectionUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n rotatedAbove: [],\n authoredAbove: [],\n };\n for (const target of targets) {\n await planRematerializationTarget(batch, target);\n }\n return {\n entries: batch.plans,\n retiredContainerIds,\n preceding: {\n policies: [...(input.preceding?.policies ?? []), input.nextPolicy],\n projections: [\n ...(input.preceding?.projections ?? []),\n ...batch.plans.flatMap((entry) =>\n entry.nextProjection ? [entry.nextProjection] : [],\n ),\n ],\n knownContainerKeks: batch.knownContainerKeks,\n },\n };\n}\n\nexport async function preparePrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<PreparedPrincipalContainerRematerializationBatch> {\n let { entries, retiredContainerIds, preceding } =\n await buildPrincipalContainerRematerializationPlans(input);\n const requests = () => entries.map((entry) => entry.planned.plan.request);\n return {\n get preceding() {\n return preceding;\n },\n get retiredContainerIds() {\n return retiredContainerIds;\n },\n get plans() {\n return entries.map((entry) => entry.planned);\n },\n get requests() {\n return requests();\n },\n carry: async (requiredContainerIds) => {\n // The refused attempt rolled back whole, so every served head still\n // stands; the batch is signed again from them with the named levels in.\n const replanned = await buildPrincipalContainerRematerializationPlans(\n input,\n requiredContainerIds,\n );\n assertNamedContainersRotated(replanned.entries, requiredContainerIds);\n entries = replanned.entries;\n retiredContainerIds = replanned.retiredContainerIds;\n preceding = replanned.preceding;\n return requests();\n },\n acknowledge: async (responses, stillCurrent) => {\n const isCurrent = () =>\n input.stillCurrent?.() !== false && stillCurrent?.() !== false;\n const heads = entries.map((entry) => authoredMutationHead(entry.planned));\n const acknowledged = await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: heads,\n responses,\n stillCurrent: isCurrent,\n });\n if (!acknowledged || !isCurrent()) return;\n const plansByOrganization = new Map<\n string,\n AuthoredContainerMutationHead[]\n >();\n for (const head of heads) {\n const organizationId = head.state.organizationId;\n const group = plansByOrganization.get(organizationId) ?? [];\n group.push(head);\n plansByOrganization.set(organizationId, group);\n }\n for (const [organizationId, organizationPlans] of plansByOrganization) {\n try {\n rememberVerifiedContainerHeads({\n organizationId,\n execSql: input.execSql,\n heads: [],\n policies: [input.nextPolicy],\n });\n } catch {\n // Cache failure must not invalidate the durably acknowledged batch.\n continue;\n }\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: { ...input.author, organizationId },\n execSql: input.execSql,\n plans: organizationPlans,\n stillCurrent: input.recitationStillCurrent ?? isCurrent,\n reportSecurityIncident: input.reportSecurityIncident,\n });\n }\n },\n };\n}\n"]}
1
+ {"version":3,"file":"principalContainerRematerialization.js","sourceRoot":"","sources":["principalContainerRematerialization.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerDirectGrant,\n PrincipalContainerGrant,\n} from \"@tearleads/crypto\";\nimport type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n getTargetContainerContext,\n readContainerState,\n} from \"../../../data/containers/shared/projection\";\nimport {\n type PrincipalPolicyCache,\n verifyContainerWriterProjection,\n} from \"../../../data/keyingProjectionVerification\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { createProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification/userKeyResolver\";\nimport { buildMaterializedContainerRekeyPlan } from \"../child/rekey\";\nimport { rebaseOnDeepestAncestor } from \"../child/rekey/carriedDescendantRekeys\";\nimport {\n containerWriterProjectionFromRotationPlan,\n containerWriterProjectionFromSharePlan,\n isSpeculativeContainerWriterProjection,\n} from \"../child/rekey/rekeyProjection\";\nimport { buildMaterializedContainerRevokePlan } from \"../child/revoke\";\nimport { selectReplacementPrincipalPolicyReferences } from \"../child/rotation/replacementPrincipalPolicyReferences\";\nimport { buildMaterializedContainerSharePlan } from \"../child/share/shareMaterialization\";\nimport { acknowledgePrincipalContainerRematerialization } from \"./acknowledgePrincipalContainerRematerialization\";\nimport { withPrecedingRematerialization } from \"./precedingPrincipalRematerialization\";\nimport {\n addPlan,\n assertNamedContainersRotated,\n type BatchPlanning,\n carryLevel,\n type PrincipalContainerRematerializationInput,\n type PrincipalRematerializationPredecessor,\n planOnceMoreAfterRollback,\n rerootOnAuthoredPaths,\n staleLevelsAbove,\n} from \"./principalContainerRematerializationPlanning\";\nimport {\n loadRematerializationTargets,\n loadServedProjection,\n type MaterializedPrincipalContainerMutationPlan,\n type PlannedRematerialization,\n type RematerializationTarget,\n seededPrincipalPolicyCache,\n} from \"./principalContainerRematerializationTargets\";\n\nfunction matchingGroupGrant(input: {\n readonly directGrants: readonly ContainerDirectGrant[];\n readonly groupId: string;\n}): ContainerDirectGrant | null {\n return (\n input.directGrants.find(\n (grant) =>\n grant.subjectType === \"group\" && grant.subjectId === input.groupId,\n ) ?? null\n );\n}\n\nfunction referencedGroupKeyEpoch(input: {\n readonly groupId: string;\n readonly referencedPrincipalHeads: ReturnType<\n typeof readContainerState\n >[\"referencedPrincipalHeads\"];\n}): number | null {\n return (\n input.referencedPrincipalHeads.find(\n (head) =>\n head.principalType === \"group\" && head.principalId === input.groupId,\n )?.keyEpoch ?? null\n );\n}\n\nasync function loadGrantedContainerContext(\n input: PrincipalContainerRematerializationInput,\n grantRow: PrincipalContainerGrant,\n projection: ContainerWriterProjectionResponse,\n principalPolicyCache: PrincipalPolicyCache,\n) {\n // A projection re-rooted on a rotation this batch has yet to commit must\n // not pin anything: its heads are speculative until acknowledged, and a\n // pin past the group's served head would refuse the other served paths.\n await verifyContainerWriterProjection({\n execSql: input.execSql,\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n principalPolicyCache,\n projection,\n resolveUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const state = readContainerState(\n getTargetContainerContext(projection).manifest,\n );\n const grant = matchingGroupGrant({\n directGrants: state.directGrants,\n groupId: input.groupId,\n });\n if (grant && grant.accessLevel !== grantRow.accessLevel) {\n const nextGrant = input.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n if (!nextGrant || nextGrant.accessLevel !== grantRow.accessLevel) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the expected group grant`,\n );\n }\n }\n const referencedKeyEpoch = referencedGroupKeyEpoch({\n groupId: input.groupId,\n referencedPrincipalHeads: state.referencedPrincipalHeads,\n });\n if (grant && referencedKeyEpoch === null) {\n throw new Error(\n `Container ${grantRow.containerId} is missing its group reference`,\n );\n }\n return { grant, projection, referencedKeyEpoch };\n}\n\nexport async function buildPrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<ContainerMutationRequest[]> {\n return (\n await buildPrincipalContainerRematerializationPlans(input)\n ).entries.map((entry) => entry.planned.plan.request);\n}\n\nexport interface PreparedPrincipalContainerRematerializationBatch {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly retiredContainerIds: readonly string[];\n readonly acknowledge: (\n responses: readonly ContainerMutationResponse[],\n stillCurrent?: (() => boolean) | undefined,\n ) => Promise<void>;\n /**\n * Re-sign the batch with the descendant rekeys the server named for its\n * rotations woven in, parent-first, each against the path the batch will\n * leave behind. A named container the batch already rotates is re-planned\n * under what is carried above it, so no container rotates twice. Returns the\n * whole request list, which replaces `requests`; `acknowledge` then expects\n * the responses in that order.\n */\n readonly carry: (\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>;\n readonly plans: readonly MaterializedPrincipalContainerMutationPlan[];\n readonly requests: readonly ContainerMutationRequest[];\n /** Rebuild a refused batch against fresh served container heads. */\n readonly refreshAfterConflict?:\n | (() => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n}\n\nasync function buildPrincipalContainerRematerializationPlan(input: {\n readonly grantRow: PrincipalContainerGrant;\n /** Keys the batch minted above this container; see `BatchPlanning`. */\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n /** Holds the policy this batch commits, which rebased paths already cite. */\n readonly principalPolicyCache: PrincipalPolicyCache;\n /** The served projection, re-rooted on any rotation planned above it. */\n readonly projection: ContainerWriterProjectionResponse;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n}): Promise<MaterializedPrincipalContainerMutationPlan> {\n const { grantRow } = input;\n const rematerialization = {\n ...input.rematerialization,\n nextPolicy: await selectReplacementPrincipalPolicyReferences({\n policy: input.rematerialization.nextPolicy,\n projection: input.projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveAuthoredPolicyReferences:\n input.rematerialization.resolveAuthoredPolicyReferences,\n }),\n };\n const { grant, projection, referencedKeyEpoch } =\n await loadGrantedContainerContext(\n rematerialization,\n grantRow,\n input.projection,\n input.principalPolicyCache,\n );\n const nextGrant = rematerialization.nextPolicy.grants.find(\n (candidate) => candidate.containerId === grantRow.containerId,\n );\n const author = {\n ...rematerialization.author,\n organizationId: projection.organizationId,\n };\n const sharedInput = {\n author,\n execSql: rematerialization.execSql,\n knownContainerKeks: input.knownContainerKeks,\n // Planning against a path this batch has yet to commit pins nothing; the\n // acknowledgement advances every head at once. The rekey planner applies\n // this rule itself; revoke and grant planning take it from here.\n persistVerificationCheckpoints:\n !isSpeculativeContainerWriterProjection(projection),\n previousProjection: projection,\n principalPolicyCache: input.principalPolicyCache,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n };\n if (grantRow.containerId === rematerialization.revokedContainerId) {\n if (!grant) {\n throw new Error(\n `Container ${grantRow.containerId} does not contain the revoked group grant`,\n );\n }\n return buildMaterializedContainerRevokePlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n revokedSubject: {\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (!grant || grant.accessLevel !== nextGrant?.accessLevel) {\n if (!nextGrant) {\n throw new Error(\n `Container ${grantRow.containerId} is absent from the next group grant set`,\n );\n }\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: nextGrant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n if (referencedKeyEpoch === rematerialization.nextPolicy.keyEpoch) {\n return buildMaterializedContainerSharePlan({\n ...sharedInput,\n accessLevel: grant.accessLevel,\n recipient: {\n principalPolicy: rematerialization.nextPolicy,\n subjectId: rematerialization.groupId,\n subjectType: \"group\",\n },\n });\n }\n return buildMaterializedContainerRekeyPlan({\n ...sharedInput,\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n });\n}\n\n/**\n * Plan one target against the paths already planned above it. A grant's\n * rematerialization extends the served head; a rotation's, and every carried\n * rekey, extends the epoch the batch mints above it.\n */\nasync function planRematerializationTarget(\n batch: BatchPlanning,\n target: RematerializationTarget,\n): Promise<void> {\n const { rematerialization } = batch;\n const rebased = rebaseOnDeepestAncestor(\n target.projection,\n batch.rotatedAbove,\n );\n const stale = rebased\n ? staleLevelsAbove(\n rebased.projection,\n rebased.ancestor.containerKeks.at(-1)?.containerId ?? \"\",\n )\n : [];\n for (const containerId of stale) {\n await carryLevel(\n batch,\n await loadServedProjection(rematerialization.apiClient, containerId),\n );\n }\n if (!target.grantRow) {\n await carryLevel(batch, target.projection);\n return;\n }\n // Each level carried above re-roots the target one step deeper.\n const previousProjection = await rerootOnAuthoredPaths(\n batch,\n target.projection,\n );\n const planned = await buildPrincipalContainerRematerializationPlan({\n grantRow: target.grantRow,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n projection: previousProjection,\n rematerialization,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n });\n const nextProjection =\n \"keyring\" in planned.plan\n ? await containerWriterProjectionFromRotationPlan({\n plan: planned.plan,\n previousProjection,\n })\n : await containerWriterProjectionFromSharePlan({\n plan: planned.plan,\n previousProjection,\n });\n addPlan(batch, {\n carried: false,\n planned,\n rotated: \"keyring\" in planned.plan ? nextProjection : null,\n nextProjection,\n });\n}\n\n/**\n * Sign the batch parent-first. `carriedContainerIds` are the descendant rekeys\n * a refused attempt was told to carry; woven in by depth, each sits under the\n * rotation it rides, and a named container the batch rematerializes anyway is\n * re-planned there rather than rotated twice.\n */\nfunction buildPrincipalContainerRematerializationPlans(\n input: PrincipalContainerRematerializationInput,\n carriedContainerIds: readonly string[] = [],\n) {\n return planOnceMoreAfterRollback(\n input.apiClient,\n [...input.grants.map((grant) => grant.containerId), ...carriedContainerIds],\n () => planRematerializationBatch(input, carriedContainerIds),\n );\n}\n\nasync function planRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n carriedContainerIds: readonly string[],\n): Promise<{\n entries: PlannedRematerialization[];\n retiredContainerIds: readonly string[];\n preceding: PrincipalRematerializationPredecessor;\n}> {\n input = withPrecedingRematerialization(input);\n if (\n input.revokedContainerId &&\n !input.grants.some(\n (grant) => grant.containerId === input.revokedContainerId,\n )\n ) {\n throw new Error(\"Revoked container is not granted to the group\");\n }\n const { targets, retiredContainerIds } = await loadRematerializationTargets({\n apiClient: input.apiClient,\n carriedContainerIds,\n grants: input.grants,\n });\n const batch: BatchPlanning = {\n knownContainerKeks: new Map(input.preceding?.knownContainerKeks),\n plans: [],\n // A rotation planned above cites the group at the head this batch commits,\n // which no store holds yet; the cache is what lets a rebased path verify.\n principalPolicyCache: new Map([\n ...(input.preceding?.policies ?? []).flatMap((policy) => [\n ...seededPrincipalPolicyCache(policy),\n ]),\n ...seededPrincipalPolicyCache(input.nextPolicy),\n ]),\n rematerialization: input,\n resolveProjectionUserKey: createProjectionUserKeyResolver({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n }),\n rotatedAbove: [],\n authoredAbove: [],\n };\n for (const target of targets) {\n await planRematerializationTarget(batch, target);\n }\n return {\n entries: batch.plans,\n retiredContainerIds,\n preceding: {\n policies: [...(input.preceding?.policies ?? []), input.nextPolicy],\n projections: [\n ...(input.preceding?.projections ?? []),\n ...batch.plans.flatMap((entry) =>\n entry.nextProjection ? [entry.nextProjection] : [],\n ),\n ],\n knownContainerKeks: batch.knownContainerKeks,\n },\n };\n}\n\nexport async function preparePrincipalContainerRematerializationBatch(\n input: PrincipalContainerRematerializationInput,\n): Promise<PreparedPrincipalContainerRematerializationBatch> {\n let { entries, retiredContainerIds, preceding } =\n await buildPrincipalContainerRematerializationPlans(input);\n const requests = () => entries.map((entry) => entry.planned.plan.request);\n return {\n get preceding() {\n return preceding;\n },\n get retiredContainerIds() {\n return retiredContainerIds;\n },\n get plans() {\n return entries.map((entry) => entry.planned);\n },\n get requests() {\n return requests();\n },\n refreshAfterConflict: async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n for (const containerId of new Set([\n ...input.grants.map((grant) => grant.containerId),\n ...entries.map((entry) => entry.planned.plan.containerId),\n ])) {\n input.apiClient.evictContainerWriterProjection?.(containerId);\n }\n const replanned =\n await buildPrincipalContainerRematerializationPlans(input);\n entries = replanned.entries;\n retiredContainerIds = replanned.retiredContainerIds;\n preceding = replanned.preceding;\n return requests();\n },\n carry: async (requiredContainerIds) => {\n // The refused attempt rolled back whole, so every served head still\n // stands; the batch is signed again from them with the named levels in.\n const replanned = await buildPrincipalContainerRematerializationPlans(\n input,\n requiredContainerIds,\n );\n assertNamedContainersRotated(replanned.entries, requiredContainerIds);\n entries = replanned.entries;\n retiredContainerIds = replanned.retiredContainerIds;\n preceding = replanned.preceding;\n return requests();\n },\n acknowledge: (responses, stillCurrent) =>\n acknowledgePrincipalContainerRematerialization(\n input,\n entries,\n responses,\n stillCurrent,\n ),\n };\n}\n"]}
@@ -32,6 +32,9 @@ export async function commitCurrentGroupPolicyMutation(input) {
32
32
  // Refuse the whole transaction if a damaged-key repair needs extra rekeys;
33
33
  // ordinary adds preserve key epochs and need no descendant carry retry.
34
34
  carryDescendantRekeys: member ? undefined : prepared.carry,
35
+ refreshContainerMutations: member
36
+ ? undefined
37
+ : prepared.refreshAfterConflict,
35
38
  stillCurrent: context.stillCurrent,
36
39
  });
37
40
  if (!response)
@@ -1 +1 @@
1
- {"version":3,"file":"commitCurrentGroupPolicyMutation.js","sourceRoot":"","sources":["commitCurrentGroupPolicyMutation.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,mCAAmC,EAAE,MAAM,kDAAkD,CAAC;AAMvG,OAAO,EACL,4CAA4C,EAC5C,4BAA4B,GAC7B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,sCAAsC,EAAE,MAAM,gDAAgD,CAAC;AAExG,OAAO,EACL,iBAAiB,EACjB,6BAA6B,GAC9B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAEL,uBAAuB,GACxB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAsBpE,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,gCAAgC,CACpD,KAAkB;IAElB,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC1B,mCAAmC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,6BAA6B,CAAC;QACnD,0BAA0B,EAAE,KAAK,CAAC,0BAA0B;QAC5D,OAAO,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;KAC9B,CAAC,CAAC;IACH,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACnE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM;QACzB,CAAC,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC;QAC3C,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,MAAM,aAAa,CACpD,KAAK,EACL,MAAM,EACN,MAAM,EAAE,SAAS,CAClB,CAAC;IACF,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAChD,KAAK,EACL,YAAY,EACZ,MAAM,EAAE,YAAY,CACrB,CAAC;IACF,mCAAmC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC;QAC7C,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,mBAAmB;QACnB,aAAa,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;QACpC,wEAAwE;QACxE,2EAA2E;QAC3E,wEAAwE;QACxE,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK;QAC1D,YAAY,EAAE,OAAO,CAAC,YAAY;KACnC,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAC7D,mCAAmC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,sCAAsC,CAC1C;QACE,WAAW,EAAE,KAAK,CAAC,OAAO;QAC1B,kBAAkB,EAAE,mBAAmB;QACvC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChE,EACD,QAAQ,CACT,CAAC;IACF,MAAM,OAAO,CAAC,kBAAkB,CAAC;QAC/B,gBAAgB,EACd,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,YAAY;YACnC,CAAC,CAAC;gBACE;oBACE,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc;oBACtC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;oBAC7B,QAAQ,EAAE,QAAQ,CAAC,YAAY;oBAC/B,mBAAmB,EAAE,MAAM,EAAE,QAAQ,CAAC,mBAAmB;iBAC1D;aACF;YACH,CAAC,CAAC,EAAE;QACR,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,mBAAmB;QACnB,QAAQ;QACR,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB;KAClD,CAAC,CAAC;IACH,IAAI,MAAM,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QACpC,MAAM,MAAM,CAAC,QAAQ,CAAC,WAAW,CAC/B,QAAQ,CAAC,YAAY,CAAC,kBAAkB,EACxC,OAAO,CAAC,YAAY,CACrB,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,CAAC,WAAW,CACxB,QAAQ,CAAC,WAAW,CAAC,kBAAkB,EACvC,OAAO,CAAC,YAAY,CACrB,CAAC;IACF,mCAAmC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,OAAO,QAAQ,CAAC,WAAW,CAAC;AAC9B,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,MAAyB,EACzB,MAAyE,EACzE,SAAiD;IAEjD,MAAM,YAAY,GAAG,MAAM,uBAAuB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,MAAM,0BAA0B,CAAC;QAClD,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,qBAAqB;QAC3D,YAAY;QACZ,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,gBAAgB,EAAE,CAAC,MAAM,CAAC;QAC1B,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,iBAAiB;QACnD,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,qBAAqB;QAC3D,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY;KAC1C,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG;QACf,GAAG,CAAC,SAAS,EAAE,QAAQ,IAAI,EAAE,CAAC;QAC9B;YACE,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,cAAc;YACpE,MAAM,EAAE,UAAU;YAClB,YAAY,EAAE;gBACZ,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,MAAM;gBACzC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM;aACnC;YACD,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY;SAC1C;KACF,CAAC;IACF,sEAAsE;IACtE,wEAAwE;IACxE,oEAAoE;IACpE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,UAAU,EAAE;QAClE,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE;QACnC,WAAW,EAAE,SAAS,EAAE,WAAW,IAAI,EAAE;QACzC,kBAAkB,EAAE,SAAS,EAAE,kBAAkB,IAAI,IAAI,GAAG,EAAE;QAC9D,QAAQ;KACT,CAAC,CAAC;IACH,MAAM,CAAC,OAAO,CAAC,kBAAkB,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3D,OAAO;QACL,YAAY;QACZ,QAAQ;QACR,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC3B,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE;YACrC,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,KAAkB,EAClB,YAAiE,EACjE,UAA2E;IAE3E,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC1B,IACE,KAAK,CAAC,MAAM;QACZ,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,WAAW;YAC1D,OAAO,CAAC,aAAa;YACrB,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,YAAY;iBAC1D,SAAS;gBACV,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC;QAE/D,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;IACJ,IAAI,UAAU,GAAG,4BAA4B,CAAC;QAC5C,UAAU,EAAE,OAAO,CAAC,sBAAsB;QAC1C,QAAQ,EAAE,YAAY;KACvB,CAAC,CAAC;IACH,IAAI,UAAU;QACZ,UAAU,GAAG,4BAA4B,CAAC;YACxC,UAAU,EAAE,EAAE,GAAG,OAAO,CAAC,sBAAsB,EAAE,UAAU,EAAE;YAC7D,QAAQ,EAAE,UAAU;SACrB,CAAC,CAAC;IACL,MAAM,eAAe,GAAG,OAAO,CAAC,yBAAyB;QACvD,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU;QAC1B,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,iBAAiB,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,6BAA6B,CAAC;QACrD,0BAA0B,EAAE,KAAK,CAAC,0BAA0B;QAC5D,OAAO,EAAE,iBAAiB,CAAC,eAAe,CAAC;KAC5C,CAAC,CAAC;IACH,OAAO,4CAA4C,CAAC;QAClD,eAAe;QACf,UAAU;QACV,aAAa,EAAE,OAAO,CAAC,mBAAmB,CAAC,OAAO;QAClD,UAAU,EAAE,OAAO,CAAC,sBAAsB;QAC1C,UAAU;QACV,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type {\n SigningKeyPair,\n VerifiedPrincipalPolicyCurrent,\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 { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport type {\n PreparedPrincipalContainerRematerializationBatch,\n PrincipalRematerializationPredecessor,\n} from \"../../containers/rematerialization\";\nimport {\n buildOrganizationGroupDirectoryPolicyRequest,\n replaceOrganizationGroupHead,\n} from \"../groups/organizationGroupDirectory\";\nimport { assertAuthoredPrincipalMutationReceipt } from \"../principalMutations/principalMutationReceipt\";\nimport type { RuntimeCurrentGroupMutationContext } from \"../principalMutations/runtimeCurrentGroupMutation\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"../trustedOrganizationUsers\";\nimport { prepareAuthoredGroupPolicy } from \"./groupPolicyMutationAcknowledgement\";\nimport {\n type PrincipalPolicyReadWriteApi,\n submitGroupPolicyCommit,\n} from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\n\ninterface GroupPolicyChange {\n readonly context: RuntimeCurrentGroupMutationContext;\n readonly request: PutPrincipalPolicyRequest;\n readonly prepareContainerMutations: (\n nextPolicy: VerifiedPrincipalPolicyCurrent,\n preceding?: PrincipalRematerializationPredecessor | undefined,\n ) => Promise<PreparedPrincipalContainerRematerializationBatch>;\n}\n\ninterface CommitInput extends GroupPolicyChange {\n readonly member?: GroupPolicyChange | undefined;\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly groupId: string;\n readonly organizationId: string;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}\n\n/** Commit and retain the group, optional roster enrollment and directory together. */\nexport async function commitCurrentGroupPolicyMutation(\n input: CommitInput,\n): Promise<PrincipalPolicyMutationResponse> {\n const { context } = input;\n assertProjectionVerificationCurrent(context.stillCurrent);\n const [signer] = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: [input.signerUserId],\n });\n if (!signer) throw new Error(\"Group policy signer is unavailable\");\n const member = input.member\n ? await prepareChange(input.member, signer)\n : null;\n const { expectedHead, prepared } = await prepareChange(\n input,\n signer,\n member?.preceding,\n );\n const organizationRequest = await prepareDirectory(\n input,\n expectedHead,\n member?.expectedHead,\n );\n assertProjectionVerificationCurrent(context.stillCurrent);\n const response = await submitGroupPolicyCommit({\n apiClient: input.apiClient,\n groupId: input.groupId,\n organizationId: input.organizationId,\n request: input.request,\n organizationRequest,\n memberRequest: input.member?.request,\n // A compound retry must rebuild both batches' shared speculative heads.\n // Refuse the whole transaction if a damaged-key repair needs extra rekeys;\n // ordinary adds preserve key epochs and need no descendant carry retry.\n carryDescendantRekeys: member ? undefined : prepared.carry,\n stillCurrent: context.stillCurrent,\n });\n if (!response) throw new Error(\"Group policy update failed\");\n assertProjectionVerificationCurrent(context.stillCurrent);\n await assertAuthoredPrincipalMutationReceipt(\n {\n groupPolicy: input.request,\n organizationPolicy: organizationRequest,\n ...(input.member ? { memberPolicy: input.member.request } : {}),\n },\n response,\n );\n await context.retainAcknowledged({\n additionalGroups:\n input.member && response.memberPolicy\n ? [\n {\n ...input.member.context.groupRetention,\n request: input.member.request,\n response: response.memberPolicy,\n retiredContainerIds: member?.prepared.retiredContainerIds,\n },\n ]\n : [],\n request: input.request,\n organizationRequest,\n response,\n retiredContainerIds: prepared.retiredContainerIds,\n });\n if (member && response.memberPolicy) {\n await member.prepared.acknowledge(\n response.memberPolicy.containerMutations,\n context.stillCurrent,\n );\n }\n await prepared.acknowledge(\n response.groupPolicy.containerMutations,\n context.stillCurrent,\n );\n assertProjectionVerificationCurrent(context.stillCurrent);\n return response.groupPolicy;\n}\n\nasync function prepareChange(\n change: GroupPolicyChange,\n signer: Awaited<ReturnType<typeof resolveRequiredUserIdentities>>[number],\n preceding?: PrincipalRematerializationPredecessor,\n) {\n const expectedHead = await groupPolicyMutationHead(change.request);\n const nextPolicy = await prepareAuthoredGroupPolicy({\n verifiedCurrentPolicy: change.context.verifiedCurrentPolicy,\n expectedHead,\n request: change.request,\n signerPublicKeys: [signer],\n externalAuthority: change.context.externalAuthority,\n localPolicyCheckpoint: change.context.localPolicyCheckpoint,\n stillCurrent: change.context.stillCurrent,\n });\n const authored = [\n ...(preceding?.authored ?? []),\n {\n organizationId: change.context.organizationDescriptor.organizationId,\n policy: nextPolicy,\n dependencies: [\n change.context.organizationCurrent.policy,\n change.context.adminCurrent.policy,\n ],\n stillCurrent: change.context.stillCurrent,\n },\n ];\n // A level the batch plans under its own rotation cites this successor\n // before the transaction commits, so the batch resolves it as authored,\n // exactly as the next group in a compound transaction does (#2646).\n const prepared = await change.prepareContainerMutations(nextPolicy, {\n policies: preceding?.policies ?? [],\n projections: preceding?.projections ?? [],\n knownContainerKeks: preceding?.knownContainerKeks ?? new Map(),\n authored,\n });\n change.request.containerMutations = [...prepared.requests];\n return {\n expectedHead,\n prepared,\n preceding: prepared.preceding\n ? { ...prepared.preceding, authored }\n : undefined,\n };\n}\n\nasync function prepareDirectory(\n input: CommitInput,\n expectedHead: Awaited<ReturnType<typeof groupPolicyMutationHead>>,\n memberHead: Awaited<ReturnType<typeof groupPolicyMutationHead>> | undefined,\n) {\n const { context } = input;\n if (\n input.member &&\n (input.member.context.currentPolicy.currentState.principalId !==\n context.memberGroupId ||\n input.member.context.organizationCurrent.current.currentState\n .stateHash !==\n context.organizationCurrent.current.currentState.stateHash)\n )\n throw new Error(\n \"Roster and group changes must share the same organization policy\",\n );\n let groupHeads = replaceOrganizationGroupHead({\n descriptor: context.organizationDescriptor,\n nextHead: expectedHead,\n });\n if (memberHead)\n groupHeads = replaceOrganizationGroupHead({\n descriptor: { ...context.organizationDescriptor, groupHeads },\n nextHead: memberHead,\n });\n const adminProjection = context.isOrganizationAdminsGroup\n ? input.request.projection\n : context.adminCurrent.current.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n return buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: context.organizationCurrent.current,\n descriptor: context.organizationDescriptor,\n groupHeads,\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n}\n"]}
1
+ {"version":3,"file":"commitCurrentGroupPolicyMutation.js","sourceRoot":"","sources":["commitCurrentGroupPolicyMutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n SigningKeyPair,\n VerifiedPrincipalPolicyCurrent,\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 { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport type {\n PreparedPrincipalContainerRematerializationBatch,\n PrincipalRematerializationPredecessor,\n} from \"../../containers/rematerialization\";\nimport {\n buildOrganizationGroupDirectoryPolicyRequest,\n replaceOrganizationGroupHead,\n} from \"../groups/organizationGroupDirectory\";\nimport { assertAuthoredPrincipalMutationReceipt } from \"../principalMutations/principalMutationReceipt\";\nimport type { RuntimeCurrentGroupMutationContext } from \"../principalMutations/runtimeCurrentGroupMutation\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"../trustedOrganizationUsers\";\nimport { prepareAuthoredGroupPolicy } from \"./groupPolicyMutationAcknowledgement\";\nimport {\n type PrincipalPolicyReadWriteApi,\n submitGroupPolicyCommit,\n} from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\n\ninterface GroupPolicyChange {\n readonly context: RuntimeCurrentGroupMutationContext;\n readonly request: PutPrincipalPolicyRequest;\n readonly prepareContainerMutations: (\n nextPolicy: VerifiedPrincipalPolicyCurrent,\n preceding?: PrincipalRematerializationPredecessor | undefined,\n ) => Promise<PreparedPrincipalContainerRematerializationBatch>;\n}\n\ninterface CommitInput extends GroupPolicyChange {\n readonly member?: GroupPolicyChange | undefined;\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly groupId: string;\n readonly organizationId: string;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}\n\n/** Commit and retain the group, optional roster enrollment and directory together. */\nexport async function commitCurrentGroupPolicyMutation(\n input: CommitInput,\n): Promise<PrincipalPolicyMutationResponse> {\n const { context } = input;\n assertProjectionVerificationCurrent(context.stillCurrent);\n const [signer] = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: [input.signerUserId],\n });\n if (!signer) throw new Error(\"Group policy signer is unavailable\");\n const member = input.member\n ? await prepareChange(input.member, signer)\n : null;\n const { expectedHead, prepared } = await prepareChange(\n input,\n signer,\n member?.preceding,\n );\n const organizationRequest = await prepareDirectory(\n input,\n expectedHead,\n member?.expectedHead,\n );\n assertProjectionVerificationCurrent(context.stillCurrent);\n const response = await submitGroupPolicyCommit({\n apiClient: input.apiClient,\n groupId: input.groupId,\n organizationId: input.organizationId,\n request: input.request,\n organizationRequest,\n memberRequest: input.member?.request,\n // A compound retry must rebuild both batches' shared speculative heads.\n // Refuse the whole transaction if a damaged-key repair needs extra rekeys;\n // ordinary adds preserve key epochs and need no descendant carry retry.\n carryDescendantRekeys: member ? undefined : prepared.carry,\n refreshContainerMutations: member\n ? undefined\n : prepared.refreshAfterConflict,\n stillCurrent: context.stillCurrent,\n });\n if (!response) throw new Error(\"Group policy update failed\");\n assertProjectionVerificationCurrent(context.stillCurrent);\n await assertAuthoredPrincipalMutationReceipt(\n {\n groupPolicy: input.request,\n organizationPolicy: organizationRequest,\n ...(input.member ? { memberPolicy: input.member.request } : {}),\n },\n response,\n );\n await context.retainAcknowledged({\n additionalGroups:\n input.member && response.memberPolicy\n ? [\n {\n ...input.member.context.groupRetention,\n request: input.member.request,\n response: response.memberPolicy,\n retiredContainerIds: member?.prepared.retiredContainerIds,\n },\n ]\n : [],\n request: input.request,\n organizationRequest,\n response,\n retiredContainerIds: prepared.retiredContainerIds,\n });\n if (member && response.memberPolicy) {\n await member.prepared.acknowledge(\n response.memberPolicy.containerMutations,\n context.stillCurrent,\n );\n }\n await prepared.acknowledge(\n response.groupPolicy.containerMutations,\n context.stillCurrent,\n );\n assertProjectionVerificationCurrent(context.stillCurrent);\n return response.groupPolicy;\n}\n\nasync function prepareChange(\n change: GroupPolicyChange,\n signer: Awaited<ReturnType<typeof resolveRequiredUserIdentities>>[number],\n preceding?: PrincipalRematerializationPredecessor,\n) {\n const expectedHead = await groupPolicyMutationHead(change.request);\n const nextPolicy = await prepareAuthoredGroupPolicy({\n verifiedCurrentPolicy: change.context.verifiedCurrentPolicy,\n expectedHead,\n request: change.request,\n signerPublicKeys: [signer],\n externalAuthority: change.context.externalAuthority,\n localPolicyCheckpoint: change.context.localPolicyCheckpoint,\n stillCurrent: change.context.stillCurrent,\n });\n const authored = [\n ...(preceding?.authored ?? []),\n {\n organizationId: change.context.organizationDescriptor.organizationId,\n policy: nextPolicy,\n dependencies: [\n change.context.organizationCurrent.policy,\n change.context.adminCurrent.policy,\n ],\n stillCurrent: change.context.stillCurrent,\n },\n ];\n // A level the batch plans under its own rotation cites this successor\n // before the transaction commits, so the batch resolves it as authored,\n // exactly as the next group in a compound transaction does (#2646).\n const prepared = await change.prepareContainerMutations(nextPolicy, {\n policies: preceding?.policies ?? [],\n projections: preceding?.projections ?? [],\n knownContainerKeks: preceding?.knownContainerKeks ?? new Map(),\n authored,\n });\n change.request.containerMutations = [...prepared.requests];\n return {\n expectedHead,\n prepared,\n preceding: prepared.preceding\n ? { ...prepared.preceding, authored }\n : undefined,\n };\n}\n\nasync function prepareDirectory(\n input: CommitInput,\n expectedHead: Awaited<ReturnType<typeof groupPolicyMutationHead>>,\n memberHead: Awaited<ReturnType<typeof groupPolicyMutationHead>> | undefined,\n) {\n const { context } = input;\n if (\n input.member &&\n (input.member.context.currentPolicy.currentState.principalId !==\n context.memberGroupId ||\n input.member.context.organizationCurrent.current.currentState\n .stateHash !==\n context.organizationCurrent.current.currentState.stateHash)\n )\n throw new Error(\n \"Roster and group changes must share the same organization policy\",\n );\n let groupHeads = replaceOrganizationGroupHead({\n descriptor: context.organizationDescriptor,\n nextHead: expectedHead,\n });\n if (memberHead)\n groupHeads = replaceOrganizationGroupHead({\n descriptor: { ...context.organizationDescriptor, groupHeads },\n nextHead: memberHead,\n });\n const adminProjection = context.isOrganizationAdminsGroup\n ? input.request.projection\n : context.adminCurrent.current.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n return buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: context.organizationCurrent.current,\n descriptor: context.organizationDescriptor,\n groupHeads,\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n}\n"]}
@@ -1,22 +1,17 @@
1
1
  import type { ContainerMutationRequest, PutPrincipalPolicyRequest } from "../../../internal/validators/request/index.js";
2
2
  import { type CommitOrganizationGroupPolicyResponse } from "../../../internal/validators/response/index.js";
3
3
  import type { PrincipalPolicyReadWriteApi } from "../principalPolicy/principalPolicyApi.js";
4
- /**
5
- * Commit, answering one refusal: a rematerialized rekey or revoke that would
6
- * strand a level above a directly granted container is refused with the
7
- * descendant rekeys it must carry. The refused attempt rolled back whole, so
8
- * the served heads still stand; the batch is signed again with the named
9
- * levels woven in, replaces the container mutations, and the commit is retried
10
- * once. A second refusal means the tree moved underneath, and the caller's own
11
- * retry starts from a fresh policy.
12
- */
13
- export declare function submitGroupPolicyCommit(input: {
4
+ interface CommitInput {
14
5
  readonly apiClient: PrincipalPolicyReadWriteApi;
15
6
  readonly carryDescendantRekeys?: ((requiredContainerIds: readonly string[]) => Promise<readonly ContainerMutationRequest[]>) | undefined;
7
+ readonly refreshContainerMutations?: (() => Promise<readonly ContainerMutationRequest[]>) | undefined;
16
8
  readonly groupId: string;
17
9
  readonly organizationId: string;
18
10
  readonly organizationRequest: PutPrincipalPolicyRequest;
19
11
  readonly memberRequest?: PutPrincipalPolicyRequest | undefined;
20
12
  readonly request: PutPrincipalPolicyRequest;
21
13
  readonly stillCurrent?: (() => boolean) | undefined;
22
- }): Promise<CommitOrganizationGroupPolicyResponse | null>;
14
+ }
15
+ /** Answer one explicit transactional refusal, preserving uncertain outcomes. */
16
+ export declare function submitGroupPolicyCommit(input: CommitInput): Promise<CommitOrganizationGroupPolicyResponse | null>;
17
+ export {};
@@ -1,14 +1,8 @@
1
1
  import { CONTAINER_MUTATION_ERROR_CODES, } from "../../../internal/validators/response/index.js";
2
- /**
3
- * Commit, answering one refusal: a rematerialized rekey or revoke that would
4
- * strand a level above a directly granted container is refused with the
5
- * descendant rekeys it must carry. The refused attempt rolled back whole, so
6
- * the served heads still stand; the batch is signed again with the named
7
- * levels woven in, replaces the container mutations, and the commit is retried
8
- * once. A second refusal means the tree moved underneath, and the caller's own
9
- * retry starts from a fresh policy.
10
- */
2
+ /** Answer one explicit transactional refusal, preserving uncertain outcomes. */
11
3
  export async function submitGroupPolicyCommit(input) {
4
+ if (input.stillCurrent?.() === false)
5
+ return null;
12
6
  const body = () => ({
13
7
  groupPolicy: input.request,
14
8
  ...(input.memberRequest ? { memberPolicy: input.memberRequest } : {}),
@@ -18,54 +12,73 @@ export async function submitGroupPolicyCommit(input) {
18
12
  if (!commitOrganizationGroupPolicyResult) {
19
13
  return input.apiClient.commitOrganizationGroupPolicy(input.organizationId, input.groupId, body());
20
14
  }
21
- const first = await commitOrganizationGroupPolicyResult.call(input.apiClient, input.organizationId, input.groupId, body(), { reportErrors: false });
15
+ const submit = () => commitOrganizationGroupPolicyResult.call(input.apiClient, input.organizationId, input.groupId, body(), { reportErrors: false });
16
+ const first = await submit();
22
17
  if (first.ok)
23
18
  return first.data;
24
- if (first.kind === "cancelled")
19
+ if (!isRefused(first) || input.stillCurrent?.() === false)
25
20
  return null;
26
- if (first.kind === "outcome-unknown")
27
- throw new Error(first.message ??
28
- "Policy request may have committed; refresh before retrying");
29
- if (input.memberRequest &&
30
- first.code === CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired) {
31
- throw new Error("Repair the affected container keys before retrying enrollment; no memberships were changed");
32
- }
33
- if (!input.carryDescendantRekeys ||
34
- first.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||
35
- !first.requiredContainerIds?.length) {
36
- first.report?.();
21
+ if (!(await answerRefusal(input, first)))
37
22
  return null;
23
+ if (input.stillCurrent?.() === false)
24
+ return null;
25
+ const second = await submit();
26
+ if (second.ok)
27
+ return second.data;
28
+ if (isRefused(second) && input.stillCurrent?.() !== false)
29
+ second.report?.();
30
+ return null;
31
+ }
32
+ function isRefused(failure) {
33
+ if (failure.kind === "outcome-unknown")
34
+ throw new Error(failure.message ??
35
+ "Policy request may have committed; refresh before retrying");
36
+ return failure.kind !== "cancelled";
37
+ }
38
+ async function answerRefusal(input, failure) {
39
+ const retry = selectRetry(input, failure);
40
+ if (!retry) {
41
+ failure.report?.();
42
+ return false;
38
43
  }
39
- let carried;
40
44
  try {
41
- carried = await input.carryDescendantRekeys(first.requiredContainerIds);
45
+ const requests = await retry.prepare();
46
+ if (input.stillCurrent?.() === false)
47
+ return false;
48
+ if (retry.requireNonempty && requests.length === 0) {
49
+ failure.report?.();
50
+ return false;
51
+ }
52
+ input.request.containerMutations = [...requests];
53
+ return true;
42
54
  }
43
55
  catch (error) {
44
- // The refusal was answerable, and the answer failed: surface both. Once
45
- // the generation that owned the attempt is gone, only the failure is
46
- // surfaced; a superseded refusal is not an error.
47
56
  if (input.stillCurrent?.() !== false)
48
- first.report?.();
57
+ failure.report?.();
49
58
  throw error;
50
59
  }
51
- if (input.stillCurrent?.() === false)
52
- return null;
53
- // Nothing signed means the same refusal again; report the one already had.
54
- if (carried.length === 0) {
55
- first.report?.();
56
- return null;
57
- }
58
- input.request.containerMutations = [...carried];
59
- const second = await commitOrganizationGroupPolicyResult.call(input.apiClient, input.organizationId, input.groupId, body(), { reportErrors: false });
60
- if (!second.ok) {
61
- if (second.kind === "cancelled")
62
- return null;
63
- if (second.kind === "outcome-unknown")
64
- throw new Error(second.message ??
65
- "Policy request may have committed; refresh before retrying");
66
- second.report?.();
60
+ }
61
+ function selectRetry(input, failure) {
62
+ if (failure.status !== 409)
67
63
  return null;
64
+ if (failure.code === CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired) {
65
+ if (input.memberRequest)
66
+ throw new Error("Repair the affected container keys before retrying enrollment; no memberships were changed");
67
+ const { carryDescendantRekeys } = input;
68
+ const { requiredContainerIds } = failure;
69
+ return carryDescendantRekeys && requiredContainerIds?.length
70
+ ? {
71
+ prepare: () => carryDescendantRekeys(requiredContainerIds),
72
+ requireNonempty: true,
73
+ }
74
+ : null;
68
75
  }
69
- return second.data;
76
+ // A compound retry must rebuild both batches' shared speculative paths.
77
+ // Until it can do that, refuse atomically instead of reusing either batch.
78
+ if (!input.memberRequest &&
79
+ failure.code === CONTAINER_MUTATION_ERROR_CODES.stateStale &&
80
+ input.refreshContainerMutations)
81
+ return { prepare: input.refreshContainerMutations, requireNonempty: false };
82
+ return null;
70
83
  }
71
84
  //# sourceMappingURL=submitGroupPolicyCommit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"submitGroupPolicyCommit.js","sourceRoot":"","sources":["submitGroupPolicyCommit.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerMutationRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type CommitOrganizationGroupPolicyResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyReadWriteApi } from \"../principalPolicy/principalPolicyApi\";\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 memberRequest?: PutPrincipalPolicyRequest | undefined;\n readonly request: PutPrincipalPolicyRequest;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<CommitOrganizationGroupPolicyResponse | null> {\n const body = () => ({\n groupPolicy: input.request,\n ...(input.memberRequest ? { memberPolicy: input.memberRequest } : {}),\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.memberRequest &&\n first.code === CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired\n ) {\n throw new Error(\n \"Repair the affected container keys before retrying enrollment; no memberships were changed\",\n );\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"]}
1
+ {"version":3,"file":"submitGroupPolicyCommit.js","sourceRoot":"","sources":["submitGroupPolicyCommit.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerMutationRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type CommitOrganizationGroupPolicyResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyReadWriteApi } from \"../principalPolicy/principalPolicyApi\";\n\ntype CommitFailure = Extract<\n Awaited<\n ReturnType<\n NonNullable<\n PrincipalPolicyReadWriteApi[\"commitOrganizationGroupPolicyResult\"]\n >\n >\n >,\n { ok: false }\n>;\ninterface CommitInput {\n readonly apiClient: PrincipalPolicyReadWriteApi;\n readonly carryDescendantRekeys?:\n | ((\n requiredContainerIds: readonly string[],\n ) => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n readonly refreshContainerMutations?:\n | (() => Promise<readonly ContainerMutationRequest[]>)\n | undefined;\n readonly groupId: string;\n readonly organizationId: string;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly memberRequest?: PutPrincipalPolicyRequest | undefined;\n readonly request: PutPrincipalPolicyRequest;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\n/** Answer one explicit transactional refusal, preserving uncertain outcomes. */\nexport async function submitGroupPolicyCommit(\n input: CommitInput,\n): Promise<CommitOrganizationGroupPolicyResponse | null> {\n if (input.stillCurrent?.() === false) return null;\n const body = () => ({\n groupPolicy: input.request,\n ...(input.memberRequest ? { memberPolicy: input.memberRequest } : {}),\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 submit = () =>\n commitOrganizationGroupPolicyResult.call(\n input.apiClient,\n input.organizationId,\n input.groupId,\n body(),\n { reportErrors: false },\n );\n const first = await submit();\n if (first.ok) return first.data;\n if (!isRefused(first) || input.stillCurrent?.() === false) return null;\n if (!(await answerRefusal(input, first))) return null;\n if (input.stillCurrent?.() === false) return null;\n const second = await submit();\n if (second.ok) return second.data;\n if (isRefused(second) && input.stillCurrent?.() !== false) second.report?.();\n return null;\n}\n\nfunction isRefused(failure: CommitFailure): boolean {\n if (failure.kind === \"outcome-unknown\")\n throw new Error(\n failure.message ??\n \"Policy request may have committed; refresh before retrying\",\n );\n return failure.kind !== \"cancelled\";\n}\n\nasync function answerRefusal(\n input: CommitInput,\n failure: CommitFailure,\n): Promise<boolean> {\n const retry = selectRetry(input, failure);\n if (!retry) {\n failure.report?.();\n return false;\n }\n try {\n const requests = await retry.prepare();\n if (input.stillCurrent?.() === false) return false;\n if (retry.requireNonempty && requests.length === 0) {\n failure.report?.();\n return false;\n }\n input.request.containerMutations = [...requests];\n return true;\n } catch (error) {\n if (input.stillCurrent?.() !== false) failure.report?.();\n throw error;\n }\n}\n\nfunction selectRetry(input: CommitInput, failure: CommitFailure) {\n if (failure.status !== 409) return null;\n if (\n failure.code === CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired\n ) {\n if (input.memberRequest)\n throw new Error(\n \"Repair the affected container keys before retrying enrollment; no memberships were changed\",\n );\n const { carryDescendantRekeys } = input;\n const { requiredContainerIds } = failure;\n return carryDescendantRekeys && requiredContainerIds?.length\n ? {\n prepare: () => carryDescendantRekeys(requiredContainerIds),\n requireNonempty: true,\n }\n : null;\n }\n // A compound retry must rebuild both batches' shared speculative paths.\n // Until it can do that, refuse atomically instead of reusing either batch.\n if (\n !input.memberRequest &&\n failure.code === CONTAINER_MUTATION_ERROR_CODES.stateStale &&\n input.refreshContainerMutations\n )\n return { prepare: input.refreshContainerMutations, requireNonempty: false };\n return null;\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
2
- import { verifyPrincipalPolicyBundleWithExternalOrganizationAdmins } from "../../../data/principals/principalPolicyAdminSigners.js";
2
+ import { ProjectionDependencyUnavailableError } from "../../../data/keyingProjectionVerification/dependencyUnavailable.js";
3
+ import { externalAuthorityCouldAuthorize, verifyPrincipalPolicyBundleWithExternalOrganizationAdmins, } from "../../../data/principals/principalPolicyAdminSigners.js";
3
4
  import { collectPrincipalPolicySignerPublicKeys, principalPolicyStates, } from "../policyVerification.js";
4
5
  function getBundleReferenceFailure(reference, bundle) {
5
6
  const states = principalPolicyStates(bundle);
@@ -131,7 +132,24 @@ export async function validatePrincipalPolicyBundleForCache(input) {
131
132
  expectedReference: input.reference,
132
133
  loadExternalAuthority: async () => {
133
134
  usedExternalAdminPolicy = true;
134
- return ((await input.loadExternalAdminPolicy())?.externalAuthority ?? null);
135
+ const authority = (await input.loadExternalAdminPolicy())
136
+ ?.externalAuthority;
137
+ if (authority)
138
+ return authority;
139
+ // The loader returns null when the organization's Admins policy could
140
+ // not be fetched, and an honest server always serves it. When that
141
+ // evidence is all the chain lacks, the gap is availability, not a
142
+ // refused signer, so it must not surface as an incident. A chain no
143
+ // evidence could authorize keeps its unauthorized refusal.
144
+ if (await externalAuthorityCouldAuthorize({
145
+ bundle: input.bundle,
146
+ expectedReference: input.reference,
147
+ localCheckpoint: input.localCheckpoint,
148
+ signerPublicKeys: signerPublicKeys.signerPublicKeys,
149
+ })) {
150
+ throw new ProjectionDependencyUnavailableError("Organization Admins evidence is unavailable");
151
+ }
152
+ return null;
135
153
  },
136
154
  localCheckpoint: input.localCheckpoint,
137
155
  signerPublicKeys: signerPublicKeys.signerPublicKeys,
@@ -1 +1 @@
1
- {"version":3,"file":"principalPolicyCacheValidation.js","sourceRoot":"","sources":["principalPolicyCacheValidation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type KeyingVerificationCode,\n KeyingVerificationError,\n type PrincipalPolicyCheckpoint,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { verifyPrincipalPolicyBundleWithExternalOrganizationAdmins } from \"../../../data/principals/principalPolicyAdminSigners\";\nimport type { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport type { VerifiedExternalAdminPolicy } from \"../externalAdminPolicy\";\nimport {\n collectPrincipalPolicySignerPublicKeys,\n type PrincipalPolicySignerPublicKeyLoadErrorCode,\n principalPolicyStates,\n} from \"../policyVerification\";\n\ninterface PrincipalPolicyValidationFailure {\n readonly code: KeyingVerificationCode;\n readonly message: string;\n}\n\nfunction getBundleReferenceFailure(\n reference: ReferencedPrincipalStateResponse,\n bundle: PrincipalPolicyBundleResponse,\n): PrincipalPolicyValidationFailure | null {\n const states = principalPolicyStates(bundle);\n const hasReferencedPrincipal = states.some(\n (state) =>\n state.principalType === reference.principalType &&\n state.principalId === reference.principalId,\n );\n if (!hasReferencedPrincipal) {\n return {\n code: \"object_mismatch\",\n message: \"bundle principal does not match referenced principal\",\n };\n }\n if (\n !states.some(\n (state) =>\n state.principalType === reference.principalType &&\n state.principalId === reference.principalId &&\n state.version === reference.version &&\n state.keyEpoch === reference.keyEpoch &&\n state.stateHash === reference.stateHash &&\n state.keyFingerprint === reference.keyFingerprint,\n )\n ) {\n return {\n code: \"hash_mismatch\",\n message: \"bundle chain does not contain referenced principal\",\n };\n }\n if (\n bundle.currentMemberEnvelopes.principalType !==\n bundle.currentState.principalType ||\n bundle.currentMemberEnvelopes.principalId !==\n bundle.currentState.principalId\n ) {\n return {\n code: \"object_mismatch\",\n message: \"member envelope principal does not match current principal\",\n };\n }\n if (\n bundle.currentMemberEnvelopes.stateHash !== bundle.currentState.stateHash\n ) {\n return {\n code: \"hash_mismatch\",\n message: \"member envelope state hash does not match current principal\",\n };\n }\n if (bundle.currentMemberEnvelopes.epoch !== bundle.currentState.keyEpoch) {\n return {\n code: \"hash_mismatch\",\n message: \"member envelope epoch does not match current principal\",\n };\n }\n if (\n bundle.currentPayload.principalType !== bundle.currentState.principalType ||\n bundle.currentPayload.principalId !== bundle.currentState.principalId\n ) {\n return {\n code: \"object_mismatch\",\n message: \"payload principal does not match current principal\",\n };\n }\n if (bundle.currentPayload.stateHash !== bundle.currentState.stateHash) {\n return {\n code: \"hash_mismatch\",\n message: \"payload state hash does not match current principal\",\n };\n }\n return null;\n}\n\nfunction getCheckpointFailure(\n checkpoint: PrincipalPolicyCheckpoint | null,\n bundle: PrincipalPolicyBundleResponse,\n): PrincipalPolicyValidationFailure | null {\n if (!checkpoint) {\n return null;\n }\n const current = bundle.currentState;\n if (current.version < checkpoint.version) {\n return {\n code: \"rollback\",\n message: \"principal policy state is older than the local checkpoint\",\n };\n }\n if (\n current.version === checkpoint.version &&\n current.stateHash !== checkpoint.stateHash\n ) {\n return {\n code: \"equivocation\",\n message: \"principal policy state conflicts with the local checkpoint\",\n };\n }\n if (current.version === checkpoint.version) {\n return null;\n }\n const checkpointState = principalPolicyStates(bundle).find(\n (state) => state.version === checkpoint.version,\n );\n return checkpointState?.stateHash === checkpoint.stateHash\n ? null\n : {\n code: \"stale_predecessor\",\n message: \"principal policy chain does not extend the local checkpoint\",\n };\n}\n\nfunction signerPublicKeyLoadFailure(\n code: PrincipalPolicySignerPublicKeyLoadErrorCode,\n): PrincipalPolicyValidationFailure {\n switch (code) {\n case \"fingerprint-mismatch\":\n return {\n code: \"signer_mismatch\",\n message: \"signer key fingerprint does not match state signer\",\n };\n case \"not-found\":\n // The identity source throws for transport failures, so an absent\n // signer here is the server asserting the cited user does not exist.\n return {\n code: \"missing_dependency\",\n message: \"signer identity is unknown to the server\",\n };\n }\n}\n\nfunction verificationError(\n failure: PrincipalPolicyValidationFailure,\n): KeyingVerificationError {\n return new KeyingVerificationError(failure.code, failure.message);\n}\n\nexport async function validatePrincipalPolicyBundleForCache(input: {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>;\n readonly localCheckpoint: PrincipalPolicyCheckpoint | null;\n readonly reference: ReferencedPrincipalStateResponse;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}): Promise<\n | {\n readonly externalAdminPolicy: VerifiedExternalAdminPolicy | null;\n readonly ok: true;\n readonly policy: VerifiedPrincipalPolicy;\n }\n | { readonly error: KeyingVerificationError; readonly ok: false }\n> {\n const referenceFailure = getBundleReferenceFailure(\n input.reference,\n input.bundle,\n );\n if (referenceFailure) {\n return { error: verificationError(referenceFailure), ok: false };\n }\n const checkpointFailure = getCheckpointFailure(\n input.localCheckpoint,\n input.bundle,\n );\n if (checkpointFailure) {\n return { error: verificationError(checkpointFailure), ok: false };\n }\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle: input.bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in signerPublicKeys) {\n return {\n error: verificationError(\n signerPublicKeyLoadFailure(signerPublicKeys.error),\n ),\n ok: false,\n };\n }\n\n let usedExternalAdminPolicy = false;\n const verified =\n await verifyPrincipalPolicyBundleWithExternalOrganizationAdmins({\n bundle: input.bundle,\n expectedReference: input.reference,\n loadExternalAuthority: async () => {\n usedExternalAdminPolicy = true;\n return (\n (await input.loadExternalAdminPolicy())?.externalAuthority ?? null\n );\n },\n localCheckpoint: input.localCheckpoint,\n signerPublicKeys: signerPublicKeys.signerPublicKeys,\n });\n return verified.ok\n ? {\n externalAdminPolicy: usedExternalAdminPolicy\n ? await input.loadExternalAdminPolicy()\n : null,\n ok: true,\n policy: verified.value,\n }\n : { error: verified.error, ok: false };\n}\n"]}
1
+ {"version":3,"file":"principalPolicyCacheValidation.js","sourceRoot":"","sources":["principalPolicyCacheValidation.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type KeyingVerificationCode,\n KeyingVerificationError,\n type PrincipalPolicyCheckpoint,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { ProjectionDependencyUnavailableError } from \"../../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport {\n externalAuthorityCouldAuthorize,\n verifyPrincipalPolicyBundleWithExternalOrganizationAdmins,\n} from \"../../../data/principals/principalPolicyAdminSigners\";\nimport type { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport type { VerifiedExternalAdminPolicy } from \"../externalAdminPolicy\";\nimport {\n collectPrincipalPolicySignerPublicKeys,\n type PrincipalPolicySignerPublicKeyLoadErrorCode,\n principalPolicyStates,\n} from \"../policyVerification\";\n\ninterface PrincipalPolicyValidationFailure {\n readonly code: KeyingVerificationCode;\n readonly message: string;\n}\n\nfunction getBundleReferenceFailure(\n reference: ReferencedPrincipalStateResponse,\n bundle: PrincipalPolicyBundleResponse,\n): PrincipalPolicyValidationFailure | null {\n const states = principalPolicyStates(bundle);\n const hasReferencedPrincipal = states.some(\n (state) =>\n state.principalType === reference.principalType &&\n state.principalId === reference.principalId,\n );\n if (!hasReferencedPrincipal) {\n return {\n code: \"object_mismatch\",\n message: \"bundle principal does not match referenced principal\",\n };\n }\n if (\n !states.some(\n (state) =>\n state.principalType === reference.principalType &&\n state.principalId === reference.principalId &&\n state.version === reference.version &&\n state.keyEpoch === reference.keyEpoch &&\n state.stateHash === reference.stateHash &&\n state.keyFingerprint === reference.keyFingerprint,\n )\n ) {\n return {\n code: \"hash_mismatch\",\n message: \"bundle chain does not contain referenced principal\",\n };\n }\n if (\n bundle.currentMemberEnvelopes.principalType !==\n bundle.currentState.principalType ||\n bundle.currentMemberEnvelopes.principalId !==\n bundle.currentState.principalId\n ) {\n return {\n code: \"object_mismatch\",\n message: \"member envelope principal does not match current principal\",\n };\n }\n if (\n bundle.currentMemberEnvelopes.stateHash !== bundle.currentState.stateHash\n ) {\n return {\n code: \"hash_mismatch\",\n message: \"member envelope state hash does not match current principal\",\n };\n }\n if (bundle.currentMemberEnvelopes.epoch !== bundle.currentState.keyEpoch) {\n return {\n code: \"hash_mismatch\",\n message: \"member envelope epoch does not match current principal\",\n };\n }\n if (\n bundle.currentPayload.principalType !== bundle.currentState.principalType ||\n bundle.currentPayload.principalId !== bundle.currentState.principalId\n ) {\n return {\n code: \"object_mismatch\",\n message: \"payload principal does not match current principal\",\n };\n }\n if (bundle.currentPayload.stateHash !== bundle.currentState.stateHash) {\n return {\n code: \"hash_mismatch\",\n message: \"payload state hash does not match current principal\",\n };\n }\n return null;\n}\n\nfunction getCheckpointFailure(\n checkpoint: PrincipalPolicyCheckpoint | null,\n bundle: PrincipalPolicyBundleResponse,\n): PrincipalPolicyValidationFailure | null {\n if (!checkpoint) {\n return null;\n }\n const current = bundle.currentState;\n if (current.version < checkpoint.version) {\n return {\n code: \"rollback\",\n message: \"principal policy state is older than the local checkpoint\",\n };\n }\n if (\n current.version === checkpoint.version &&\n current.stateHash !== checkpoint.stateHash\n ) {\n return {\n code: \"equivocation\",\n message: \"principal policy state conflicts with the local checkpoint\",\n };\n }\n if (current.version === checkpoint.version) {\n return null;\n }\n const checkpointState = principalPolicyStates(bundle).find(\n (state) => state.version === checkpoint.version,\n );\n return checkpointState?.stateHash === checkpoint.stateHash\n ? null\n : {\n code: \"stale_predecessor\",\n message: \"principal policy chain does not extend the local checkpoint\",\n };\n}\n\nfunction signerPublicKeyLoadFailure(\n code: PrincipalPolicySignerPublicKeyLoadErrorCode,\n): PrincipalPolicyValidationFailure {\n switch (code) {\n case \"fingerprint-mismatch\":\n return {\n code: \"signer_mismatch\",\n message: \"signer key fingerprint does not match state signer\",\n };\n case \"not-found\":\n // The identity source throws for transport failures, so an absent\n // signer here is the server asserting the cited user does not exist.\n return {\n code: \"missing_dependency\",\n message: \"signer identity is unknown to the server\",\n };\n }\n}\n\nfunction verificationError(\n failure: PrincipalPolicyValidationFailure,\n): KeyingVerificationError {\n return new KeyingVerificationError(failure.code, failure.message);\n}\n\nexport async function validatePrincipalPolicyBundleForCache(input: {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly loadExternalAdminPolicy: () => Promise<VerifiedExternalAdminPolicy | null>;\n readonly localCheckpoint: PrincipalPolicyCheckpoint | null;\n readonly reference: ReferencedPrincipalStateResponse;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}): Promise<\n | {\n readonly externalAdminPolicy: VerifiedExternalAdminPolicy | null;\n readonly ok: true;\n readonly policy: VerifiedPrincipalPolicy;\n }\n | { readonly error: KeyingVerificationError; readonly ok: false }\n> {\n const referenceFailure = getBundleReferenceFailure(\n input.reference,\n input.bundle,\n );\n if (referenceFailure) {\n return { error: verificationError(referenceFailure), ok: false };\n }\n const checkpointFailure = getCheckpointFailure(\n input.localCheckpoint,\n input.bundle,\n );\n if (checkpointFailure) {\n return { error: verificationError(checkpointFailure), ok: false };\n }\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle: input.bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in signerPublicKeys) {\n return {\n error: verificationError(\n signerPublicKeyLoadFailure(signerPublicKeys.error),\n ),\n ok: false,\n };\n }\n\n let usedExternalAdminPolicy = false;\n const verified =\n await verifyPrincipalPolicyBundleWithExternalOrganizationAdmins({\n bundle: input.bundle,\n expectedReference: input.reference,\n loadExternalAuthority: async () => {\n usedExternalAdminPolicy = true;\n const authority = (await input.loadExternalAdminPolicy())\n ?.externalAuthority;\n if (authority) return authority;\n // The loader returns null when the organization's Admins policy could\n // not be fetched, and an honest server always serves it. When that\n // evidence is all the chain lacks, the gap is availability, not a\n // refused signer, so it must not surface as an incident. A chain no\n // evidence could authorize keeps its unauthorized refusal.\n if (\n await externalAuthorityCouldAuthorize({\n bundle: input.bundle,\n expectedReference: input.reference,\n localCheckpoint: input.localCheckpoint,\n signerPublicKeys: signerPublicKeys.signerPublicKeys,\n })\n ) {\n throw new ProjectionDependencyUnavailableError(\n \"Organization Admins evidence is unavailable\",\n );\n }\n return null;\n },\n localCheckpoint: input.localCheckpoint,\n signerPublicKeys: signerPublicKeys.signerPublicKeys,\n });\n return verified.ok\n ? {\n externalAdminPolicy: usedExternalAdminPolicy\n ? await input.loadExternalAdminPolicy()\n : null,\n ok: true,\n policy: verified.value,\n }\n : { error: verified.error, ok: false };\n}\n"]}