@tearleads/client-sdk 0.1.19 → 0.1.21

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 (238) hide show
  1. package/client/organizations/index.js +2 -2
  2. package/client/organizations/index.js.map +1 -1
  3. package/client/organizations/organizationHistory.js +66 -0
  4. package/client/organizations/organizationHistory.js.map +1 -0
  5. package/client/organizations/organizationReadModels.d.ts +1 -1
  6. package/client/organizations/organizationReadModels.js +7 -27
  7. package/client/organizations/organizationReadModels.js.map +1 -1
  8. package/client/organizations/organizationsTypes.d.ts +1 -1
  9. package/client/organizations/organizationsTypes.js.map +1 -1
  10. package/data/containers/shared/types.d.ts +2 -2
  11. package/data/containers/shared/types.js.map +1 -1
  12. package/data/documents/shared/syncSubmitFailure.d.ts +2 -2
  13. package/data/documents/shared/syncSubmitFailure.js.map +1 -1
  14. package/data/keyingProjectionVerification/documentPurgeCheckpointCurrency.js +34 -8
  15. package/data/keyingProjectionVerification/documentPurgeCheckpointCurrency.js.map +1 -1
  16. package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +1 -1
  17. package/data/keyingProjectionVerification/documentPurgePolicyCheckpoints.js +17 -0
  18. package/data/keyingProjectionVerification/documentPurgePolicyCheckpoints.js.map +1 -0
  19. package/data/keyingProjectionVerification/documentPurgePolicyCurrency.js +55 -0
  20. package/data/keyingProjectionVerification/documentPurgePolicyCurrency.js.map +1 -0
  21. package/data/keyingProjectionVerification/documentPurgePrincipalEvidence.js +25 -13
  22. package/data/keyingProjectionVerification/documentPurgePrincipalEvidence.js.map +1 -1
  23. package/data/keyingProjectionVerification/documentPurgeProofVerification.d.ts +5 -3
  24. package/data/keyingProjectionVerification/documentPurgeProofVerification.js +52 -8
  25. package/data/keyingProjectionVerification/documentPurgeProofVerification.js.map +1 -1
  26. package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +1 -1
  27. package/data/keyingProjectionVerification/types.d.ts +4 -0
  28. package/data/keyingProjectionVerification/types.js.map +1 -1
  29. package/data/persistence/organizations/organizationReadModelProjection.js +2 -2
  30. package/data/persistence/organizations/organizationReadModelProjection.js.map +1 -1
  31. package/data/persistence/principalAuthorizationCheckpoints.js +1 -1
  32. package/data/persistence/principalAuthorizationCheckpoints.js.map +1 -1
  33. package/data/persistence/principalCurrentAcknowledgementPersistence.d.ts +1 -0
  34. package/data/persistence/principalCurrentAcknowledgementPersistence.js +58 -12
  35. package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -1
  36. package/data/persistence/principalHistoryEvidencePersistence.d.ts +2 -0
  37. package/data/persistence/principalHistoryEvidencePersistence.js +2 -0
  38. package/data/persistence/principalHistoryEvidencePersistence.js.map +1 -1
  39. package/data/persistence/principalHistoryIncompleteRetention.js +32 -0
  40. package/data/persistence/principalHistoryIncompleteRetention.js.map +1 -0
  41. package/data/persistence/principalHistoryNodeRetention.js +76 -0
  42. package/data/persistence/principalHistoryNodeRetention.js.map +1 -0
  43. package/data/persistence/principalHistoryPrefixPersistence.d.ts +1 -0
  44. package/data/persistence/principalHistoryPrefixPersistence.js +30 -1
  45. package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
  46. package/data/persistence/principalHistoryRootOwnership.js +71 -0
  47. package/data/persistence/principalHistoryRootOwnership.js.map +1 -0
  48. package/data/persistence/principalHistoryStagePersistence.js +45 -0
  49. package/data/persistence/principalHistoryStagePersistence.js.map +1 -1
  50. package/data/persistence/principalHistoryStageRetention.js +44 -0
  51. package/data/persistence/principalHistoryStageRetention.js.map +1 -0
  52. package/data/persistence/principalHistoryUnpublishedRetention.js +71 -0
  53. package/data/persistence/principalHistoryUnpublishedRetention.js.map +1 -0
  54. package/data/persistence/principalKeyEnvelopeArchivePersistence.js +63 -0
  55. package/data/persistence/principalKeyEnvelopeArchivePersistence.js.map +1 -0
  56. package/data/persistence/principalKeyEnvelopeCandidates.js +10 -1
  57. package/data/persistence/principalKeyEnvelopeCandidates.js.map +1 -1
  58. package/data/persistence/principalPolicyReferencePersistence.js +2 -2
  59. package/data/persistence/principalPolicyReferencePersistence.js.map +1 -1
  60. package/data/sqlite/principalHistoryEvidenceSchema.js +2 -0
  61. package/data/sqlite/principalHistoryEvidenceSchema.js.map +1 -1
  62. package/data/sqlite/principalHistoryNodeRetentionSchema.js +30 -0
  63. package/data/sqlite/principalHistoryNodeRetentionSchema.js.map +1 -0
  64. package/data/sqlite/principalHistoryRetentionSchema.js +40 -0
  65. package/data/sqlite/principalHistoryRetentionSchema.js.map +1 -0
  66. package/data/sqlite/principalHistoryStageSchema.js +2 -0
  67. package/data/sqlite/principalHistoryStageSchema.js.map +1 -1
  68. package/data/sqlite/schema.d.ts +453 -0
  69. package/data/sqlite/schema.js +6 -0
  70. package/data/sqlite/schema.js.map +1 -1
  71. package/data/sqlite/sqliteCommitGuards.js +49 -0
  72. package/data/sqlite/sqliteCommitGuards.js.map +1 -0
  73. package/data/sqlite/sqlitePersistenceRuntime.js +14 -2
  74. package/data/sqlite/sqlitePersistenceRuntime.js.map +1 -1
  75. package/index.d.ts +3 -1
  76. package/index.js.map +1 -1
  77. package/internal/api-client/ApiClient.d.ts +60 -137
  78. package/internal/api-client/ApiClient.js +7 -5
  79. package/internal/api-client/ApiClient.js.map +1 -1
  80. package/internal/api-client/apiRequestRuntime.js +7 -7
  81. package/internal/api-client/apiRequestRuntime.js.map +1 -1
  82. package/internal/api-client/documentPurge.js +25 -0
  83. package/internal/api-client/documentPurge.js.map +1 -0
  84. package/internal/api-client/organizationPolicyHistory.d.ts +53 -0
  85. package/internal/api-client/organizationPolicyHistory.js +15 -0
  86. package/internal/api-client/organizationPolicyHistory.js.map +1 -0
  87. package/internal/api-client/requestInternals.js +4 -4
  88. package/internal/api-client/requestInternals.js.map +1 -1
  89. package/internal/api-client/types.d.ts +2 -2
  90. package/internal/api-client/types.js.map +1 -1
  91. package/internal/crypto/keying/accessEvent.js +11 -9
  92. package/internal/crypto/keying/accessEvent.js.map +1 -1
  93. package/internal/crypto/keying/principalPolicyChainEntry.js +3 -0
  94. package/internal/crypto/keying/principalPolicyChainEntry.js.map +1 -1
  95. package/internal/crypto/keying/principalPolicyHistory.js +4 -0
  96. package/internal/crypto/keying/principalPolicyHistory.js.map +1 -1
  97. package/internal/crypto/keying/principalPolicyHistoryTypes.d.ts +2 -0
  98. package/internal/crypto/keying/principalPolicyHistoryTypes.js.map +1 -1
  99. package/internal/crypto/keying/principalPolicyTransition.d.ts +2 -1
  100. package/internal/crypto/keying/principalPolicyTransition.js +5 -0
  101. package/internal/crypto/keying/principalPolicyTransition.js.map +1 -1
  102. package/internal/crypto/principalState.js +2 -2
  103. package/internal/crypto/principalState.js.map +1 -1
  104. package/internal/validators/operation/containerMutations.d.ts +448 -6528
  105. package/internal/validators/operation/documentMutations.d.ts +323 -579
  106. package/internal/validators/operation/documentMutations.js +22 -4
  107. package/internal/validators/operation/documentMutations.js.map +1 -1
  108. package/internal/validators/operation/documentSync.d.ts +26 -406
  109. package/internal/validators/operation/organizationPolicyHistory.d.ts +188 -310
  110. package/internal/validators/operation/organizationPolicyHistory.js +17 -3
  111. package/internal/validators/operation/organizationPolicyHistory.js.map +1 -1
  112. package/internal/validators/operation/organizations.d.ts +2 -2
  113. package/internal/validators/request/principal.js +2 -2
  114. package/internal/validators/request/principal.js.map +1 -1
  115. package/internal/validators/response/containerMutationError.d.ts +28 -408
  116. package/internal/validators/response/documentMutation.d.ts +232 -544
  117. package/internal/validators/response/documentMutation.js +1 -2
  118. package/internal/validators/response/documentMutation.js.map +1 -1
  119. package/internal/validators/response/documentSyncError.d.ts +26 -406
  120. package/internal/validators/response/documentSyncError.js +4 -3
  121. package/internal/validators/response/documentSyncError.js.map +1 -1
  122. package/internal/validators/response/index.d.ts +1 -1
  123. package/internal/validators/response/index.js +1 -1
  124. package/internal/validators/response/index.js.map +1 -1
  125. package/internal/validators/response/organization.d.ts +1 -1
  126. package/internal/validators/response/organization.js +1 -1
  127. package/internal/validators/response/organization.js.map +1 -1
  128. package/internal/validators/response/organizationPolicyHistory.d.ts +127 -309
  129. package/internal/validators/response/organizationPolicyHistory.js +10 -4
  130. package/internal/validators/response/organizationPolicyHistory.js.map +1 -1
  131. package/internal/validators/response/organizationReadModel.d.ts +5 -5
  132. package/internal/validators/response/principal.d.ts +28 -408
  133. package/internal/validators/response/principal.js +3 -1
  134. package/internal/validators/response/principal.js.map +1 -1
  135. package/internal/validators/response/principalReference.d.ts +1 -1
  136. package/internal/validators/response/principalReference.js +1 -1
  137. package/internal/validators/response/principalReference.js.map +1 -1
  138. package/internal/validators/response/principalSnapshot.js +4 -4
  139. package/internal/validators/response/principalSnapshot.js.map +1 -1
  140. package/internal/validators/util/index.d.ts +1 -1
  141. package/internal/validators/util/index.js +1 -1
  142. package/internal/validators/util/index.js.map +1 -1
  143. package/internal/validators/util/principalHistoryWire.d.ts +2 -0
  144. package/internal/validators/util/principalHistoryWire.js +2 -0
  145. package/internal/validators/util/principalHistoryWire.js.map +1 -1
  146. package/package.json +1 -1
  147. package/workflows/container-contents/container-state/createWithMetadata.js +19 -49
  148. package/workflows/container-contents/container-state/createWithMetadata.js.map +1 -1
  149. package/workflows/container-contents/container-state/groupGrantVerification.js +29 -0
  150. package/workflows/container-contents/container-state/groupGrantVerification.js.map +1 -1
  151. package/workflows/container-contents/container-state/groupShareEpoch.js +33 -0
  152. package/workflows/container-contents/container-state/groupShareEpoch.js.map +1 -0
  153. package/workflows/container-contents/container-state/remote.js +4 -1
  154. package/workflows/container-contents/container-state/remote.js.map +1 -1
  155. package/workflows/container-contents/container-state/share.js +2 -24
  156. package/workflows/container-contents/container-state/share.js.map +1 -1
  157. package/workflows/container-contents/documentTombstoneEvidence.js +23 -12
  158. package/workflows/container-contents/documentTombstoneEvidence.js.map +1 -1
  159. package/workflows/containers/child/create.js +1 -3
  160. package/workflows/containers/child/create.js.map +1 -1
  161. package/workflows/containers/child/createSubmission.d.ts +1 -3
  162. package/workflows/containers/child/createSubmission.js +13 -15
  163. package/workflows/containers/child/createSubmission.js.map +1 -1
  164. package/workflows/containers/child/currentShareGrantMutation.js +82 -0
  165. package/workflows/containers/child/currentShareGrantMutation.js.map +1 -0
  166. package/workflows/containers/child/currentSharePrincipalPolicy.js +83 -0
  167. package/workflows/containers/child/currentSharePrincipalPolicy.js.map +1 -0
  168. package/workflows/containers/child/mutationSubmit.js +1 -1
  169. package/workflows/containers/child/mutationSubmit.js.map +1 -1
  170. package/workflows/containers/child/runtimeCurrentGroupShare.js +82 -0
  171. package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -0
  172. package/workflows/containers/child/share.js +1 -14
  173. package/workflows/containers/child/share.js.map +1 -1
  174. package/workflows/containers/child/shareProjection.js +15 -0
  175. package/workflows/containers/child/shareProjection.js.map +1 -0
  176. package/workflows/containers/mutationResponse.js +1 -1
  177. package/workflows/containers/mutationResponse.js.map +1 -1
  178. package/workflows/documents/purge.d.ts +3 -0
  179. package/workflows/documents/purge.js +13 -0
  180. package/workflows/documents/purge.js.map +1 -1
  181. package/workflows/documents/sync.js +2 -0
  182. package/workflows/documents/sync.js.map +1 -1
  183. package/workflows/documents/syncFailures.js +2 -2
  184. package/workflows/documents/syncFailures.js.map +1 -1
  185. package/workflows/documents/syncPolicyRepair.js +15 -13
  186. package/workflows/documents/syncPolicyRepair.js.map +1 -1
  187. package/workflows/organizations/initialPrincipalCurrentPublication.js +2 -0
  188. package/workflows/organizations/initialPrincipalCurrentPublication.js.map +1 -1
  189. package/workflows/organizations/loadPolicyHistoryDetails.js +31 -32
  190. package/workflows/organizations/loadPolicyHistoryDetails.js.map +1 -1
  191. package/workflows/organizations/organizationPolicyHistoryDetails.js +37 -15
  192. package/workflows/organizations/organizationPolicyHistoryDetails.js.map +1 -1
  193. package/workflows/organizations/organizationPolicyHistoryVerification.js +56 -69
  194. package/workflows/organizations/organizationPolicyHistoryVerification.js.map +1 -1
  195. package/workflows/organizations/policyHistoryCache.js +5 -2
  196. package/workflows/organizations/policyHistoryCache.js.map +1 -1
  197. package/workflows/organizations/policyHistoryTypes.d.ts +1 -0
  198. package/workflows/organizations/policyHistoryTypes.js.map +1 -1
  199. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +4 -1
  200. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -1
  201. package/workflows/principals/loadRecoveredPrincipalHistoryPage.d.ts +0 -1
  202. package/workflows/principals/loadRecoveredPrincipalHistoryPage.js +1 -2
  203. package/workflows/principals/loadRecoveredPrincipalHistoryPage.js.map +1 -1
  204. package/workflows/principals/policyRepair.js +38 -0
  205. package/workflows/principals/policyRepair.js.map +1 -0
  206. package/workflows/principals/policyRepairBudget.d.ts +2 -2
  207. package/workflows/principals/policyRepairBudget.js +3 -3
  208. package/workflows/principals/policyRepairBudget.js.map +1 -1
  209. package/workflows/principals/principalHistoryRecoveryPrefix.js +4 -0
  210. package/workflows/principals/principalHistoryRecoveryPrefix.js.map +1 -1
  211. package/workflows/principals/principalRecoveryLocalPreference.js +3 -2
  212. package/workflows/principals/principalRecoveryLocalPreference.js.map +1 -1
  213. package/workflows/principals/publicPrincipalHistoryPage.js +1 -0
  214. package/workflows/principals/publicPrincipalHistoryPage.js.map +1 -1
  215. package/workflows/principals/publicPrincipalHistoryProgress.js +1 -0
  216. package/workflows/principals/publicPrincipalHistoryProgress.js.map +1 -1
  217. package/workflows/principals/publicPrincipalHistoryTypes.d.ts +2 -0
  218. package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -1
  219. package/workflows/principals/publicProjectionPrincipal.js +1 -0
  220. package/workflows/principals/publicProjectionPrincipal.js.map +1 -1
  221. package/workflows/principals/recoverPrincipalHistoryPage.js +2 -1
  222. package/workflows/principals/recoverPrincipalHistoryPage.js.map +1 -1
  223. package/workflows/principals/recoverPrincipalPolicyHistory.js +1 -0
  224. package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
  225. package/workflows/principals/recoverPublicPrincipalHistory.js +2 -0
  226. package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -1
  227. package/workflows/principals/runtimePolicyRecovery.js +2 -1
  228. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  229. package/workflows/principals/selectPublicPrincipalHistory.js +21 -15
  230. package/workflows/principals/selectPublicPrincipalHistory.js.map +1 -1
  231. package/workflows/sync/remoteResetPrincipalScope.js +6 -0
  232. package/workflows/sync/remoteResetPrincipalScope.js.map +1 -1
  233. package/data/keyingProjectionVerification/principalPolicySnapshotVerification.js +0 -208
  234. package/data/keyingProjectionVerification/principalPolicySnapshotVerification.js.map +0 -1
  235. package/data/keyingProjectionVerification/snapshotVerificationCache.js +0 -39
  236. package/data/keyingProjectionVerification/snapshotVerificationCache.js.map +0 -1
  237. package/workflows/containers/child/policyRepair.js +0 -23
  238. package/workflows/containers/child/policyRepair.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentShareGrantMutation.js","sourceRoot":"","sources":["currentShareGrantMutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MaterializedContainerSharePlan } from \"../../../data/containers/shared/types\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { commitCurrentGroupPolicyMutation } from \"../../organizations/commitCurrentGroupPolicyMutation\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadataRuntime\";\nimport { buildSetGroupContainerGrantPolicyRequest } from \"../../organizations/groupPolicyRequests\";\nimport {\n type PreparedPrincipalContainerRematerializationBatch,\n preparePrincipalContainerRematerializationBatch,\n} from \"../../organizations/principalContainerRematerialization\";\nimport { groupPolicyNameMismatch } from \"../../organizations/principalPolicyRequest\";\nimport type {\n createRuntimeCurrentGroupMutation,\n RuntimeCurrentGroupMutationContext,\n} from \"../../organizations/runtimeCurrentGroupMutation\";\nimport type { createRuntimeCurrentSharePrincipalPolicy } from \"./currentSharePrincipalPolicy\";\nimport type { shareRemoteContainerWithGroup } from \"./share\";\nimport { GroupShareNameMismatchError } from \"./sharePrincipalPolicy\";\n\n/** Fresh mutation authority rechecks the chosen name before authoring a grant. */\nexport async function commitCurrentShareGrant(input: {\n readonly runtime: Parameters<\n typeof createRuntimeCurrentSharePrincipalPolicy\n >[0];\n readonly share: Parameters<typeof shareRemoteContainerWithGroup>[0];\n readonly recitationStillCurrent?: (() => boolean) | undefined;\n readonly mutate: NonNullable<\n ReturnType<typeof createRuntimeCurrentGroupMutation>\n >;\n}): ReturnType<typeof shareRemoteContainerWithGroup> {\n const share = input.share;\n const expectedName = share.expectedGroupName;\n if (expectedName === null)\n throw new Error(\n \"Minting a group grant requires the chosen group name; only a re-wrap of an existing signed grant may omit it\",\n );\n const signingKeyPair = share.signingKeyPair;\n if (!signingKeyPair)\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n return input.mutate(\n {\n groupId: share.recipientGroupId,\n organizationId: share.author.organizationId,\n signerUserId: share.author.signerUserId,\n stillCurrent: share.stillCurrent ?? (() => true),\n },\n async (context) => {\n await assertCurrentShareGrantName(\n input.runtime,\n share,\n context,\n expectedName,\n );\n const request = await buildSetGroupContainerGrantPolicyRequest({\n ...context,\n accessLevel: share.accessLevel,\n containerId: share.containerId,\n signerUserId: share.author.signerUserId,\n signingFingerprint: share.author.signerKeyFingerprint,\n signingKeyPair,\n });\n const prepared: {\n batch?: PreparedPrincipalContainerRematerializationBatch;\n } = {};\n const response = await commitCurrentGroupPolicyMutation({\n apiClient: share.apiClient,\n context,\n groupId: share.recipientGroupId,\n organizationId: share.author.organizationId,\n request,\n signerUserId: share.author.signerUserId,\n signingFingerprint: share.author.signerKeyFingerprint,\n signingKeyPair,\n resolveTrustedUserIdentity: share.resolveTrustedUserIdentity,\n prepareContainerMutations: async (nextPolicy) => {\n prepared.batch = await prepareCurrentShareGrantBatch(\n share,\n context,\n nextPolicy,\n input.recitationStillCurrent,\n );\n return prepared.batch;\n },\n });\n const index =\n prepared.batch?.plans.findIndex(\n (planned) => planned.plan.containerId === share.containerId,\n ) ?? -1;\n const plan = prepared.batch?.plans[index];\n const acknowledgement = response.containerMutations[index];\n if (!plan || !acknowledgement || !isSharePlan(plan))\n throw new Error(\"Container group share acknowledgement is incomplete\");\n return {\n containerKey: plan.containerKey,\n plan: plan.plan,\n response: acknowledgement,\n };\n },\n );\n}\n\nfunction isSharePlan(\n plan: PreparedPrincipalContainerRematerializationBatch[\"plans\"][number],\n): plan is MaterializedContainerSharePlan {\n return plan.plan.body.eventType === \"container.grant\";\n}\n\nasync function assertCurrentShareGrantName(\n runtime: Parameters<typeof createRuntimeCurrentSharePrincipalPolicy>[0],\n share: Parameters<typeof shareRemoteContainerWithGroup>[0],\n context: RuntimeCurrentGroupMutationContext,\n expectedName: string,\n) {\n const mismatch = await groupPolicyNameMismatch(\n context.currentPolicy,\n expectedName,\n createRuntimeGroupMetadataAccess(\n runtime,\n share.author.organizationId,\n context.stillCurrent,\n context.verifyMetadataContainer,\n ).readName,\n );\n if (mismatch)\n throw new GroupShareNameMismatchError(\n \"Container share group name does not match the signed group policy\",\n );\n assertProjectionVerificationCurrent(context.stillCurrent);\n}\n\nfunction prepareCurrentShareGrantBatch(\n share: Parameters<typeof shareRemoteContainerWithGroup>[0],\n context: RuntimeCurrentGroupMutationContext,\n nextPolicy: Parameters<\n typeof preparePrincipalContainerRematerializationBatch\n >[0][\"nextPolicy\"],\n recitationStillCurrent?: () => boolean,\n) {\n return preparePrincipalContainerRematerializationBatch({\n ...share,\n grants: [\n ...new Map(\n [...context.currentPolicy.currentGrants, ...nextPolicy.grants].map(\n (grant) => [grant.containerId, grant] as const,\n ),\n ).values(),\n ],\n groupId: share.recipientGroupId,\n nextPolicy,\n resolveAuthoredPolicyReferences: context.resolveAuthoredPolicyReferences,\n stillCurrent: context.stillCurrent,\n recitationStillCurrent,\n });\n}\n"]}
@@ -0,0 +1,83 @@
1
+ import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../../data/keyingProjectionVerification/types.js";
3
+ import { advanceKeyingCheckpointsAtomically } from "../../../data/persistence/keyingCheckpointAdvancePersistence.js";
4
+ import { principalHeadMatchesReference } from "../../../data/principals/organizationAuthorityDescriptor.js";
5
+ import { createSelectedCurrentGroupMetadataContainerVerifier } from "../../organizations/currentGroupMetadataAuthority.js";
6
+ import { loadCurrentOrganizationAuthority } from "../../organizations/currentOrganizationAuthority.js";
7
+ import { createCurrentPrincipalMutationLease } from "../../organizations/currentPrincipalMutationLease.js";
8
+ import { assertGroupMetadataBinding } from "../../organizations/groupMetadataBinding.js";
9
+ import { createRuntimeGroupMetadataAccess } from "../../organizations/groupMetadataRuntime.js";
10
+ import { groupPolicyNameMismatch, } from "../../organizations/principalPolicyRequest.js";
11
+ import { GroupShareNameMismatchError } from "./sharePrincipalPolicy.js";
12
+ /** A share read need not be a group administrator; minting a grant checks that separately. */
13
+ export function createRuntimeCurrentSharePrincipalPolicy(runtime) {
14
+ const lease = createCurrentPrincipalMutationLease(runtime);
15
+ if (!lease)
16
+ return undefined;
17
+ return async (input, work) => {
18
+ input = {
19
+ ...input,
20
+ expectedGroupHead: input.expectedGroupHead
21
+ ? { ...input.expectedGroupHead }
22
+ : undefined,
23
+ };
24
+ return lease(input.stillCurrent, async ({ resolveCurrentPolicy, stillCurrent: leaseCurrent }) => {
25
+ await runtime.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);
26
+ assertProjectionVerificationCurrent(leaseCurrent);
27
+ const authority = await loadCurrentOrganizationAuthority({
28
+ execSql: runtime.infra.execSql,
29
+ organizationId: input.organizationId,
30
+ resolveCurrentPolicy,
31
+ stillCurrent: leaseCurrent,
32
+ });
33
+ const group = await authority.readGroup(input.groupId);
34
+ const stillCurrent = () => leaseCurrent() && authority.stillCurrent() && group.stillCurrent();
35
+ assertProjectionVerificationCurrent(stillCurrent);
36
+ if (input.expectedGroupHead &&
37
+ !principalHeadMatchesReference(group.policy.state, input.expectedGroupHead))
38
+ throw new KeyingVerificationError("object_mismatch", "Container share expected group head conflicts with the signed organization directory");
39
+ assertGroupMetadataBinding(group.current, authority.descriptor);
40
+ await assertCurrentShareName({
41
+ runtime,
42
+ input,
43
+ authority,
44
+ group,
45
+ stillCurrent,
46
+ });
47
+ assertProjectionVerificationCurrent(stillCurrent);
48
+ const checkpointPolicies = [...group.dependencies, group.policy];
49
+ await advanceKeyingCheckpointsAtomically({
50
+ access: [],
51
+ execSql: runtime.infra.execSql,
52
+ organizationId: input.organizationId,
53
+ policies: checkpointPolicies,
54
+ stillCurrent,
55
+ });
56
+ assertProjectionVerificationCurrent(stillCurrent);
57
+ const result = await work({
58
+ current: group.current,
59
+ policy: group.policy,
60
+ checkpointPolicies,
61
+ stillCurrent,
62
+ });
63
+ assertProjectionVerificationCurrent(stillCurrent);
64
+ return result;
65
+ });
66
+ };
67
+ }
68
+ async function assertCurrentShareName({ runtime, input, authority, group, stillCurrent, }) {
69
+ if (input.expectedGroupName === undefined)
70
+ return;
71
+ const readName = input.readEncryptedName ??
72
+ createRuntimeGroupMetadataAccess(runtime, input.organizationId, stillCurrent, createSelectedCurrentGroupMetadataContainerVerifier({
73
+ authority,
74
+ organizationId: input.organizationId,
75
+ stillCurrent,
76
+ })).readName;
77
+ const mismatch = await groupPolicyNameMismatch(group.current, input.expectedGroupName, readName);
78
+ if (mismatch)
79
+ throw new GroupShareNameMismatchError(mismatch === "forbidden_characters"
80
+ ? "Container share group name contains control or format characters"
81
+ : "Container share group name does not match the signed group policy");
82
+ }
83
+ //# sourceMappingURL=currentSharePrincipalPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentSharePrincipalPolicy.js","sourceRoot":"","sources":["currentSharePrincipalPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { advanceKeyingCheckpointsAtomically } from \"../../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { principalHeadMatchesReference } from \"../../../data/principals/organizationAuthorityDescriptor\";\nimport { createSelectedCurrentGroupMetadataContainerVerifier } from \"../../organizations/currentGroupMetadataAuthority\";\nimport { loadCurrentOrganizationAuthority } from \"../../organizations/currentOrganizationAuthority\";\nimport { createCurrentPrincipalMutationLease } from \"../../organizations/currentPrincipalMutationLease\";\nimport { assertGroupMetadataBinding } from \"../../organizations/groupMetadataBinding\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadataRuntime\";\nimport type { PrincipalMutationRecoveryApi } from \"../../organizations/principalMutationJournalManagement\";\nimport {\n type GroupPolicyNameReader,\n groupPolicyNameMismatch,\n} from \"../../organizations/principalPolicyRequest\";\nimport { GroupShareNameMismatchError } from \"./sharePrincipalPolicy\";\n\ntype CurrentShareRuntime = Parameters<\n typeof createRuntimeGroupMetadataAccess\n>[0] &\n Parameters<typeof createCurrentPrincipalMutationLease>[0] & {\n readonly apiClient: {\n readonly recoverPendingPrincipalMutation?:\n | PrincipalMutationRecoveryApi[\"recoverPendingPrincipalMutation\"]\n | undefined;\n };\n };\n\ninterface CurrentShareInput {\n readonly groupId: string;\n readonly organizationId: string;\n readonly expectedGroupHead?: ReferencedPrincipalHead | undefined;\n readonly expectedGroupName?: string | undefined;\n /** Trusted internal reader; it must authenticate the signed metadata container. */\n readonly readEncryptedName?: GroupPolicyNameReader | undefined;\n readonly stillCurrent: () => boolean;\n}\n\ntype CurrentGroup = Awaited<\n ReturnType<\n Awaited<ReturnType<typeof loadCurrentOrganizationAuthority>>[\"readGroup\"]\n >\n>;\n\nexport interface CurrentSharePrincipalPolicy {\n readonly current: CurrentGroup[\"current\"];\n readonly policy: CurrentGroup[\"policy\"];\n readonly checkpointPolicies: readonly CurrentGroup[\"policy\"][];\n readonly stillCurrent: () => boolean;\n}\n\n/** A share read need not be a group administrator; minting a grant checks that separately. */\nexport function createRuntimeCurrentSharePrincipalPolicy(\n runtime: CurrentShareRuntime,\n) {\n const lease = createCurrentPrincipalMutationLease(runtime);\n if (!lease) return undefined;\n return async <T>(\n input: CurrentShareInput,\n work: (policy: CurrentSharePrincipalPolicy) => Promise<T>,\n ): Promise<T> => {\n input = {\n ...input,\n expectedGroupHead: input.expectedGroupHead\n ? { ...input.expectedGroupHead }\n : undefined,\n };\n return lease(\n input.stillCurrent,\n async ({ resolveCurrentPolicy, stillCurrent: leaseCurrent }) => {\n await runtime.apiClient.recoverPendingPrincipalMutation?.(\n input.organizationId,\n );\n assertProjectionVerificationCurrent(leaseCurrent);\n const authority = await loadCurrentOrganizationAuthority({\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n resolveCurrentPolicy,\n stillCurrent: leaseCurrent,\n });\n const group = await authority.readGroup(input.groupId);\n const stillCurrent = () =>\n leaseCurrent() && authority.stillCurrent() && group.stillCurrent();\n assertProjectionVerificationCurrent(stillCurrent);\n if (\n input.expectedGroupHead &&\n !principalHeadMatchesReference(\n group.policy.state,\n input.expectedGroupHead,\n )\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Container share expected group head conflicts with the signed organization directory\",\n );\n assertGroupMetadataBinding(group.current, authority.descriptor);\n await assertCurrentShareName({\n runtime,\n input,\n authority,\n group,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const checkpointPolicies = [...group.dependencies, group.policy];\n await advanceKeyingCheckpointsAtomically({\n access: [],\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n policies: checkpointPolicies,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const result = await work({\n current: group.current,\n policy: group.policy,\n checkpointPolicies,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n return result;\n },\n );\n };\n}\n\nasync function assertCurrentShareName({\n runtime,\n input,\n authority,\n group,\n stillCurrent,\n}: {\n runtime: CurrentShareRuntime;\n input: CurrentShareInput;\n authority: Awaited<ReturnType<typeof loadCurrentOrganizationAuthority>>;\n group: CurrentGroup;\n stillCurrent: () => boolean;\n}) {\n if (input.expectedGroupName === undefined) return;\n const readName =\n input.readEncryptedName ??\n createRuntimeGroupMetadataAccess(\n runtime,\n input.organizationId,\n stillCurrent,\n createSelectedCurrentGroupMetadataContainerVerifier({\n authority,\n organizationId: input.organizationId,\n stillCurrent,\n }),\n ).readName;\n const mismatch = await groupPolicyNameMismatch(\n group.current,\n input.expectedGroupName,\n readName,\n );\n if (mismatch)\n throw new GroupShareNameMismatchError(\n mismatch === \"forbidden_characters\"\n ? \"Container share group name contains control or format characters\"\n : \"Container share group name does not match the signed group policy\",\n );\n}\n"]}
@@ -107,7 +107,7 @@ export async function submitAcknowledgedContainerMutation(input) {
107
107
  // path, so listing it here spares its recitation budget.
108
108
  plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],
109
109
  reportSecurityIncident: input.reportSecurityIncident,
110
- stillCurrent: input.stillCurrent,
110
+ stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,
111
111
  });
112
112
  }
113
113
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnyVerifiedPrincipalPolicy } from \"@tearleads/crypto\";\nimport type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./carriedDescendantRekeys\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly AnyVerifiedPrincipalPolicy[];\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) return null;\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
1
+ {"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./carriedDescendantRekeys\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n /** Session lifetime for best-effort work after durable acknowledgement. */\n recitationStillCurrent?: (() => boolean) | undefined;\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) return null;\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
@@ -0,0 +1,82 @@
1
+ import { nullOnProjectionVerificationCancellation, requireProjectionUserKeyResolver, } from "../../../data/keyingProjectionVerification.js";
2
+ import { principalPolicyCacheForVerifiedPolicies } from "../../../data/keyingProjectionVerification/principalPolicyCache.js";
3
+ import { inheritPrincipalHistoryProtection } from "../../../data/principals/principalHistoryRuntime.js";
4
+ import { createRuntimeCurrentGroupMutation } from "../../organizations/runtimeCurrentGroupMutation.js";
5
+ import { commitCurrentShareGrant } from "./currentShareGrantMutation.js";
6
+ import { createRuntimeCurrentSharePrincipalPolicy } from "./currentSharePrincipalPolicy.js";
7
+ import { submitAcknowledgedContainerMutation, submitPlainContainerMutation, } from "./mutationSubmit.js";
8
+ import { buildMaterializedContainerSharePlan } from "./shareMaterialization.js";
9
+ import { resolveShareProjection } from "./shareProjection.js";
10
+ /** Current evidence covers planning, any compound grant mint, and acknowledgement. */
11
+ export function createRuntimeCurrentGroupShare(runtime) {
12
+ const readCurrent = createRuntimeCurrentSharePrincipalPolicy(runtime);
13
+ const api = runtime.apiClient;
14
+ const readPages = api.getPrincipalPolicyPages;
15
+ if (!readCurrent || !readPages)
16
+ return undefined;
17
+ const mutate = createRuntimeCurrentGroupMutation(inheritPrincipalHistoryProtection(runtime, {
18
+ ...runtime,
19
+ apiClient: {
20
+ getPrincipalPolicyPages: readPages.bind(api),
21
+ ...(api.getProjectionPolicyHistoryPages
22
+ ? {
23
+ getProjectionPolicyHistoryPages: api.getProjectionPolicyHistoryPages.bind(api),
24
+ }
25
+ : {}),
26
+ recoverPendingPrincipalMutation: async (organizationId) => {
27
+ // Built-in clients supply journal recovery; standalone hosts retain
28
+ // the same transport/recovery responsibility as the legacy adapter.
29
+ await api.recoverPendingPrincipalMutation?.(organizationId);
30
+ },
31
+ },
32
+ }));
33
+ if (!mutate)
34
+ throw new Error("Current group mutation custody is unavailable");
35
+ return async (input) => {
36
+ if (input.stillCurrent?.() === false)
37
+ return null;
38
+ const recitationStillCurrent = input.stillCurrent ?? (() => true);
39
+ return nullOnProjectionVerificationCancellation(() => readCurrent({
40
+ expectedGroupName: input.expectedGroupName ?? undefined,
41
+ groupId: input.recipientGroupId,
42
+ organizationId: input.author.organizationId,
43
+ stillCurrent: input.stillCurrent ?? (() => true),
44
+ }, async ({ policy, checkpointPolicies, stillCurrent }) => {
45
+ const share = { ...input, stillCurrent };
46
+ const resolveProjectionUserKey = requireProjectionUserKeyResolver(input.resolveProjectionUserKey, "Remote container share");
47
+ const previousProjection = await resolveShareProjection(share, resolveProjectionUserKey);
48
+ if (!previousProjection)
49
+ return null;
50
+ const grant = policy.grants.find((candidate) => candidate.containerId === input.containerId);
51
+ if (!grant || grant.accessLevel !== input.accessLevel)
52
+ return commitCurrentShareGrant({
53
+ runtime,
54
+ share,
55
+ mutate,
56
+ recitationStillCurrent,
57
+ });
58
+ const materialized = await buildMaterializedContainerSharePlan({
59
+ ...share,
60
+ previousProjection,
61
+ principalPolicyCache: principalPolicyCacheForVerifiedPolicies(checkpointPolicies),
62
+ recipient: {
63
+ principalPolicy: policy,
64
+ subjectId: input.recipientGroupId,
65
+ subjectType: "group",
66
+ },
67
+ resolveProjectionUserKey,
68
+ });
69
+ return submitAcknowledgedContainerMutation({
70
+ ...share,
71
+ recitationPolicies: checkpointPolicies,
72
+ recitationStillCurrent,
73
+ containerKey: materialized.containerKey,
74
+ plan: materialized.plan,
75
+ submit: () => submitPlainContainerMutation(() => input.apiClient.shareContainer(input.containerId, materialized.plan.request, {
76
+ expectedPaymentRequiredOrganizationId: input.author.organizationId,
77
+ })),
78
+ });
79
+ }));
80
+ };
81
+ }
82
+ //# sourceMappingURL=runtimeCurrentGroupShare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeCurrentGroupShare.js","sourceRoot":"","sources":["runtimeCurrentGroupShare.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n nullOnProjectionVerificationCancellation,\n requireProjectionUserKeyResolver,\n} from \"../../../data/keyingProjectionVerification\";\nimport { principalPolicyCacheForVerifiedPolicies } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { inheritPrincipalHistoryProtection } from \"../../../data/principals/principalHistoryRuntime\";\nimport { createRuntimeCurrentGroupMutation } from \"../../organizations/runtimeCurrentGroupMutation\";\nimport { commitCurrentShareGrant } from \"./currentShareGrantMutation\";\nimport { createRuntimeCurrentSharePrincipalPolicy } from \"./currentSharePrincipalPolicy\";\nimport {\n submitAcknowledgedContainerMutation,\n submitPlainContainerMutation,\n} from \"./mutationSubmit\";\nimport type { shareRemoteContainerWithGroup } from \"./share\";\nimport { buildMaterializedContainerSharePlan } from \"./shareMaterialization\";\nimport { resolveShareProjection } from \"./shareProjection\";\n\n/** Current evidence covers planning, any compound grant mint, and acknowledgement. */\nexport function createRuntimeCurrentGroupShare(\n runtime: Parameters<typeof createRuntimeCurrentSharePrincipalPolicy>[0],\n): typeof shareRemoteContainerWithGroup | undefined {\n const readCurrent = createRuntimeCurrentSharePrincipalPolicy(runtime);\n const api = runtime.apiClient;\n const readPages = api.getPrincipalPolicyPages;\n if (!readCurrent || !readPages) return undefined;\n const mutate = createRuntimeCurrentGroupMutation(\n inheritPrincipalHistoryProtection(runtime, {\n ...runtime,\n apiClient: {\n getPrincipalPolicyPages: readPages.bind(api),\n ...(api.getProjectionPolicyHistoryPages\n ? {\n getProjectionPolicyHistoryPages:\n api.getProjectionPolicyHistoryPages.bind(api),\n }\n : {}),\n recoverPendingPrincipalMutation: async (organizationId: string) => {\n // Built-in clients supply journal recovery; standalone hosts retain\n // the same transport/recovery responsibility as the legacy adapter.\n await api.recoverPendingPrincipalMutation?.(organizationId);\n },\n },\n }),\n );\n if (!mutate) throw new Error(\"Current group mutation custody is unavailable\");\n return async (input) => {\n if (input.stillCurrent?.() === false) return null;\n const recitationStillCurrent = input.stillCurrent ?? (() => true);\n return nullOnProjectionVerificationCancellation(() =>\n readCurrent(\n {\n expectedGroupName: input.expectedGroupName ?? undefined,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n stillCurrent: input.stillCurrent ?? (() => true),\n },\n async ({ policy, checkpointPolicies, stillCurrent }) => {\n const share = { ...input, stillCurrent };\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const previousProjection = await resolveShareProjection(\n share,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n const grant = policy.grants.find(\n (candidate) => candidate.containerId === input.containerId,\n );\n if (!grant || grant.accessLevel !== input.accessLevel)\n return commitCurrentShareGrant({\n runtime,\n share,\n mutate,\n recitationStillCurrent,\n });\n const materialized = await buildMaterializedContainerSharePlan({\n ...share,\n previousProjection,\n principalPolicyCache:\n principalPolicyCacheForVerifiedPolicies(checkpointPolicies),\n recipient: {\n principalPolicy: policy,\n subjectId: input.recipientGroupId,\n subjectType: \"group\",\n },\n resolveProjectionUserKey,\n });\n return submitAcknowledgedContainerMutation({\n ...share,\n recitationPolicies: checkpointPolicies,\n recitationStillCurrent,\n containerKey: materialized.containerKey,\n plan: materialized.plan,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materialized.plan.request,\n {\n expectedPaymentRequiredOrganizationId:\n input.author.organizationId,\n },\n ),\n ),\n });\n },\n ),\n );\n };\n}\n"]}
@@ -7,27 +7,14 @@ import { createGroupMetadataContainerVerifier } from "../../organizations/groupM
7
7
  import { preparePrincipalContainerRematerializationBatch } from "../../organizations/principalContainerRematerialization.js";
8
8
  import { setOrganizationGroupContainerGrant } from "../../organizations/principalPolicy.js";
9
9
  import { submitAcknowledgedContainerMutation, submitPlainContainerMutation, } from "./mutationSubmit.js";
10
- import { projectionWithCurrentAncestors } from "./shareAncestorRepair.js";
11
10
  import { buildMaterializedContainerSharePlan } from "./shareMaterialization.js";
12
11
  import { advanceVerifiedSharePolicies, loadVerifiedGroupSharePrincipalPolicy, } from "./sharePrincipalPolicy.js";
12
+ import { resolveShareProjection } from "./shareProjection.js";
13
13
  class ContainerShareGenerationExpiredError extends Error {
14
14
  }
15
15
  async function buildCurrentContainerSharePlan(input) {
16
16
  return nullOnProjectionVerificationCancellation(() => buildMaterializedContainerSharePlan(input));
17
17
  }
18
- /** The container's projection, with any lazily stale chain above it repaired. */
19
- async function resolveShareProjection(input, resolveProjectionUserKey) {
20
- const servedProjection = input.previousProjection ??
21
- (await input.apiClient.getContainerWriterProjection(input.containerId));
22
- if (!servedProjection || input.stillCurrent?.() === false)
23
- return null;
24
- const previousProjection = await projectionWithCurrentAncestors({
25
- ...input,
26
- previousProjection: servedProjection,
27
- resolveProjectionUserKey,
28
- });
29
- return input.stillCurrent?.() === false ? null : previousProjection;
30
- }
31
18
  export async function shareRemoteContainer(input) {
32
19
  const resolveProjectionUserKey = requireProjectionUserKeyResolver(input.resolveProjectionUserKey, "Remote container share");
33
20
  const resolveTrustedUserIdentity = requireTrustedUserIdentityResolver(input.resolveTrustedUserIdentity);
@@ -1 +1 @@
1
- {"version":3,"file":"share.js","sourceRoot":"","sources":["share.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerAccessLevel,\n SigningKeyPair,\n VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport type {\n ContainerMutationAuthor,\n ContainerShareApi,\n ContainerSharePlan,\n MaterializedContainerSharePlan,\n} from \"../../../data/containers/shared/types\";\nimport {\n isProjectionVerificationCancelledError,\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../../data/keyingProjectionVerification\";\nimport { principalPolicyCacheForVerifiedPolicies } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { savePrincipalPolicyBundle } from \"../../../data/persistence/principalPolicyPersistence\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n requireTrustedUserIdentityResolver,\n type TrustedUserIdentityResolver,\n} from \"../../../data/trustedUserIdentity\";\nimport { createGroupMetadataAccess } from \"../../organizations/groupMetadataAccess\";\nimport { createGroupMetadataContainerVerifier } from \"../../organizations/groupMetadataContainerAuthority\";\nimport { preparePrincipalContainerRematerializationBatch } from \"../../organizations/principalContainerRematerialization\";\nimport { setOrganizationGroupContainerGrant } from \"../../organizations/principalPolicy\";\nimport type { GroupPolicyNameReader } from \"../../organizations/principalPolicyRequest\";\nimport {\n submitAcknowledgedContainerMutation,\n submitPlainContainerMutation,\n} from \"./mutationSubmit\";\nimport { projectionWithCurrentAncestors } from \"./shareAncestorRepair\";\nimport { buildMaterializedContainerSharePlan } from \"./shareMaterialization\";\nimport {\n advanceVerifiedSharePolicies,\n type ContainerManagedPrincipalShareApi,\n loadVerifiedGroupSharePrincipalPolicy,\n} from \"./sharePrincipalPolicy\";\n\nclass ContainerShareGenerationExpiredError extends Error {}\n\nasync function buildCurrentContainerSharePlan(\n input: Parameters<typeof buildMaterializedContainerSharePlan>[0],\n): Promise<MaterializedContainerSharePlan | null> {\n return nullOnProjectionVerificationCancellation(() =>\n buildMaterializedContainerSharePlan(input),\n );\n}\n\n/** The container's projection, with any lazily stale chain above it repaired. */\nasync function resolveShareProjection(\n input: Omit<\n Parameters<typeof projectionWithCurrentAncestors>[0],\n \"previousProjection\" | \"resolveProjectionUserKey\"\n > & { previousProjection?: ContainerWriterProjectionResponse | undefined },\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<ContainerWriterProjectionResponse | null> {\n const servedProjection =\n input.previousProjection ??\n (await input.apiClient.getContainerWriterProjection(input.containerId));\n if (!servedProjection || input.stillCurrent?.() === false) return null;\n const previousProjection = await projectionWithCurrentAncestors({\n ...input,\n previousProjection: servedProjection,\n resolveProjectionUserKey,\n });\n return input.stillCurrent?.() === false ? null : previousProjection;\n}\n\nexport async function shareRemoteContainer(input: {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n} | null> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const resolveTrustedUserIdentity = requireTrustedUserIdentityResolver(\n input.resolveTrustedUserIdentity,\n );\n const recipientIdentity = await resolveTrustedUserIdentity(\n input.recipientUserId,\n );\n if (!recipientIdentity || input.stillCurrent?.() === false) {\n return null;\n }\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n previousProjection,\n recipient: {\n recipientEncapsulationPublicKey: recipientIdentity.encapsulationPublicKey,\n subjectId: input.recipientUserId,\n subjectType: \"user\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n return submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: [],\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n}\n\ninterface RemoteContainerGroupShareInput {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerManagedPrincipalShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n /**\n * The display name the user chose the group by, checked against the name\n * committed in the verified group policy so a relabeled read-model row\n * cannot redirect the share onto another group. `null` is reserved for the\n * grant-preserving re-wrap: a share that would mint a new grant without a\n * name is refused.\n */\n expectedGroupName: string | null;\n readEncryptedName?: GroupPolicyNameReader | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n signingKeyPair?: SigningKeyPair | null | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\ninterface RemoteContainerGroupShareResult {\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n}\n\nfunction isMaterializedContainerSharePlan(\n value: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >[\"plans\"][number],\n): value is MaterializedContainerSharePlan {\n return value.plan.body.eventType === \"container.grant\";\n}\n\nasync function prepareMissingGroupGrantMutations(input: {\n currentPolicy: PrincipalPolicyBundleResponse;\n nextPolicy: VerifiedPrincipalPolicy;\n shareInput: RemoteContainerGroupShareInput;\n}) {\n const { currentPolicy, nextPolicy, shareInput } = input;\n return preparePrincipalContainerRematerializationBatch({\n reportSecurityIncident: shareInput.reportSecurityIncident,\n apiClient: shareInput.apiClient,\n author: shareInput.author,\n execSql: shareInput.execSql,\n grants: [\n ...new Map(\n [...currentPolicy.currentGrants, ...nextPolicy.grants].map(\n (grant) => [grant.containerId, grant] as const,\n ),\n ).values(),\n ],\n groupId: shareInput.recipientGroupId,\n nextPolicy,\n resolveTrustedUserIdentity: shareInput.resolveTrustedUserIdentity,\n stillCurrent: shareInput.stillCurrent,\n targetSecretKey: shareInput.targetSecretKey,\n warmReferencedPrincipalPolicies: shareInput.warmReferencedPrincipalPolicies,\n });\n}\n\nasync function commitMissingGroupGrantPolicy(\n input: RemoteContainerGroupShareInput,\n): Promise<{\n preparedTarget: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >;\n storedPolicy: Awaited<ReturnType<typeof setOrganizationGroupContainerGrant>>;\n} | null> {\n const signingKeyPair = input.signingKeyPair;\n if (!signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n const policyApi = {\n recoverPendingPrincipalMutation:\n input.apiClient.recoverPendingPrincipalMutation?.bind(input.apiClient),\n commitOrganizationGroupPolicy:\n input.apiClient.commitOrganizationGroupPolicy.bind(input.apiClient),\n getCurrentPrincipalPolicy: input.apiClient.getCurrentPrincipalPolicy.bind(\n input.apiClient,\n ),\n };\n let preparedTarget:\n | Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >\n | undefined;\n try {\n const storedPolicy = await setOrganizationGroupContainerGrant({\n accessLevel: input.accessLevel,\n apiClient: policyApi,\n assertCanCommit: () => {\n if (input.stillCurrent?.() === false) {\n throw new ContainerShareGenerationExpiredError();\n }\n },\n containerId: input.containerId,\n execSql: input.execSql,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n prepareContainerMutations: async ({ currentPolicy, nextPolicy }) => {\n preparedTarget = await prepareMissingGroupGrantMutations({\n currentPolicy,\n nextPolicy,\n shareInput: input,\n });\n return preparedTarget;\n },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n signerUserId: input.author.signerUserId,\n signingFingerprint: input.author.signerKeyFingerprint,\n signingKeyPair,\n });\n if (!preparedTarget) {\n throw new Error(\"Container group share preparation is incomplete\");\n }\n return { preparedTarget, storedPolicy };\n } catch (error) {\n if (\n error instanceof ContainerShareGenerationExpiredError ||\n isProjectionVerificationCancelledError(error)\n ) {\n return null;\n }\n throw error;\n }\n}\n\nasync function commitMissingGroupGrant(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (!input.signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n if (input.stillCurrent?.() === false) return null;\n const committed = await commitMissingGroupGrantPolicy(input);\n if (!committed) return null;\n const { preparedTarget, storedPolicy } = committed;\n const targetIndex = preparedTarget?.plans.findIndex(\n (planned) => planned.plan.containerId === input.containerId,\n );\n const response =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : storedPolicy.containerMutations[targetIndex];\n const targetPlan =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : preparedTarget?.plans[targetIndex];\n if (\n !targetPlan ||\n !response ||\n !isMaterializedContainerSharePlan(targetPlan)\n ) {\n throw new Error(\"Container group share acknowledgement is incomplete\");\n }\n return {\n containerKey: targetPlan.containerKey,\n plan: targetPlan.plan,\n response,\n };\n}\n\n// Only a re-wrap of an existing signed grant may run without the chosen name;\n// minting a grant is exactly the operation the name binding protects.\nfunction assertGrantMintNamed(expectedGroupName: string | null): void {\n if (expectedGroupName === null) {\n throw new Error(\n \"Minting a group grant requires the chosen group name; only a re-wrap of an existing signed grant may omit it\",\n );\n }\n}\n\nfunction loadShareGroupPolicy(input: RemoteContainerGroupShareInput) {\n return loadVerifiedGroupSharePrincipalPolicy({\n apiClient: input.apiClient,\n execSql: input.execSql,\n expectedGroupName: input.expectedGroupName ?? undefined,\n readEncryptedName:\n input.readEncryptedName ??\n createGroupMetadataAccess({\n ...input,\n organizationId: input.author.organizationId,\n verifyMetadataContainer: createGroupMetadataContainerVerifier({\n ...input,\n organizationId: input.author.organizationId,\n stillCurrent: input.stillCurrent ?? (() => true),\n }),\n }).readName,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n}\n\nexport async function shareRemoteContainerWithGroup(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (input.stillCurrent?.() === false) return null;\n await input.apiClient.recoverPendingPrincipalMutation?.(\n input.author.organizationId,\n );\n if (input.stillCurrent?.() === false) return null;\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n const verifiedPrincipalPolicy = await loadShareGroupPolicy(input);\n if (input.stillCurrent?.() === false) return null;\n await advanceVerifiedSharePolicies(\n input.execSql,\n verifiedPrincipalPolicy,\n input.stillCurrent,\n );\n if (input.stillCurrent?.() === false) return null;\n\n const signedGrant = verifiedPrincipalPolicy.policy.grants.find(\n (grant) => grant.containerId === input.containerId,\n );\n if (!signedGrant || signedGrant.accessLevel !== input.accessLevel) {\n assertGrantMintNamed(input.expectedGroupName);\n return commitMissingGroupGrant(input);\n }\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n principalPolicyCache: principalPolicyCacheForVerifiedPolicies(\n verifiedPrincipalPolicy.checkpointPolicies,\n ),\n previousProjection,\n recipient: {\n principalPolicy: verifiedPrincipalPolicy.policy,\n subjectId: input.recipientGroupId,\n subjectType: \"group\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n const result = await submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: verifiedPrincipalPolicy.checkpointPolicies,\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n if (!result) return null;\n\n // Keep the previously cached group epoch available until the old container\n // wrap has been unwrapped and the replacement has committed. Root has no\n // parent fallback, so caching the rotated policy any earlier destroys the\n // only local path to the KEK that must be re-wrapped.\n if (input.stillCurrent?.() !== false) {\n await savePrincipalPolicyBundle(\n input.execSql,\n verifiedPrincipalPolicy.bundle,\n new Date().toISOString(),\n input.author.organizationId,\n { stillCurrent: input.stillCurrent },\n );\n }\n if (input.stillCurrent?.() === false) return null;\n\n return result;\n}\n"]}
1
+ {"version":3,"file":"share.js","sourceRoot":"","sources":["share.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerAccessLevel,\n SigningKeyPair,\n VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport type {\n ContainerMutationAuthor,\n ContainerShareApi,\n ContainerSharePlan,\n MaterializedContainerSharePlan,\n} from \"../../../data/containers/shared/types\";\nimport {\n isProjectionVerificationCancelledError,\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../../data/keyingProjectionVerification\";\nimport { principalPolicyCacheForVerifiedPolicies } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { savePrincipalPolicyBundle } from \"../../../data/persistence/principalPolicyPersistence\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n requireTrustedUserIdentityResolver,\n type TrustedUserIdentityResolver,\n} from \"../../../data/trustedUserIdentity\";\nimport { createGroupMetadataAccess } from \"../../organizations/groupMetadataAccess\";\nimport { createGroupMetadataContainerVerifier } from \"../../organizations/groupMetadataContainerAuthority\";\nimport { preparePrincipalContainerRematerializationBatch } from \"../../organizations/principalContainerRematerialization\";\nimport { setOrganizationGroupContainerGrant } from \"../../organizations/principalPolicy\";\nimport type { GroupPolicyNameReader } from \"../../organizations/principalPolicyRequest\";\nimport {\n submitAcknowledgedContainerMutation,\n submitPlainContainerMutation,\n} from \"./mutationSubmit\";\nimport { buildMaterializedContainerSharePlan } from \"./shareMaterialization\";\nimport {\n advanceVerifiedSharePolicies,\n type ContainerManagedPrincipalShareApi,\n loadVerifiedGroupSharePrincipalPolicy,\n} from \"./sharePrincipalPolicy\";\nimport { resolveShareProjection } from \"./shareProjection\";\n\nclass ContainerShareGenerationExpiredError extends Error {}\n\nasync function buildCurrentContainerSharePlan(\n input: Parameters<typeof buildMaterializedContainerSharePlan>[0],\n): Promise<MaterializedContainerSharePlan | null> {\n return nullOnProjectionVerificationCancellation(() =>\n buildMaterializedContainerSharePlan(input),\n );\n}\n\nexport async function shareRemoteContainer(input: {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n} | null> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const resolveTrustedUserIdentity = requireTrustedUserIdentityResolver(\n input.resolveTrustedUserIdentity,\n );\n const recipientIdentity = await resolveTrustedUserIdentity(\n input.recipientUserId,\n );\n if (!recipientIdentity || input.stillCurrent?.() === false) {\n return null;\n }\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n previousProjection,\n recipient: {\n recipientEncapsulationPublicKey: recipientIdentity.encapsulationPublicKey,\n subjectId: input.recipientUserId,\n subjectType: \"user\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n return submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: [],\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n}\n\ninterface RemoteContainerGroupShareInput {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerManagedPrincipalShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n /**\n * The display name the user chose the group by, checked against the name\n * committed in the verified group policy so a relabeled read-model row\n * cannot redirect the share onto another group. `null` is reserved for the\n * grant-preserving re-wrap: a share that would mint a new grant without a\n * name is refused.\n */\n expectedGroupName: string | null;\n readEncryptedName?: GroupPolicyNameReader | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n signingKeyPair?: SigningKeyPair | null | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\ninterface RemoteContainerGroupShareResult {\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n}\n\nfunction isMaterializedContainerSharePlan(\n value: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >[\"plans\"][number],\n): value is MaterializedContainerSharePlan {\n return value.plan.body.eventType === \"container.grant\";\n}\n\nasync function prepareMissingGroupGrantMutations(input: {\n currentPolicy: PrincipalPolicyBundleResponse;\n nextPolicy: VerifiedPrincipalPolicy;\n shareInput: RemoteContainerGroupShareInput;\n}) {\n const { currentPolicy, nextPolicy, shareInput } = input;\n return preparePrincipalContainerRematerializationBatch({\n reportSecurityIncident: shareInput.reportSecurityIncident,\n apiClient: shareInput.apiClient,\n author: shareInput.author,\n execSql: shareInput.execSql,\n grants: [\n ...new Map(\n [...currentPolicy.currentGrants, ...nextPolicy.grants].map(\n (grant) => [grant.containerId, grant] as const,\n ),\n ).values(),\n ],\n groupId: shareInput.recipientGroupId,\n nextPolicy,\n resolveTrustedUserIdentity: shareInput.resolveTrustedUserIdentity,\n stillCurrent: shareInput.stillCurrent,\n targetSecretKey: shareInput.targetSecretKey,\n warmReferencedPrincipalPolicies: shareInput.warmReferencedPrincipalPolicies,\n });\n}\n\nasync function commitMissingGroupGrantPolicy(\n input: RemoteContainerGroupShareInput,\n): Promise<{\n preparedTarget: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >;\n storedPolicy: Awaited<ReturnType<typeof setOrganizationGroupContainerGrant>>;\n} | null> {\n const signingKeyPair = input.signingKeyPair;\n if (!signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n const policyApi = {\n recoverPendingPrincipalMutation:\n input.apiClient.recoverPendingPrincipalMutation?.bind(input.apiClient),\n commitOrganizationGroupPolicy:\n input.apiClient.commitOrganizationGroupPolicy.bind(input.apiClient),\n getCurrentPrincipalPolicy: input.apiClient.getCurrentPrincipalPolicy.bind(\n input.apiClient,\n ),\n };\n let preparedTarget:\n | Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >\n | undefined;\n try {\n const storedPolicy = await setOrganizationGroupContainerGrant({\n accessLevel: input.accessLevel,\n apiClient: policyApi,\n assertCanCommit: () => {\n if (input.stillCurrent?.() === false) {\n throw new ContainerShareGenerationExpiredError();\n }\n },\n containerId: input.containerId,\n execSql: input.execSql,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n prepareContainerMutations: async ({ currentPolicy, nextPolicy }) => {\n preparedTarget = await prepareMissingGroupGrantMutations({\n currentPolicy,\n nextPolicy,\n shareInput: input,\n });\n return preparedTarget;\n },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n signerUserId: input.author.signerUserId,\n signingFingerprint: input.author.signerKeyFingerprint,\n signingKeyPair,\n });\n if (!preparedTarget) {\n throw new Error(\"Container group share preparation is incomplete\");\n }\n return { preparedTarget, storedPolicy };\n } catch (error) {\n if (\n error instanceof ContainerShareGenerationExpiredError ||\n isProjectionVerificationCancelledError(error)\n ) {\n return null;\n }\n throw error;\n }\n}\n\nasync function commitMissingGroupGrant(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (!input.signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n if (input.stillCurrent?.() === false) return null;\n const committed = await commitMissingGroupGrantPolicy(input);\n if (!committed) return null;\n const { preparedTarget, storedPolicy } = committed;\n const targetIndex = preparedTarget?.plans.findIndex(\n (planned) => planned.plan.containerId === input.containerId,\n );\n const response =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : storedPolicy.containerMutations[targetIndex];\n const targetPlan =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : preparedTarget?.plans[targetIndex];\n if (\n !targetPlan ||\n !response ||\n !isMaterializedContainerSharePlan(targetPlan)\n ) {\n throw new Error(\"Container group share acknowledgement is incomplete\");\n }\n return {\n containerKey: targetPlan.containerKey,\n plan: targetPlan.plan,\n response,\n };\n}\n\n// Only a re-wrap of an existing signed grant may run without the chosen name;\n// minting a grant is exactly the operation the name binding protects.\nfunction assertGrantMintNamed(expectedGroupName: string | null): void {\n if (expectedGroupName === null) {\n throw new Error(\n \"Minting a group grant requires the chosen group name; only a re-wrap of an existing signed grant may omit it\",\n );\n }\n}\n\nfunction loadShareGroupPolicy(input: RemoteContainerGroupShareInput) {\n return loadVerifiedGroupSharePrincipalPolicy({\n apiClient: input.apiClient,\n execSql: input.execSql,\n expectedGroupName: input.expectedGroupName ?? undefined,\n readEncryptedName:\n input.readEncryptedName ??\n createGroupMetadataAccess({\n ...input,\n organizationId: input.author.organizationId,\n verifyMetadataContainer: createGroupMetadataContainerVerifier({\n ...input,\n organizationId: input.author.organizationId,\n stillCurrent: input.stillCurrent ?? (() => true),\n }),\n }).readName,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n}\n\nexport async function shareRemoteContainerWithGroup(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (input.stillCurrent?.() === false) return null;\n await input.apiClient.recoverPendingPrincipalMutation?.(\n input.author.organizationId,\n );\n if (input.stillCurrent?.() === false) return null;\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n const verifiedPrincipalPolicy = await loadShareGroupPolicy(input);\n if (input.stillCurrent?.() === false) return null;\n await advanceVerifiedSharePolicies(\n input.execSql,\n verifiedPrincipalPolicy,\n input.stillCurrent,\n );\n if (input.stillCurrent?.() === false) return null;\n\n const signedGrant = verifiedPrincipalPolicy.policy.grants.find(\n (grant) => grant.containerId === input.containerId,\n );\n if (!signedGrant || signedGrant.accessLevel !== input.accessLevel) {\n assertGrantMintNamed(input.expectedGroupName);\n return commitMissingGroupGrant(input);\n }\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n principalPolicyCache: principalPolicyCacheForVerifiedPolicies(\n verifiedPrincipalPolicy.checkpointPolicies,\n ),\n previousProjection,\n recipient: {\n principalPolicy: verifiedPrincipalPolicy.policy,\n subjectId: input.recipientGroupId,\n subjectType: \"group\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n const result = await submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: verifiedPrincipalPolicy.checkpointPolicies,\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n if (!result) return null;\n\n // Keep the previously cached group epoch available until the old container\n // wrap has been unwrapped and the replacement has committed. Root has no\n // parent fallback, so caching the rotated policy any earlier destroys the\n // only local path to the KEK that must be re-wrapped.\n if (input.stillCurrent?.() !== false) {\n await savePrincipalPolicyBundle(\n input.execSql,\n verifiedPrincipalPolicy.bundle,\n new Date().toISOString(),\n input.author.organizationId,\n { stillCurrent: input.stillCurrent },\n );\n }\n if (input.stillCurrent?.() === false) return null;\n\n return result;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import { projectionWithCurrentAncestors } from "./shareAncestorRepair.js";
2
+ /** The container's projection, with any lazily stale chain above it repaired. */
3
+ export async function resolveShareProjection(input, resolveProjectionUserKey) {
4
+ const servedProjection = input.previousProjection ??
5
+ (await input.apiClient.getContainerWriterProjection(input.containerId));
6
+ if (!servedProjection || input.stillCurrent?.() === false)
7
+ return null;
8
+ const previousProjection = await projectionWithCurrentAncestors({
9
+ ...input,
10
+ previousProjection: servedProjection,
11
+ resolveProjectionUserKey,
12
+ });
13
+ return input.stillCurrent?.() === false ? null : previousProjection;
14
+ }
15
+ //# sourceMappingURL=shareProjection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shareProjection.js","sourceRoot":"","sources":["shareProjection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAEvE,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAG0E,EAC1E,wBAAmD;IAEnD,MAAM,gBAAgB,GACpB,KAAK,CAAC,kBAAkB;QACxB,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,4BAA4B,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACvE,MAAM,kBAAkB,GAAG,MAAM,8BAA8B,CAAC;QAC9D,GAAG,KAAK;QACR,kBAAkB,EAAE,gBAAgB;QACpC,wBAAwB;KACzB,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACtE,CAAC","sourcesContent":["import type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { projectionWithCurrentAncestors } from \"./shareAncestorRepair\";\n\n/** The container's projection, with any lazily stale chain above it repaired. */\nexport async function resolveShareProjection(\n input: Omit<\n Parameters<typeof projectionWithCurrentAncestors>[0],\n \"previousProjection\" | \"resolveProjectionUserKey\"\n > & { previousProjection?: ContainerWriterProjectionResponse | undefined },\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<ContainerWriterProjectionResponse | null> {\n const servedProjection =\n input.previousProjection ??\n (await input.apiClient.getContainerWriterProjection(input.containerId));\n if (!servedProjection || input.stillCurrent?.() === false) return null;\n const previousProjection = await projectionWithCurrentAncestors({\n ...input,\n previousProjection: servedProjection,\n resolveProjectionUserKey,\n });\n return input.stillCurrent?.() === false ? null : previousProjection;\n}\n"]}
@@ -11,7 +11,7 @@ export function referencedPrincipalHeadsFromContainerMutationResponse(input) {
11
11
  return input.response.referencedPrincipalHeads.flatMap((head) => {
12
12
  if (!isReferencedPrincipalStateResponse(head) ||
13
13
  !Number.isInteger(head.version) ||
14
- !Number.isInteger(head.keyEpoch)) {
14
+ !Number.isSafeInteger(head.keyEpoch)) {
15
15
  return [];
16
16
  }
17
17
  return [
@@ -1 +1 @@
1
- {"version":3,"file":"mutationResponse.js","sourceRoot":"","sources":["mutationResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,GAEnC,MAAM,gCAAgC,CAAC;AAExC,MAAM,UAAU,uCAAuC,CAAC,KAIvD;IACC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CACpC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EACnC,oBAAoB,CACrB,CAAC;IACF,IACE,OAAO,kBAAkB,KAAK,QAAQ;QACtC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qDAAqD,CAAC,KAErE;IACC,OAAO,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC9D,IACE,CAAC,kCAAkC,CAAC,IAAI,CAAC;YACzC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;YAC/B,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAChC,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO;YACL;gBACE,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,cAAc,EAAE,IAAI,CAAC,cAAc;aACpC;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n isReferencedPrincipalStateResponse,\n type ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\n\nexport function readContainerMutationMetadataDocumentId(input: {\n response: {\n accessManifest: { state: Record<string, unknown> };\n };\n}): string {\n const metadataDocumentId = Reflect.get(\n input.response.accessManifest.state,\n \"metadataDocumentId\",\n );\n if (\n typeof metadataDocumentId !== \"string\" ||\n metadataDocumentId.length === 0\n ) {\n throw new Error(\"Container mutation response is missing metadata state\");\n }\n\n return metadataDocumentId;\n}\n\nexport function referencedPrincipalHeadsFromContainerMutationResponse(input: {\n response: { referencedPrincipalHeads: readonly unknown[] };\n}): ReferencedPrincipalStateResponse[] {\n return input.response.referencedPrincipalHeads.flatMap((head) => {\n if (\n !isReferencedPrincipalStateResponse(head) ||\n !Number.isInteger(head.version) ||\n !Number.isInteger(head.keyEpoch)\n ) {\n return [];\n }\n\n return [\n {\n principalType: head.principalType,\n principalId: head.principalId,\n version: head.version,\n keyEpoch: head.keyEpoch,\n stateHash: head.stateHash,\n keyFingerprint: head.keyFingerprint,\n },\n ];\n });\n}\n"]}
1
+ {"version":3,"file":"mutationResponse.js","sourceRoot":"","sources":["mutationResponse.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kCAAkC,GAEnC,MAAM,gCAAgC,CAAC;AAExC,MAAM,UAAU,uCAAuC,CAAC,KAIvD;IACC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CACpC,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC,KAAK,EACnC,oBAAoB,CACrB,CAAC;IACF,IACE,OAAO,kBAAkB,KAAK,QAAQ;QACtC,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,kBAAkB,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qDAAqD,CAAC,KAErE;IACC,OAAO,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC9D,IACE,CAAC,kCAAkC,CAAC,IAAI,CAAC;YACzC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;YAC/B,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpC,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO;YACL;gBACE,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,cAAc,EAAE,IAAI,CAAC,cAAc;aACpC;SACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n isReferencedPrincipalStateResponse,\n type ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\n\nexport function readContainerMutationMetadataDocumentId(input: {\n response: {\n accessManifest: { state: Record<string, unknown> };\n };\n}): string {\n const metadataDocumentId = Reflect.get(\n input.response.accessManifest.state,\n \"metadataDocumentId\",\n );\n if (\n typeof metadataDocumentId !== \"string\" ||\n metadataDocumentId.length === 0\n ) {\n throw new Error(\"Container mutation response is missing metadata state\");\n }\n\n return metadataDocumentId;\n}\n\nexport function referencedPrincipalHeadsFromContainerMutationResponse(input: {\n response: { referencedPrincipalHeads: readonly unknown[] };\n}): ReferencedPrincipalStateResponse[] {\n return input.response.referencedPrincipalHeads.flatMap((head) => {\n if (\n !isReferencedPrincipalStateResponse(head) ||\n !Number.isInteger(head.version) ||\n !Number.isSafeInteger(head.keyEpoch)\n ) {\n return [];\n }\n\n return [\n {\n principalType: head.principalType,\n principalId: head.principalId,\n version: head.version,\n keyEpoch: head.keyEpoch,\n stateHash: head.stateHash,\n keyFingerprint: head.keyFingerprint,\n },\n ];\n });\n}\n"]}
@@ -29,6 +29,8 @@ export declare function createVerifiedRemoteDocumentDeletionHandler(input: {
29
29
  readonly documentId: string;
30
30
  }) => Promise<void> | void;
31
31
  readonly resolveProjectionUserKey: ProjectionUserKeyResolver;
32
+ readonly stillCurrent?: (() => boolean) | undefined;
33
+ readonly warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;
32
34
  }): (deleted: {
33
35
  readonly documentId: string;
34
36
  }) => Promise<void>;
@@ -41,6 +43,7 @@ export declare function purgeRemoteDocument(input: {
41
43
  readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;
42
44
  }) => Promise<void> | void;
43
45
  readonly resolveProjectionUserKey: ProjectionUserKeyResolver;
46
+ readonly stillCurrent?: (() => boolean) | undefined;
44
47
  readonly warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;
45
48
  }): Promise<DocumentPurgeResponse | null>;
46
49
  export {};
@@ -26,6 +26,8 @@ async function loadAuthenticatedDocumentPurgeProof(input) {
26
26
  expectedOrganizationId: input.expectedOrganizationId,
27
27
  proof: initialProof,
28
28
  resolveUserKey: input.resolveProjectionUserKey,
29
+ stillCurrent: input.stillCurrent,
30
+ warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
29
31
  });
30
32
  // The current API returns complete history to recorded readers. Otherwise
31
33
  // its terminal snapshot needs an exact local pin; a floor refetch cannot
@@ -105,6 +107,8 @@ export function createVerifiedRemoteDocumentDeletionHandler(input) {
105
107
  execSql: input.execSql,
106
108
  expectedOrganizationId: input.expectedOrganizationId,
107
109
  resolveProjectionUserKey: input.resolveProjectionUserKey,
110
+ stillCurrent: input.stillCurrent,
111
+ warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
108
112
  });
109
113
  if (!proof) {
110
114
  throw new ProjectionDependencyUnavailableError("Remote document deletion is missing its signed purge proof");
@@ -115,6 +119,8 @@ export function createVerifiedRemoteDocumentDeletionHandler(input) {
115
119
  expectedOrganizationId: input.expectedOrganizationId,
116
120
  proof,
117
121
  resolveUserKey: input.resolveProjectionUserKey,
122
+ stillCurrent: input.stillCurrent,
123
+ warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
118
124
  });
119
125
  await input.onVerifiedDeletion({
120
126
  commitPurgeProof: verified.commitCheckpoints,
@@ -137,6 +143,8 @@ export async function purgeRemoteDocument(input) {
137
143
  execSql: input.execSql,
138
144
  expectedOrganizationId: input.author.organizationId,
139
145
  resolveProjectionUserKey: input.resolveProjectionUserKey,
146
+ stillCurrent: input.stillCurrent,
147
+ warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
140
148
  });
141
149
  if (!proof) {
142
150
  throw new ProjectionDependencyUnavailableError("Purged remote document is missing its signed purge proof");
@@ -147,6 +155,8 @@ export async function purgeRemoteDocument(input) {
147
155
  expectedOrganizationId: input.author.organizationId,
148
156
  proof,
149
157
  resolveUserKey: input.resolveProjectionUserKey,
158
+ stillCurrent: input.stillCurrent,
159
+ warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
150
160
  });
151
161
  await input.onVerifiedPurge({
152
162
  commitPurgeProof: verified.commitCheckpoints,
@@ -157,6 +167,7 @@ export async function purgeRemoteDocument(input) {
157
167
  execSql: input.execSql,
158
168
  projection: writerProjection,
159
169
  resolveUserKey: input.resolveProjectionUserKey,
170
+ stillCurrent: input.stillCurrent,
160
171
  warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
161
172
  });
162
173
  const request = await buildDocumentPurgeRequest({
@@ -175,6 +186,8 @@ export async function purgeRemoteDocument(input) {
175
186
  expectedOrganizationId: input.author.organizationId,
176
187
  proof: response,
177
188
  resolveUserKey: input.resolveProjectionUserKey,
189
+ stillCurrent: input.stillCurrent,
190
+ warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
178
191
  });
179
192
  await input.onVerifiedPurge({
180
193
  commitPurgeProof: verified.commitCheckpoints,