@tearleads/client-sdk 0.1.58 → 0.1.59

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 (380) hide show
  1. package/Tearleads.d.ts +2 -2
  2. package/Tearleads.js +1 -1
  3. package/Tearleads.js.map +1 -1
  4. package/client/blobs.d.ts +1 -1
  5. package/client/blobs.js.map +1 -1
  6. package/client/deviceFirst.js.map +1 -1
  7. package/client/identity.js +1 -1
  8. package/client/identity.js.map +1 -1
  9. package/client/index.d.ts +1 -1
  10. package/client/index.js +1 -1
  11. package/client/index.js.map +1 -1
  12. package/client/organizations/organizationAccessRestoration.js.map +1 -1
  13. package/client/organizations/organizationDataUsage.js.map +1 -1
  14. package/client/organizations/organizationGroupNameHydration.js.map +1 -1
  15. package/client/organizations/organizationMetadataProfileSync.js +1 -1
  16. package/client/organizations/organizationMetadataProfileSync.js.map +1 -1
  17. package/client/organizations/organizationReadModels.js.map +1 -1
  18. package/client/organizations/organizationWorkflowRuntime.js.map +1 -1
  19. package/client/rootContainerAdoption.js.map +1 -1
  20. package/client/securityIncidents.d.ts +1 -1
  21. package/client/securityIncidents.js.map +1 -1
  22. package/client/session/sessionLoginRefusal.js.map +1 -1
  23. package/client/session/sessionRootAuthority.js.map +1 -1
  24. package/client/session/sessionTypes.d.ts +1 -1
  25. package/client/session/sessionTypes.js.map +1 -1
  26. package/client/userIdentities.d.ts +1 -1
  27. package/client/userIdentities.js.map +1 -1
  28. package/client/workflowRuntime.d.ts +2 -2
  29. package/client/workflowRuntime.js.map +1 -1
  30. package/data/blobs/createBlobStore.d.ts +1 -1
  31. package/data/blobs/createBlobStore.js.map +1 -1
  32. package/data/blobs/encryptedBlobByteSource.js +1 -1
  33. package/data/blobs/encryptedBlobByteSource.js.map +1 -1
  34. package/data/blobs/encryptedBlobEnvelope.d.ts +1 -1
  35. package/data/blobs/encryptedBlobEnvelope.js +2 -2
  36. package/data/blobs/encryptedBlobEnvelope.js.map +1 -1
  37. package/data/blobs/encryptedBlobStore.d.ts +1 -1
  38. package/data/blobs/encryptedBlobStore.js +1 -1
  39. package/data/blobs/encryptedBlobStore.js.map +1 -1
  40. package/data/blobs/memoryBlobStore.d.ts +1 -1
  41. package/data/blobs/memoryBlobStore.js +1 -1
  42. package/data/blobs/memoryBlobStore.js.map +1 -1
  43. package/data/blobs/opfsBlobStore.d.ts +1 -1
  44. package/data/blobs/opfsBlobStore.js +1 -1
  45. package/data/blobs/opfsBlobStore.js.map +1 -1
  46. package/data/containers/containerMetadataDocument.js +1 -1
  47. package/data/containers/containerMetadataDocument.js.map +1 -1
  48. package/data/containers/shared/events.js +1 -1
  49. package/data/containers/shared/events.js.map +1 -1
  50. package/data/containers/shared/heldContainerHeads.js +1 -1
  51. package/data/containers/shared/heldContainerHeads.js.map +1 -1
  52. package/data/containers/shared/mutationAcknowledgement.js +1 -1
  53. package/data/containers/shared/mutationAcknowledgement.js.map +1 -1
  54. package/data/containers/shared/principalPolicies.js +1 -1
  55. package/data/containers/shared/principalPolicies.js.map +1 -1
  56. package/data/containers/shared/readers.js +2 -2
  57. package/data/containers/shared/readers.js.map +1 -1
  58. package/data/documents/attachmentContentIdentity.js +1 -1
  59. package/data/documents/attachmentContentIdentity.js.map +1 -1
  60. package/data/documents/blob/shared/blobEnvelopeStream.js.map +1 -1
  61. package/data/documents/blob/shared/blobSourceSnapshot.d.ts +1 -1
  62. package/data/documents/blob/shared/blobSourceSnapshot.js.map +1 -1
  63. package/data/documents/blob/shared/chunkedBlobCrypto.js.map +1 -1
  64. package/data/documents/blob/shared/encryptedUploadParts.js.map +1 -1
  65. package/data/documents/blob/shared/events.js +1 -1
  66. package/data/documents/blob/shared/events.js.map +1 -1
  67. package/data/documents/blob/shared/types.d.ts +2 -2
  68. package/data/documents/blob/shared/types.js.map +1 -1
  69. package/data/documents/shared/containerKekPathHistory.js +1 -1
  70. package/data/documents/shared/containerKekPathHistory.js.map +1 -1
  71. package/data/documents/shared/containerKekPathVerification.d.ts +1 -1
  72. package/data/documents/shared/containerKekPathVerification.js +1 -1
  73. package/data/documents/shared/events.js +1 -1
  74. package/data/documents/shared/events.js.map +1 -1
  75. package/data/documents/shared/manifestBundleReaders.js +2 -2
  76. package/data/documents/shared/manifestBundleReaders.js.map +1 -1
  77. package/data/documents/shared/projection.d.ts +1 -1
  78. package/data/documents/shared/projection.js +2 -2
  79. package/data/documents/shared/projection.js.map +1 -1
  80. package/data/documents/shared/projectionContentKeys.d.ts +1 -1
  81. package/data/documents/shared/readers.js +3 -3
  82. package/data/documents/shared/readers.js.map +1 -1
  83. package/data/documents/shared/stableDocumentId.js +1 -1
  84. package/data/documents/shared/stableDocumentId.js.map +1 -1
  85. package/data/documents/shared/types.d.ts +1 -1
  86. package/data/documents/shared/types.js +1 -1
  87. package/data/{keyingCanonicalJson.js → keying/canonicalJson.js} +3 -3
  88. package/data/keying/canonicalJson.js.map +1 -0
  89. package/data/keyingProjectionVerification/bundleVerification.js +1 -1
  90. package/data/keyingProjectionVerification/bundleVerification.js.map +1 -1
  91. package/data/keyingProjectionVerification/containerAncestorCitations.js +1 -1
  92. package/data/keyingProjectionVerification/containerAncestorCitations.js.map +1 -1
  93. package/data/keyingProjectionVerification/containerManifestVerification.js +1 -1
  94. package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
  95. package/data/keyingProjectionVerification/documentManifestVerification.js +1 -1
  96. package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
  97. package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js +1 -1
  98. package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +1 -1
  99. package/data/keyingProjectionVerification/error.js +1 -1
  100. package/data/keyingProjectionVerification/error.js.map +1 -1
  101. package/data/keyingProjectionVerification/index.d.ts +9 -0
  102. package/data/{keyingProjectionVerification.js → keyingProjectionVerification/index.js} +8 -8
  103. package/data/keyingProjectionVerification/index.js.map +1 -0
  104. package/data/keyingProjectionVerification/principalPolicyCache.js +1 -1
  105. package/data/keyingProjectionVerification/principalPolicyCache.js.map +1 -1
  106. package/data/keyingProjectionVerification/principalPolicyVerification.js +1 -1
  107. package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
  108. package/data/keyingProjectionVerification/readers.d.ts +1 -1
  109. package/data/keyingProjectionVerification/readers.js +3 -3
  110. package/data/keyingProjectionVerification/readers.js.map +1 -1
  111. package/data/keyingProjectionVerification/userKeyResolver.d.ts +1 -1
  112. package/data/keyingProjectionVerification/userKeyResolver.js.map +1 -1
  113. package/data/persistence/containers/containerPersistence.js +1 -1
  114. package/data/persistence/containers/containerPersistence.js.map +1 -1
  115. package/data/persistence/documents/documentDiscoveryCandidate.js +1 -1
  116. package/data/persistence/documents/documentDiscoveryCandidate.js.map +1 -1
  117. package/data/persistence/documents/documentDiscoveryEvidencePersistence.js +1 -1
  118. package/data/persistence/documents/documentDiscoveryEvidencePersistence.js.map +1 -1
  119. package/data/persistence/documents/internal/documentProjectionRows.js +1 -1
  120. package/data/persistence/documents/internal/documentProjectionRows.js.map +1 -1
  121. package/data/persistence/documents/internal/documentRows.js +1 -1
  122. package/data/persistence/documents/internal/documentRows.js.map +1 -1
  123. package/data/persistence/principalPolicyBundleIntegrity.js +1 -1
  124. package/data/persistence/principalPolicyBundleIntegrity.js.map +1 -1
  125. package/data/persistence/principalPolicyReferenceCheckpoint.js +1 -1
  126. package/data/persistence/principalPolicyReferenceCheckpoint.js.map +1 -1
  127. package/data/persistence/principalPolicyReferenceIndexPersistence.js +1 -1
  128. package/data/persistence/principalPolicyReferenceIndexPersistence.js.map +1 -1
  129. package/data/persistence/principalPolicyReferencePersistence.js +1 -1
  130. package/data/persistence/principalPolicyReferencePersistence.js.map +1 -1
  131. package/data/persistence/securityIncidentPersistence.js.map +1 -1
  132. package/data/persistence/verifiedPrincipalPolicyBundle.js +1 -1
  133. package/data/persistence/verifiedPrincipalPolicyBundle.js.map +1 -1
  134. package/data/persistence/verifiedPrincipalPolicyCurrent.js +1 -1
  135. package/data/persistence/verifiedPrincipalPolicyCurrent.js.map +1 -1
  136. package/data/principals/principalMutationJournal.js +1 -1
  137. package/data/principals/principalMutationJournal.js.map +1 -1
  138. package/data/{securityIncidents.d.ts → shared/securityIncidents.d.ts} +1 -1
  139. package/data/sqlite/documentRecordPersistence.js +1 -1
  140. package/data/sqlite/documentRecordPersistence.js.map +1 -1
  141. package/data/sync/crdtPeerSeed.d.ts +18 -0
  142. package/data/sync/originatedDocuments.d.ts +1 -1
  143. package/data/sync/originatedDocuments.js.map +1 -1
  144. package/data/sync/syncCoordinator.d.ts +1 -1
  145. package/data/sync/syncCoordinator.js.map +1 -1
  146. package/package.json +1 -1
  147. package/stores/container-contents/backgroundHydration.js +1 -1
  148. package/stores/container-contents/backgroundHydration.js.map +1 -1
  149. package/stores/container-contents/containerContentsStore.d.ts +1 -1
  150. package/stores/container-contents/containerContentsStore.js.map +1 -1
  151. package/stores/container-contents/localRefresh.js +1 -1
  152. package/stores/container-contents/localRefresh.js.map +1 -1
  153. package/stores/container-contents/remoteContainerIngestion.js +1 -1
  154. package/stores/container-contents/remoteContainerIngestion.js.map +1 -1
  155. package/stores/container-contents/remoteWriteQueue.js +1 -1
  156. package/stores/container-contents/remoteWriteQueue.js.map +1 -1
  157. package/stores/container-contents/systemContainerHydration.js +1 -1
  158. package/stores/container-contents/systemContainerHydration.js.map +1 -1
  159. package/stores/container-contents/utils.js +1 -1
  160. package/stores/container-contents/utils.js.map +1 -1
  161. package/stores/documents/documentStore/attachmentIntents.js +1 -1
  162. package/stores/documents/documentStore/attachmentIntents.js.map +1 -1
  163. package/stores/documents/documentStore/attachmentSourceUpload.js.map +1 -1
  164. package/stores/documents/documentStore/attachmentStaging.js +1 -1
  165. package/stores/documents/documentStore/attachmentStaging.js.map +1 -1
  166. package/stores/documents/documentStore/attachmentUploadLane.js.map +1 -1
  167. package/stores/documents/documentStore/persistence.js +2 -2
  168. package/stores/documents/documentStore/persistence.js.map +1 -1
  169. package/stores/documents/documentStore/state.js +1 -1
  170. package/stores/documents/documentStore/state.js.map +1 -1
  171. package/stores/documents/documentStore/storedDocument.js +1 -1
  172. package/stores/documents/documentStore/storedDocument.js.map +1 -1
  173. package/stores/documents/documentStore/syncAttachments.js.map +1 -1
  174. package/stores/documents/documentStore.d.ts +1 -1
  175. package/stores/documents/documentStore.js.map +1 -1
  176. package/stores/documents/registry.d.ts +1 -1
  177. package/stores/documents/registry.js.map +1 -1
  178. package/stores/documents/types.d.ts +1 -1
  179. package/stores/documents/types.js.map +1 -1
  180. package/stores/local-projection/registry.d.ts +1 -1
  181. package/stores/local-projection/registry.js.map +1 -1
  182. package/sync/reconciliation/serviceTypes.d.ts +1 -1
  183. package/sync/reconciliation/serviceTypes.js.map +1 -1
  184. package/sync/reconciliation/triggers.d.ts +1 -1
  185. package/sync/reconciliation/triggers.js.map +1 -1
  186. package/workflows/blobs/attachmentBindingVerification.js +2 -2
  187. package/workflows/blobs/attachmentBindingVerification.js.map +1 -1
  188. package/workflows/blobs/blobChunkDecryption.js.map +1 -1
  189. package/workflows/blobs/decrypt.d.ts +1 -1
  190. package/workflows/blobs/decrypt.js +2 -2
  191. package/workflows/blobs/decrypt.js.map +1 -1
  192. package/workflows/blobs/detach.js +2 -2
  193. package/workflows/blobs/detach.js.map +1 -1
  194. package/workflows/blobs/hydrate.d.ts +3 -3
  195. package/workflows/blobs/hydrate.js +1 -1
  196. package/workflows/blobs/hydrate.js.map +1 -1
  197. package/workflows/blobs/hydrationResults.js.map +1 -1
  198. package/workflows/blobs/index.d.ts +2 -2
  199. package/workflows/blobs/index.js +1 -1
  200. package/workflows/blobs/index.js.map +1 -1
  201. package/workflows/blobs/multipartFirstParts.js.map +1 -1
  202. package/workflows/blobs/retainedAttachmentVerification.js +1 -1
  203. package/workflows/blobs/upload.js +3 -3
  204. package/workflows/blobs/upload.js.map +1 -1
  205. package/workflows/container-contents/container-state/createAdoption.js +1 -1
  206. package/workflows/container-contents/container-state/createAdoption.js.map +1 -1
  207. package/workflows/container-contents/container-state/createChild.js +1 -1
  208. package/workflows/container-contents/container-state/createChild.js.map +1 -1
  209. package/workflows/container-contents/container-state/createIntentSync.js +1 -1
  210. package/workflows/container-contents/container-state/createIntentSync.js.map +1 -1
  211. package/workflows/container-contents/container-state/groupGrantVerification.js +1 -1
  212. package/workflows/container-contents/container-state/moveIntentSync.js +1 -1
  213. package/workflows/container-contents/container-state/moveIntentSync.js.map +1 -1
  214. package/workflows/container-contents/container-state/purgeTreeScope.js +1 -1
  215. package/workflows/container-contents/container-state/purgeTreeScope.js.map +1 -1
  216. package/workflows/container-contents/container-state/share.js +1 -1
  217. package/workflows/container-contents/documentDiscoveryInputs.js +1 -1
  218. package/workflows/container-contents/documentDiscoveryInputs.js.map +1 -1
  219. package/workflows/container-contents/documentInfo.d.ts +1 -1
  220. package/workflows/container-contents/documentInfo.js.map +1 -1
  221. package/workflows/container-contents/documentLinks.d.ts +1 -1
  222. package/workflows/container-contents/documentLinks.js +1 -1
  223. package/workflows/container-contents/documentLinks.js.map +1 -1
  224. package/workflows/container-contents/documentMoveIntentSync.js +1 -1
  225. package/workflows/container-contents/documentMoveIntentSync.js.map +1 -1
  226. package/workflows/container-contents/documentPurge.d.ts +1 -1
  227. package/workflows/container-contents/documentPurge.js +1 -1
  228. package/workflows/container-contents/documentPurge.js.map +1 -1
  229. package/workflows/container-contents/documentQueries/rows.js +1 -1
  230. package/workflows/container-contents/documentQueries/rows.js.map +1 -1
  231. package/workflows/container-contents/metadata.d.ts +1 -1
  232. package/workflows/container-contents/metadataMutationPreparation.js +1 -1
  233. package/workflows/container-contents/metadataMutationPreparation.js.map +1 -1
  234. package/workflows/container-contents/metadataRemoteSync.d.ts +1 -1
  235. package/workflows/container-contents/metadataSyncErrors.js.map +1 -1
  236. package/workflows/container-contents/projectionKeys.d.ts +1 -1
  237. package/workflows/container-contents/syncLane.d.ts +1 -1
  238. package/workflows/container-contents/syncLane.js.map +1 -1
  239. package/workflows/containers/child/carriedDescendantRekeys.js +1 -1
  240. package/workflows/containers/child/create.d.ts +1 -1
  241. package/workflows/containers/child/create.js +2 -2
  242. package/workflows/containers/child/create.js.map +1 -1
  243. package/workflows/containers/child/createProjection.js +1 -1
  244. package/workflows/containers/child/createProjection.js.map +1 -1
  245. package/workflows/containers/child/createSubmission.d.ts +2 -2
  246. package/workflows/containers/child/createSubmission.js.map +1 -1
  247. package/workflows/containers/child/move.d.ts +2 -2
  248. package/workflows/containers/child/move.js +2 -2
  249. package/workflows/containers/child/move.js.map +1 -1
  250. package/workflows/containers/child/moveWraps.js +1 -1
  251. package/workflows/containers/child/mutationRequestCore.js +1 -1
  252. package/workflows/containers/child/mutationRequestCore.js.map +1 -1
  253. package/workflows/containers/child/mutationSubmit.js.map +1 -1
  254. package/workflows/containers/child/recite.js.map +1 -1
  255. package/workflows/containers/child/recitePlan.js +1 -1
  256. package/workflows/containers/child/recitePlan.js.map +1 -1
  257. package/workflows/containers/child/rekey.d.ts +1 -1
  258. package/workflows/containers/child/rekey.js +2 -2
  259. package/workflows/containers/child/rekey.js.map +1 -1
  260. package/workflows/containers/child/rekeyProjection.js +1 -1
  261. package/workflows/containers/child/rekeyProjection.js.map +1 -1
  262. package/workflows/containers/child/rekeyRemote.d.ts +2 -2
  263. package/workflows/containers/child/rekeyRemote.js.map +1 -1
  264. package/workflows/containers/child/revoke.d.ts +2 -2
  265. package/workflows/containers/child/revoke.js +2 -2
  266. package/workflows/containers/child/revoke.js.map +1 -1
  267. package/workflows/containers/child/rotationPrincipalPolicies.js +1 -1
  268. package/workflows/containers/child/runtimeCurrentGroupShare.js +1 -1
  269. package/workflows/containers/child/share.d.ts +2 -2
  270. package/workflows/containers/child/share.js +1 -1
  271. package/workflows/containers/child/share.js.map +1 -1
  272. package/workflows/containers/child/shareAncestorRepair.js.map +1 -1
  273. package/workflows/containers/child/shareMaterialization.d.ts +1 -1
  274. package/workflows/containers/child/sharePlanCore.d.ts +1 -1
  275. package/workflows/containers/child/sharePlanCore.js +1 -1
  276. package/workflows/containers/root/create.js +1 -1
  277. package/workflows/containers/root/create.js.map +1 -1
  278. package/workflows/containers/root/initialGroupPolicy.js +1 -1
  279. package/workflows/containers/root/initialGroupPolicy.js.map +1 -1
  280. package/workflows/documents/create.d.ts +1 -1
  281. package/workflows/documents/create.js +1 -1
  282. package/workflows/documents/documentMutationPreparation.js +1 -1
  283. package/workflows/documents/documentMutationPreparation.js.map +1 -1
  284. package/workflows/documents/historyContent.js +1 -1
  285. package/workflows/documents/historyContent.js.map +1 -1
  286. package/workflows/documents/linkSet.js +1 -1
  287. package/workflows/documents/linkSet.js.map +1 -1
  288. package/workflows/documents/linkSetAuthority.js +1 -1
  289. package/workflows/documents/linkSetBlobRewraps.js +2 -2
  290. package/workflows/documents/linkSetBlobRewraps.js.map +1 -1
  291. package/workflows/documents/linkSetRemote.d.ts +1 -1
  292. package/workflows/documents/linkSetRemote.js +1 -1
  293. package/workflows/documents/orphanBlobReclaims.js +1 -1
  294. package/workflows/documents/orphanBlobReclaims.js.map +1 -1
  295. package/workflows/documents/projectionKeys.d.ts +1 -1
  296. package/workflows/documents/purge.d.ts +1 -1
  297. package/workflows/documents/purge.js +2 -2
  298. package/workflows/documents/purge.js.map +1 -1
  299. package/workflows/documents/readOnlySync.d.ts +1 -1
  300. package/workflows/documents/readOnlySync.js +1 -1
  301. package/workflows/documents/readOnlySync.js.map +1 -1
  302. package/workflows/documents/sync.js +1 -1
  303. package/workflows/documents/syncContainerRekeyPreparation.js +1 -1
  304. package/workflows/documents/syncLane.d.ts +1 -1
  305. package/workflows/documents/syncLane.js.map +1 -1
  306. package/workflows/documents/syncPlanIdentity.js +1 -1
  307. package/workflows/documents/syncPlanIdentity.js.map +1 -1
  308. package/workflows/documents/syncRepairAccess.js +1 -1
  309. package/workflows/documents/syncSubmittedResult.js +1 -1
  310. package/workflows/organizations/authoredPrincipalPolicyWarmer.js +1 -1
  311. package/workflows/organizations/authoredPrincipalPolicyWarmer.js.map +1 -1
  312. package/workflows/organizations/containerGrantRevocation.d.ts +2 -2
  313. package/workflows/organizations/containerGrantRevocation.js.map +1 -1
  314. package/workflows/organizations/createCurrentOrganizationGroup.js.map +1 -1
  315. package/workflows/organizations/currentOrganizationGroupNames.js.map +1 -1
  316. package/workflows/organizations/currentPolicyMutationAcknowledgement.js +1 -1
  317. package/workflows/organizations/currentPolicyMutationAcknowledgement.js.map +1 -1
  318. package/workflows/organizations/groupCreation.d.ts +1 -1
  319. package/workflows/organizations/groupCreation.js.map +1 -1
  320. package/workflows/organizations/groupMetadataAccess.d.ts +1 -1
  321. package/workflows/organizations/groupMetadataContainerAuthority.js.map +1 -1
  322. package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
  323. package/workflows/organizations/groupNameUniqueness.js.map +1 -1
  324. package/workflows/organizations/groupPolicyMutationAcknowledgement.js +1 -1
  325. package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +1 -1
  326. package/workflows/organizations/groupPolicyRequests.js.map +1 -1
  327. package/workflows/organizations/loadPolicyHistoryDetails.js.map +1 -1
  328. package/workflows/organizations/organizationGroupDirectory.js.map +1 -1
  329. package/workflows/organizations/organizationProfile.js +1 -1
  330. package/workflows/organizations/organizationProfile.js.map +1 -1
  331. package/workflows/organizations/policyHistoryCache.js.map +1 -1
  332. package/workflows/organizations/principalContainerRematerialization.js +1 -1
  333. package/workflows/organizations/principalContainerRematerializationPlanning.js.map +1 -1
  334. package/workflows/organizations/principalMutationJournalManagement.js +1 -1
  335. package/workflows/organizations/principalMutationJournalManagement.js.map +1 -1
  336. package/workflows/organizations/principalMutationReceipt.js +1 -1
  337. package/workflows/organizations/principalMutationReceipt.js.map +1 -1
  338. package/workflows/organizations/principalPolicy.d.ts +1 -1
  339. package/workflows/organizations/principalPolicy.js.map +1 -1
  340. package/workflows/organizations/principalPolicyReceiptArtifacts.js +1 -1
  341. package/workflows/organizations/principalPolicyReceiptArtifacts.js.map +1 -1
  342. package/workflows/organizations/rosterProfileContainer.js +1 -1
  343. package/workflows/organizations/rosterProfileContainer.js.map +1 -1
  344. package/workflows/principals/policyCache.d.ts +1 -1
  345. package/workflows/principals/policyCache.js +2 -2
  346. package/workflows/principals/policyCache.js.map +1 -1
  347. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  348. package/workflows/principals/runtimePolicyWarmer.js +1 -1
  349. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
  350. package/workflows/registration/persistRegistrationBootstrap.js +1 -1
  351. package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
  352. package/workflows/runtimeInput.d.ts +3 -3
  353. package/workflows/runtimeInput.js.map +1 -1
  354. package/workflows/sync/index.d.ts +2 -1
  355. package/workflows/sync/index.js +2 -1
  356. package/workflows/sync/index.js.map +1 -1
  357. package/data/keyingCanonicalJson.js.map +0 -1
  358. package/data/keyingProjectionVerification.d.ts +0 -9
  359. package/data/keyingProjectionVerification.js.map +0 -1
  360. /package/data/{blobContracts.d.ts → blobs/blobContracts.d.ts} +0 -0
  361. /package/data/{blobContracts.js → blobs/blobContracts.js} +0 -0
  362. /package/data/{blobContracts.js.map → blobs/blobContracts.js.map} +0 -0
  363. /package/data/{accessLevel.js → keying/accessLevel.js} +0 -0
  364. /package/data/{accessLevel.js.map → keying/accessLevel.js.map} +0 -0
  365. /package/data/{stableUuid.js → keying/stableUuid.js} +0 -0
  366. /package/data/{stableUuid.js.map → keying/stableUuid.js.map} +0 -0
  367. /package/data/{principalPolicyStates.js → principals/principalPolicyStates.js} +0 -0
  368. /package/data/{principalPolicyStates.js.map → principals/principalPolicyStates.js.map} +0 -0
  369. /package/data/{domainScope.d.ts → shared/domainScope.d.ts} +0 -0
  370. /package/data/{domainScope.js → shared/domainScope.js} +0 -0
  371. /package/data/{domainScope.js.map → shared/domainScope.js.map} +0 -0
  372. /package/data/{errorMessage.js → shared/errorMessage.js} +0 -0
  373. /package/data/{errorMessage.js.map → shared/errorMessage.js.map} +0 -0
  374. /package/data/{recordReaders.d.ts → shared/recordReaders.d.ts} +0 -0
  375. /package/data/{recordReaders.js → shared/recordReaders.js} +0 -0
  376. /package/data/{recordReaders.js.map → shared/recordReaders.js.map} +0 -0
  377. /package/data/{securityIncidents.js → shared/securityIncidents.js} +0 -0
  378. /package/data/{securityIncidents.js.map → shared/securityIncidents.js.map} +0 -0
  379. /package/data/{crdtPeerSeed.js → sync/crdtPeerSeed.js} +0 -0
  380. /package/data/{crdtPeerSeed.js.map → sync/crdtPeerSeed.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"groupPolicyMutationAcknowledgement.js","sourceRoot":"","sources":["groupPolicyMutationAcknowledgement.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computePrincipalContainerGrantRoot,\n computePrincipalMemberEnvelopesRoot,\n computePrincipalMembershipRoot,\n computePrincipalProjectionRoot,\n computePrincipalStatePayloadCiphertextHash,\n makeVerifiedPrincipalPolicy,\n normalizePrincipalProjectionMembers,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicy,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type {\n CreateOrganizationGroupRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationGroupSummaryResponse,\n PrincipalPolicyBundleResponse,\n PrincipalPolicyMutationResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../../data/keyingCanonicalJson\";\nimport {\n type CurrentPolicyMutationInput,\n verifyCurrentPolicyMutation,\n} from \"./currentPolicyMutationAcknowledgement\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\nexport { assertGroupPolicyEnvelopesMatchAcknowledgement } from \"./principalPolicyReceiptArtifacts\";\n\nfunction historyWithCurrent(\n bundle: PrincipalPolicyBundleResponse,\n): PrincipalPolicyBundleResponse[\"previousStates\"] {\n return [\n ...bundle.previousStates,\n {\n state: bundle.currentState,\n projection: bundle.currentProjection,\n grants: bundle.currentGrants,\n },\n ];\n}\n\nfunction isAuthoredSuccessorConsistent(\n state: Pick<\n PrincipalStateResponse,\n | \"keyEpoch\"\n | \"keyFingerprint\"\n | \"prevStateHash\"\n | \"principalId\"\n | \"principalType\"\n | \"version\"\n >,\n expectedHead: ReferencedPrincipalHead,\n previous: PrincipalStateResponse,\n): boolean {\n return (\n state.principalType === expectedHead.principalType &&\n state.principalId === expectedHead.principalId &&\n state.version === expectedHead.version &&\n state.keyEpoch === expectedHead.keyEpoch &&\n state.keyFingerprint === expectedHead.keyFingerprint &&\n state.principalType === previous.principalType &&\n state.principalId === previous.principalId &&\n state.version === previous.version + 1 &&\n state.prevStateHash === previous.stateHash\n );\n}\n\nexport function buildAcknowledgedGroupPolicyBundle(input: {\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n}): PrincipalPolicyBundleResponse & PrincipalPolicyMutationResponse {\n assertPrincipalPolicyReceiptArtifacts(input);\n return {\n ...input.response,\n previousStates: historyWithCurrent(input.currentPolicy),\n };\n}\n\nasync function assertPolicyRequestCommitments(\n request: PutPrincipalPolicyRequest,\n): Promise<void> {\n const projection = normalizePrincipalProjectionMembers(request.projection);\n const members = projection.map((member) => ({ userId: member.userId }));\n const [\n membershipRoot,\n memberEnvelopesRoot,\n projectionRoot,\n payloadCiphertextHash,\n grantRoot,\n ] = await Promise.all([\n computePrincipalMembershipRoot(members),\n computePrincipalMemberEnvelopesRoot(request.memberEnvelopes),\n computePrincipalProjectionRoot(projection),\n computePrincipalStatePayloadCiphertextHash(\n request.encryptedPayload.ciphertext,\n ),\n computePrincipalContainerGrantRoot(request.grants),\n ]);\n if (\n request.state.membershipRoot !== membershipRoot ||\n request.state.memberEnvelopesRoot !== memberEnvelopesRoot ||\n request.state.projectionRoot !== projectionRoot ||\n request.state.memberCount !== projection.length ||\n request.state.grantRoot !== grantRoot ||\n request.state.grantCount !== request.grants.length ||\n request.encryptedPayload.ciphertextHash !== payloadCiphertextHash ||\n request.state.payloadCiphertextHash !== payloadCiphertextHash\n ) {\n throw new Error(\"Authored group policy commitments are invalid\");\n }\n}\n\nfunction verifiedPolicy(input: {\n currentPolicy?: PrincipalPolicyBundleResponse | undefined;\n projection: PutPrincipalPolicyRequest[\"projection\"];\n grants: PutPrincipalPolicyRequest[\"grants\"];\n state: PrincipalStateResponse;\n}): VerifiedPrincipalPolicy {\n const previousStates = input.currentPolicy\n ? historyWithCurrent(input.currentPolicy)\n : [];\n return makeVerifiedPrincipalPolicy({\n checkpoint: {\n principalId: input.state.principalId,\n principalType: input.state.principalType,\n stateHash: input.state.stateHash,\n version: input.state.version,\n },\n history: [\n ...previousStates,\n {\n state: input.state,\n projection: input.projection,\n grants: input.grants,\n },\n ],\n keyEpoch: input.state.keyEpoch,\n principalId: input.state.principalId,\n principalType: input.state.principalType,\n projection: input.projection,\n grants: input.grants,\n state: input.state,\n stateHash: input.state.stateHash,\n version: input.state.version,\n });\n}\n\ninterface FullPolicyMutationInput {\n readonly verifiedCurrentPolicy?: never;\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly request: PutPrincipalPolicyRequest;\n}\n\nexport function acknowledgeGroupPolicyState(\n input: CurrentPolicyMutationInput & {\n readonly response: PrincipalStateResponse;\n },\n): Promise<VerifiedPrincipalPolicyCurrent>;\nexport function acknowledgeGroupPolicyState(\n input: FullPolicyMutationInput & {\n readonly response: PrincipalStateResponse;\n },\n): Promise<VerifiedPrincipalPolicy>;\nexport async function acknowledgeGroupPolicyState(\n input: (FullPolicyMutationInput | CurrentPolicyMutationInput) & {\n readonly response: PrincipalStateResponse;\n },\n): Promise<VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent> {\n if (input.verifiedCurrentPolicy !== undefined)\n return verifyCurrentPolicyMutation(input, input.response);\n await assertPolicyRequestCommitments(input.request);\n const { createdAt: _createdAt, stateHash, ...responseState } = input.response;\n const previous = input.currentPolicy.currentState;\n if (\n stateHash !== input.expectedHead.stateHash ||\n !isAuthoredSuccessorConsistent(\n input.response,\n input.expectedHead,\n previous,\n ) ||\n canonicalKeyingJsonString(responseState, \"stored group policy state\") !==\n canonicalKeyingJsonString(\n input.request.state,\n \"authored group policy state\",\n )\n ) {\n throw new Error(\"Group policy state acknowledgement mismatch\");\n }\n return verifiedPolicy({\n currentPolicy: input.currentPolicy,\n projection: input.request.projection,\n grants: input.request.grants,\n state: input.response,\n });\n}\n\n/**\n * Materialize the locally signed successor before submission so dependent\n * container mutations can wrap to the exact head that will commit with it.\n * The server still performs the authoritative signature, transition, and\n * authorization checks inside the combined transaction.\n */\nexport function prepareAuthoredGroupPolicy(\n input: CurrentPolicyMutationInput,\n): Promise<VerifiedPrincipalPolicyCurrent>;\nexport function prepareAuthoredGroupPolicy(\n input: FullPolicyMutationInput,\n): Promise<VerifiedPrincipalPolicy>;\nexport async function prepareAuthoredGroupPolicy(\n input: FullPolicyMutationInput | CurrentPolicyMutationInput,\n): Promise<VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent> {\n if (input.verifiedCurrentPolicy !== undefined)\n return verifyCurrentPolicyMutation(input);\n await assertPolicyRequestCommitments(input.request);\n const previous = input.currentPolicy.currentState;\n const state = input.request.state;\n if (!isAuthoredSuccessorConsistent(state, input.expectedHead, previous)) {\n throw new Error(\"Authored group policy successor is inconsistent\");\n }\n return verifiedPolicy({\n currentPolicy: input.currentPolicy,\n projection: input.request.projection,\n grants: input.request.grants,\n state: {\n ...state,\n stateHash: input.expectedHead.stateHash,\n createdAt: state.signedAt,\n },\n });\n}\n\nexport async function acknowledgeInitialGroupPolicy(input: {\n readonly organizationId: string;\n readonly request: CreateOrganizationGroupRequest;\n readonly response: OrganizationGroupSummaryResponse;\n readonly stateHash: string;\n}): Promise<{\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly policy: VerifiedPrincipalPolicy;\n}> {\n await assertPolicyRequestCommitments(input.request.initialGroupPolicy);\n const state = input.request.initialGroupPolicy.state;\n if (\n input.response.groupId !== input.request.groupId ||\n input.response.organizationId !== input.organizationId ||\n input.response.isBuiltin ||\n input.response.currentState?.stateHash !== input.stateHash ||\n input.response.currentState.version !== state.version ||\n input.response.currentState.keyEpoch !== state.keyEpoch ||\n input.response.currentState.keyFingerprint !== state.keyFingerprint ||\n input.response.currentState.memberCount !== state.memberCount ||\n state.principalType !== \"group\" ||\n state.principalId !== input.request.groupId ||\n state.version !== 1 ||\n state.prevStateHash !== null\n ) {\n throw new Error(\"Created group policy acknowledgement mismatch\");\n }\n const storedState = {\n ...state,\n createdAt: input.response.createdAt,\n stateHash: input.stateHash,\n };\n const bundle: PrincipalPolicyBundleResponse = {\n currentMemberEnvelopes: {\n envelopes: input.request.initialGroupPolicy.memberEnvelopes,\n epoch: state.keyEpoch,\n principalId: state.principalId,\n principalType: state.principalType,\n stateHash: input.stateHash,\n },\n currentPayload: {\n principalId: state.principalId,\n principalType: state.principalType,\n stateHash: input.stateHash,\n ...input.request.initialGroupPolicy.encryptedPayload,\n createdAt: input.response.createdAt,\n },\n currentProjection: input.request.initialGroupPolicy.projection,\n currentGrants: input.request.initialGroupPolicy.grants,\n currentState: storedState,\n previousStates: [],\n };\n return {\n bundle,\n policy: verifiedPolicy({\n projection: input.request.initialGroupPolicy.projection,\n grants: input.request.initialGroupPolicy.grants,\n state: storedState,\n }),\n };\n}\n"]}
1
+ {"version":3,"file":"groupPolicyMutationAcknowledgement.js","sourceRoot":"","sources":["groupPolicyMutationAcknowledgement.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computePrincipalContainerGrantRoot,\n computePrincipalMemberEnvelopesRoot,\n computePrincipalMembershipRoot,\n computePrincipalProjectionRoot,\n computePrincipalStatePayloadCiphertextHash,\n makeVerifiedPrincipalPolicy,\n normalizePrincipalProjectionMembers,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicy,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type {\n CreateOrganizationGroupRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationGroupSummaryResponse,\n PrincipalPolicyBundleResponse,\n PrincipalPolicyMutationResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../../data/keying/canonicalJson\";\nimport {\n type CurrentPolicyMutationInput,\n verifyCurrentPolicyMutation,\n} from \"./currentPolicyMutationAcknowledgement\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\nexport { assertGroupPolicyEnvelopesMatchAcknowledgement } from \"./principalPolicyReceiptArtifacts\";\n\nfunction historyWithCurrent(\n bundle: PrincipalPolicyBundleResponse,\n): PrincipalPolicyBundleResponse[\"previousStates\"] {\n return [\n ...bundle.previousStates,\n {\n state: bundle.currentState,\n projection: bundle.currentProjection,\n grants: bundle.currentGrants,\n },\n ];\n}\n\nfunction isAuthoredSuccessorConsistent(\n state: Pick<\n PrincipalStateResponse,\n | \"keyEpoch\"\n | \"keyFingerprint\"\n | \"prevStateHash\"\n | \"principalId\"\n | \"principalType\"\n | \"version\"\n >,\n expectedHead: ReferencedPrincipalHead,\n previous: PrincipalStateResponse,\n): boolean {\n return (\n state.principalType === expectedHead.principalType &&\n state.principalId === expectedHead.principalId &&\n state.version === expectedHead.version &&\n state.keyEpoch === expectedHead.keyEpoch &&\n state.keyFingerprint === expectedHead.keyFingerprint &&\n state.principalType === previous.principalType &&\n state.principalId === previous.principalId &&\n state.version === previous.version + 1 &&\n state.prevStateHash === previous.stateHash\n );\n}\n\nexport function buildAcknowledgedGroupPolicyBundle(input: {\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n}): PrincipalPolicyBundleResponse & PrincipalPolicyMutationResponse {\n assertPrincipalPolicyReceiptArtifacts(input);\n return {\n ...input.response,\n previousStates: historyWithCurrent(input.currentPolicy),\n };\n}\n\nasync function assertPolicyRequestCommitments(\n request: PutPrincipalPolicyRequest,\n): Promise<void> {\n const projection = normalizePrincipalProjectionMembers(request.projection);\n const members = projection.map((member) => ({ userId: member.userId }));\n const [\n membershipRoot,\n memberEnvelopesRoot,\n projectionRoot,\n payloadCiphertextHash,\n grantRoot,\n ] = await Promise.all([\n computePrincipalMembershipRoot(members),\n computePrincipalMemberEnvelopesRoot(request.memberEnvelopes),\n computePrincipalProjectionRoot(projection),\n computePrincipalStatePayloadCiphertextHash(\n request.encryptedPayload.ciphertext,\n ),\n computePrincipalContainerGrantRoot(request.grants),\n ]);\n if (\n request.state.membershipRoot !== membershipRoot ||\n request.state.memberEnvelopesRoot !== memberEnvelopesRoot ||\n request.state.projectionRoot !== projectionRoot ||\n request.state.memberCount !== projection.length ||\n request.state.grantRoot !== grantRoot ||\n request.state.grantCount !== request.grants.length ||\n request.encryptedPayload.ciphertextHash !== payloadCiphertextHash ||\n request.state.payloadCiphertextHash !== payloadCiphertextHash\n ) {\n throw new Error(\"Authored group policy commitments are invalid\");\n }\n}\n\nfunction verifiedPolicy(input: {\n currentPolicy?: PrincipalPolicyBundleResponse | undefined;\n projection: PutPrincipalPolicyRequest[\"projection\"];\n grants: PutPrincipalPolicyRequest[\"grants\"];\n state: PrincipalStateResponse;\n}): VerifiedPrincipalPolicy {\n const previousStates = input.currentPolicy\n ? historyWithCurrent(input.currentPolicy)\n : [];\n return makeVerifiedPrincipalPolicy({\n checkpoint: {\n principalId: input.state.principalId,\n principalType: input.state.principalType,\n stateHash: input.state.stateHash,\n version: input.state.version,\n },\n history: [\n ...previousStates,\n {\n state: input.state,\n projection: input.projection,\n grants: input.grants,\n },\n ],\n keyEpoch: input.state.keyEpoch,\n principalId: input.state.principalId,\n principalType: input.state.principalType,\n projection: input.projection,\n grants: input.grants,\n state: input.state,\n stateHash: input.state.stateHash,\n version: input.state.version,\n });\n}\n\ninterface FullPolicyMutationInput {\n readonly verifiedCurrentPolicy?: never;\n readonly currentPolicy: PrincipalPolicyBundleResponse;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly request: PutPrincipalPolicyRequest;\n}\n\nexport function acknowledgeGroupPolicyState(\n input: CurrentPolicyMutationInput & {\n readonly response: PrincipalStateResponse;\n },\n): Promise<VerifiedPrincipalPolicyCurrent>;\nexport function acknowledgeGroupPolicyState(\n input: FullPolicyMutationInput & {\n readonly response: PrincipalStateResponse;\n },\n): Promise<VerifiedPrincipalPolicy>;\nexport async function acknowledgeGroupPolicyState(\n input: (FullPolicyMutationInput | CurrentPolicyMutationInput) & {\n readonly response: PrincipalStateResponse;\n },\n): Promise<VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent> {\n if (input.verifiedCurrentPolicy !== undefined)\n return verifyCurrentPolicyMutation(input, input.response);\n await assertPolicyRequestCommitments(input.request);\n const { createdAt: _createdAt, stateHash, ...responseState } = input.response;\n const previous = input.currentPolicy.currentState;\n if (\n stateHash !== input.expectedHead.stateHash ||\n !isAuthoredSuccessorConsistent(\n input.response,\n input.expectedHead,\n previous,\n ) ||\n canonicalKeyingJsonString(responseState, \"stored group policy state\") !==\n canonicalKeyingJsonString(\n input.request.state,\n \"authored group policy state\",\n )\n ) {\n throw new Error(\"Group policy state acknowledgement mismatch\");\n }\n return verifiedPolicy({\n currentPolicy: input.currentPolicy,\n projection: input.request.projection,\n grants: input.request.grants,\n state: input.response,\n });\n}\n\n/**\n * Materialize the locally signed successor before submission so dependent\n * container mutations can wrap to the exact head that will commit with it.\n * The server still performs the authoritative signature, transition, and\n * authorization checks inside the combined transaction.\n */\nexport function prepareAuthoredGroupPolicy(\n input: CurrentPolicyMutationInput,\n): Promise<VerifiedPrincipalPolicyCurrent>;\nexport function prepareAuthoredGroupPolicy(\n input: FullPolicyMutationInput,\n): Promise<VerifiedPrincipalPolicy>;\nexport async function prepareAuthoredGroupPolicy(\n input: FullPolicyMutationInput | CurrentPolicyMutationInput,\n): Promise<VerifiedPrincipalPolicy | VerifiedPrincipalPolicyCurrent> {\n if (input.verifiedCurrentPolicy !== undefined)\n return verifyCurrentPolicyMutation(input);\n await assertPolicyRequestCommitments(input.request);\n const previous = input.currentPolicy.currentState;\n const state = input.request.state;\n if (!isAuthoredSuccessorConsistent(state, input.expectedHead, previous)) {\n throw new Error(\"Authored group policy successor is inconsistent\");\n }\n return verifiedPolicy({\n currentPolicy: input.currentPolicy,\n projection: input.request.projection,\n grants: input.request.grants,\n state: {\n ...state,\n stateHash: input.expectedHead.stateHash,\n createdAt: state.signedAt,\n },\n });\n}\n\nexport async function acknowledgeInitialGroupPolicy(input: {\n readonly organizationId: string;\n readonly request: CreateOrganizationGroupRequest;\n readonly response: OrganizationGroupSummaryResponse;\n readonly stateHash: string;\n}): Promise<{\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly policy: VerifiedPrincipalPolicy;\n}> {\n await assertPolicyRequestCommitments(input.request.initialGroupPolicy);\n const state = input.request.initialGroupPolicy.state;\n if (\n input.response.groupId !== input.request.groupId ||\n input.response.organizationId !== input.organizationId ||\n input.response.isBuiltin ||\n input.response.currentState?.stateHash !== input.stateHash ||\n input.response.currentState.version !== state.version ||\n input.response.currentState.keyEpoch !== state.keyEpoch ||\n input.response.currentState.keyFingerprint !== state.keyFingerprint ||\n input.response.currentState.memberCount !== state.memberCount ||\n state.principalType !== \"group\" ||\n state.principalId !== input.request.groupId ||\n state.version !== 1 ||\n state.prevStateHash !== null\n ) {\n throw new Error(\"Created group policy acknowledgement mismatch\");\n }\n const storedState = {\n ...state,\n createdAt: input.response.createdAt,\n stateHash: input.stateHash,\n };\n const bundle: PrincipalPolicyBundleResponse = {\n currentMemberEnvelopes: {\n envelopes: input.request.initialGroupPolicy.memberEnvelopes,\n epoch: state.keyEpoch,\n principalId: state.principalId,\n principalType: state.principalType,\n stateHash: input.stateHash,\n },\n currentPayload: {\n principalId: state.principalId,\n principalType: state.principalType,\n stateHash: input.stateHash,\n ...input.request.initialGroupPolicy.encryptedPayload,\n createdAt: input.response.createdAt,\n },\n currentProjection: input.request.initialGroupPolicy.projection,\n currentGrants: input.request.initialGroupPolicy.grants,\n currentState: storedState,\n previousStates: [],\n };\n return {\n bundle,\n policy: verifiedPolicy({\n projection: input.request.initialGroupPolicy.projection,\n grants: input.request.initialGroupPolicy.grants,\n state: storedState,\n }),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"groupPolicyRequests.js","sourceRoot":"","sources":["groupPolicyRequests.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n generateKemSeedAndKeyPair,\n KeyingVerificationError,\n type PrincipalPolicyExternalAuthority,\n toFingerprint,\n unwrapDek,\n wrapDekForRecipients,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n PrincipalContainerGrantRequest,\n PrincipalProjectionMemberRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport { principalSecretKeyMatchesState } from \"../../data/principals/principalKeyValidation\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { TrustedUserIdentity } from \"../../data/trustedUserIdentity\";\nimport { isDirectGroupAdmin } from \"./groupMutationAuthorization\";\nimport {\n type BuildGroupMembershipMutationInput,\n withVerifiedGroupMutation,\n} from \"./groupPolicyMutationEvidence\";\nimport {\n rewrapProjectionMemberEnvelopes,\n toRecipientEntries,\n} from \"./principalPolicyRecipients\";\nimport {\n signedGroupPolicyRequest,\n userProjectionMember,\n} from \"./principalPolicyRequest\";\n\ntype BuildAddGroupUserPolicyInput = BuildGroupMembershipMutationInput & {\n readonly currentUsers: ReadonlyArray<TrustedUserIdentity>;\n readonly currentUserSecretKey: Uint8Array;\n readonly reportSecurityIncident?: SecurityIncidentReporter | undefined;\n readonly targetUser: TrustedUserIdentity;\n};\n\n/**\n * The signed policy commits both the group's public key and the member\n * envelopes that are supposed to wrap its secret. An envelope that unwraps to\n * a different secret means a prior admin (or the server) published a policy\n * whose envelopes do not match its signed key. Rotating repairs the group, but\n * the mismatch is evidence and is recorded before the repair proceeds.\n */\nasync function reportPrincipalEnvelopeMismatch(\n input: BuildAddGroupUserPolicyInput,\n): Promise<void> {\n const state = input.currentPolicy.currentState;\n await input.reportSecurityIncident?.(\n new KeyingVerificationError(\n \"object_mismatch\",\n \"Group member envelope does not unwrap the signed principal key\",\n ),\n {\n evidenceHashes: {\n principalKeyFingerprint: state.keyFingerprint,\n principalStateHash: state.stateHash,\n },\n objectId: state.principalId,\n objectKind: \"principal\",\n operation: \"group.policy.envelope_mismatch\",\n },\n );\n}\n\nfunction hasAdmin(\n projection: ReadonlyArray<PrincipalProjectionMemberRequest>,\n): boolean {\n return projection.some((member) => member.role === \"admin\");\n}\n\nfunction requireExternalAuthority(\n authority: PrincipalPolicyExternalAuthority | undefined,\n): PrincipalPolicyExternalAuthority {\n if (!authority) {\n throw new Error(\"External principal authority could not be verified\");\n }\n return authority;\n}\n\nasync function buildRotatedKeyGroupPolicyRequest(\n input: BuildGroupMembershipMutationInput,\n projection: ReadonlyArray<PrincipalProjectionMemberRequest>,\n users: ReadonlyArray<TrustedUserIdentity>,\n grants = input.currentPolicy.currentGrants,\n): Promise<PutPrincipalPolicyRequest> {\n const groupKem = generateKemSeedAndKeyPair();\n const memberEnvelopes = await rewrapProjectionMemberEnvelopes({\n projection,\n secretKey: groupKem.secretKey,\n users,\n });\n return signedGroupPolicyRequest({\n currentPolicy: input.currentPolicy,\n encapsulationPublicKey: bytesToBase64(groupKem.publicKey),\n externalAuthority: isDirectGroupAdmin(\n input.currentPolicy,\n input.signerUserId,\n )\n ? null\n : requireExternalAuthority(input.externalAuthority).currentHead,\n keyEpoch: input.currentPolicy.currentState.keyEpoch + 1,\n keyFingerprint: await toFingerprint(groupKem.publicKey),\n grants,\n memberEnvelopes,\n payloadCiphertext: input.currentPolicy.currentPayload.ciphertext,\n principalId: input.currentPolicy.currentState.principalId,\n projection,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n}\n\nasync function buildDirectAdminAddGroupUserPolicyRequest(\n input: BuildAddGroupUserPolicyInput,\n projection: ReadonlyArray<PrincipalProjectionMemberRequest>,\n targetKey: string,\n): Promise<PutPrincipalPolicyRequest> {\n const groupSecretKey = await unwrapDek(\n toRecipientEntries(input.currentPolicy.currentMemberEnvelopes.envelopes),\n input.currentUserSecretKey,\n );\n if (\n !(await principalSecretKeyMatchesState(\n groupSecretKey,\n input.currentPolicy.currentState,\n ))\n ) {\n await reportPrincipalEnvelopeMismatch(input);\n return buildRotatedKeyGroupPolicyRequest(input, projection, [\n ...input.currentUsers,\n input.targetUser,\n ]);\n }\n const [targetEnvelope] = await wrapDekForRecipients(groupSecretKey, [\n input.targetUser.encapsulationPublicKey,\n ]);\n\n if (!targetEnvelope) {\n throw new Error(\"Failed to wrap group key for target user\");\n }\n\n const memberEnvelopes = [\n ...input.currentPolicy.currentMemberEnvelopes.envelopes.filter(\n (envelope) => envelope.userId !== targetKey,\n ),\n {\n userId: input.targetUser.userId,\n memberKeyFingerprint: input.targetUser.encapsulationKeyFingerprint,\n kemCipherText: bytesToBase64(targetEnvelope.kemCipherText),\n wrappedKey: bytesToBase64(targetEnvelope.wrappedKey),\n },\n ];\n return signedGroupPolicyRequest({\n currentPolicy: input.currentPolicy,\n encapsulationPublicKey:\n input.currentPolicy.currentState.encapsulationPublicKey,\n externalAuthority: null,\n keyEpoch: input.currentPolicy.currentState.keyEpoch,\n keyFingerprint: input.currentPolicy.currentState.keyFingerprint,\n grants: input.currentPolicy.currentGrants,\n memberEnvelopes,\n payloadCiphertext: input.currentPolicy.currentPayload.ciphertext,\n principalId: input.currentPolicy.currentState.principalId,\n projection,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n}\n\nexport async function buildAddGroupUserPolicyRequest(\n input: BuildAddGroupUserPolicyInput,\n): Promise<PutPrincipalPolicyRequest> {\n input = {\n ...input,\n currentUsers: structuredClone(input.currentUsers),\n currentUserSecretKey: input.currentUserSecretKey.slice(),\n targetUser: structuredClone(input.targetUser),\n };\n try {\n return await withVerifiedGroupMutation(input, async (input) => {\n const targetKey = input.targetUser.userId;\n const currentProjection = input.currentPolicy.currentProjection;\n if (currentProjection.some((member) => member.userId === targetKey)) {\n throw new Error(\"User is already a group member\");\n }\n\n const projection = [\n ...currentProjection,\n userProjectionMember(\n input.targetUser.userId,\n input.isOrganizationAdminsGroup ? \"admin\" : \"member\",\n ),\n ];\n\n return isDirectGroupAdmin(input.currentPolicy, input.signerUserId)\n ? buildDirectAdminAddGroupUserPolicyRequest(\n input,\n projection,\n targetKey,\n )\n : buildRotatedKeyGroupPolicyRequest(input, projection, [\n ...input.currentUsers,\n input.targetUser,\n ]);\n });\n } finally {\n input.currentUserSecretKey.fill(0);\n }\n}\n\nexport async function buildRemoveGroupUserPolicyRequest(\n input: BuildGroupMembershipMutationInput & {\n readonly remainingUsers: ReadonlyArray<TrustedUserIdentity>;\n readonly removedUserId: string;\n },\n): Promise<PutPrincipalPolicyRequest> {\n input = { ...input, remainingUsers: structuredClone(input.remainingUsers) };\n return withVerifiedGroupMutation(input, async (input) => {\n const key = input.removedUserId;\n const projection = input.currentPolicy.currentProjection.filter(\n (member) => member.userId !== key,\n );\n\n if (projection.length === input.currentPolicy.currentProjection.length) {\n throw new Error(\"User is not a group member\");\n }\n\n if (\n hasAdmin(input.currentPolicy.currentProjection) &&\n !hasAdmin(projection)\n ) {\n throw new Error(\"Cannot remove the last group admin\");\n }\n\n return buildRotatedKeyGroupPolicyRequest(\n input,\n projection,\n input.remainingUsers,\n );\n });\n}\n\nexport async function buildGroupAccessSetShrinkPolicyRequest(\n input: BuildGroupMembershipMutationInput & {\n readonly currentUsers: ReadonlyArray<TrustedUserIdentity>;\n readonly revokedContainerId: string;\n },\n): Promise<PutPrincipalPolicyRequest> {\n input = { ...input, currentUsers: structuredClone(input.currentUsers) };\n return withVerifiedGroupMutation(input, async (input) => {\n return buildRotatedKeyGroupPolicyRequest(\n input,\n [...input.currentPolicy.currentProjection],\n input.currentUsers,\n input.currentPolicy.currentGrants.filter(\n (grant) => grant.containerId !== input.revokedContainerId,\n ),\n );\n });\n}\n\n/** Signs a complete successor grant projection without rotating group key material. */\nexport async function buildSetGroupContainerGrantPolicyRequest(\n input: BuildGroupMembershipMutationInput & {\n readonly accessLevel: PrincipalContainerGrantRequest[\"accessLevel\"];\n readonly containerId: string;\n },\n): Promise<PutPrincipalPolicyRequest> {\n return withVerifiedGroupMutation(input, async (input) => {\n const grants = [\n ...input.currentPolicy.currentGrants.filter(\n (grant) => grant.containerId !== input.containerId,\n ),\n { accessLevel: input.accessLevel, containerId: input.containerId },\n ];\n return signedGroupPolicyRequest({\n currentPolicy: input.currentPolicy,\n encapsulationPublicKey:\n input.currentPolicy.currentState.encapsulationPublicKey,\n externalAuthority: isDirectGroupAdmin(\n input.currentPolicy,\n input.signerUserId,\n )\n ? null\n : requireExternalAuthority(input.externalAuthority).currentHead,\n keyEpoch: input.currentPolicy.currentState.keyEpoch,\n keyFingerprint: input.currentPolicy.currentState.keyFingerprint,\n grants,\n memberEnvelopes: input.currentPolicy.currentMemberEnvelopes.envelopes,\n payloadCiphertext: input.currentPolicy.currentPayload.ciphertext,\n principalId: input.currentPolicy.currentState.principalId,\n projection: input.currentPolicy.currentProjection,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n });\n}\n"]}
1
+ {"version":3,"file":"groupPolicyRequests.js","sourceRoot":"","sources":["groupPolicyRequests.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n generateKemSeedAndKeyPair,\n KeyingVerificationError,\n type PrincipalPolicyExternalAuthority,\n toFingerprint,\n unwrapDek,\n wrapDekForRecipients,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n PrincipalContainerGrantRequest,\n PrincipalProjectionMemberRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport { principalSecretKeyMatchesState } from \"../../data/principals/principalKeyValidation\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\nimport type { TrustedUserIdentity } from \"../../data/trustedUserIdentity\";\nimport { isDirectGroupAdmin } from \"./groupMutationAuthorization\";\nimport {\n type BuildGroupMembershipMutationInput,\n withVerifiedGroupMutation,\n} from \"./groupPolicyMutationEvidence\";\nimport {\n rewrapProjectionMemberEnvelopes,\n toRecipientEntries,\n} from \"./principalPolicyRecipients\";\nimport {\n signedGroupPolicyRequest,\n userProjectionMember,\n} from \"./principalPolicyRequest\";\n\ntype BuildAddGroupUserPolicyInput = BuildGroupMembershipMutationInput & {\n readonly currentUsers: ReadonlyArray<TrustedUserIdentity>;\n readonly currentUserSecretKey: Uint8Array;\n readonly reportSecurityIncident?: SecurityIncidentReporter | undefined;\n readonly targetUser: TrustedUserIdentity;\n};\n\n/**\n * The signed policy commits both the group's public key and the member\n * envelopes that are supposed to wrap its secret. An envelope that unwraps to\n * a different secret means a prior admin (or the server) published a policy\n * whose envelopes do not match its signed key. Rotating repairs the group, but\n * the mismatch is evidence and is recorded before the repair proceeds.\n */\nasync function reportPrincipalEnvelopeMismatch(\n input: BuildAddGroupUserPolicyInput,\n): Promise<void> {\n const state = input.currentPolicy.currentState;\n await input.reportSecurityIncident?.(\n new KeyingVerificationError(\n \"object_mismatch\",\n \"Group member envelope does not unwrap the signed principal key\",\n ),\n {\n evidenceHashes: {\n principalKeyFingerprint: state.keyFingerprint,\n principalStateHash: state.stateHash,\n },\n objectId: state.principalId,\n objectKind: \"principal\",\n operation: \"group.policy.envelope_mismatch\",\n },\n );\n}\n\nfunction hasAdmin(\n projection: ReadonlyArray<PrincipalProjectionMemberRequest>,\n): boolean {\n return projection.some((member) => member.role === \"admin\");\n}\n\nfunction requireExternalAuthority(\n authority: PrincipalPolicyExternalAuthority | undefined,\n): PrincipalPolicyExternalAuthority {\n if (!authority) {\n throw new Error(\"External principal authority could not be verified\");\n }\n return authority;\n}\n\nasync function buildRotatedKeyGroupPolicyRequest(\n input: BuildGroupMembershipMutationInput,\n projection: ReadonlyArray<PrincipalProjectionMemberRequest>,\n users: ReadonlyArray<TrustedUserIdentity>,\n grants = input.currentPolicy.currentGrants,\n): Promise<PutPrincipalPolicyRequest> {\n const groupKem = generateKemSeedAndKeyPair();\n const memberEnvelopes = await rewrapProjectionMemberEnvelopes({\n projection,\n secretKey: groupKem.secretKey,\n users,\n });\n return signedGroupPolicyRequest({\n currentPolicy: input.currentPolicy,\n encapsulationPublicKey: bytesToBase64(groupKem.publicKey),\n externalAuthority: isDirectGroupAdmin(\n input.currentPolicy,\n input.signerUserId,\n )\n ? null\n : requireExternalAuthority(input.externalAuthority).currentHead,\n keyEpoch: input.currentPolicy.currentState.keyEpoch + 1,\n keyFingerprint: await toFingerprint(groupKem.publicKey),\n grants,\n memberEnvelopes,\n payloadCiphertext: input.currentPolicy.currentPayload.ciphertext,\n principalId: input.currentPolicy.currentState.principalId,\n projection,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n}\n\nasync function buildDirectAdminAddGroupUserPolicyRequest(\n input: BuildAddGroupUserPolicyInput,\n projection: ReadonlyArray<PrincipalProjectionMemberRequest>,\n targetKey: string,\n): Promise<PutPrincipalPolicyRequest> {\n const groupSecretKey = await unwrapDek(\n toRecipientEntries(input.currentPolicy.currentMemberEnvelopes.envelopes),\n input.currentUserSecretKey,\n );\n if (\n !(await principalSecretKeyMatchesState(\n groupSecretKey,\n input.currentPolicy.currentState,\n ))\n ) {\n await reportPrincipalEnvelopeMismatch(input);\n return buildRotatedKeyGroupPolicyRequest(input, projection, [\n ...input.currentUsers,\n input.targetUser,\n ]);\n }\n const [targetEnvelope] = await wrapDekForRecipients(groupSecretKey, [\n input.targetUser.encapsulationPublicKey,\n ]);\n\n if (!targetEnvelope) {\n throw new Error(\"Failed to wrap group key for target user\");\n }\n\n const memberEnvelopes = [\n ...input.currentPolicy.currentMemberEnvelopes.envelopes.filter(\n (envelope) => envelope.userId !== targetKey,\n ),\n {\n userId: input.targetUser.userId,\n memberKeyFingerprint: input.targetUser.encapsulationKeyFingerprint,\n kemCipherText: bytesToBase64(targetEnvelope.kemCipherText),\n wrappedKey: bytesToBase64(targetEnvelope.wrappedKey),\n },\n ];\n return signedGroupPolicyRequest({\n currentPolicy: input.currentPolicy,\n encapsulationPublicKey:\n input.currentPolicy.currentState.encapsulationPublicKey,\n externalAuthority: null,\n keyEpoch: input.currentPolicy.currentState.keyEpoch,\n keyFingerprint: input.currentPolicy.currentState.keyFingerprint,\n grants: input.currentPolicy.currentGrants,\n memberEnvelopes,\n payloadCiphertext: input.currentPolicy.currentPayload.ciphertext,\n principalId: input.currentPolicy.currentState.principalId,\n projection,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n}\n\nexport async function buildAddGroupUserPolicyRequest(\n input: BuildAddGroupUserPolicyInput,\n): Promise<PutPrincipalPolicyRequest> {\n input = {\n ...input,\n currentUsers: structuredClone(input.currentUsers),\n currentUserSecretKey: input.currentUserSecretKey.slice(),\n targetUser: structuredClone(input.targetUser),\n };\n try {\n return await withVerifiedGroupMutation(input, async (input) => {\n const targetKey = input.targetUser.userId;\n const currentProjection = input.currentPolicy.currentProjection;\n if (currentProjection.some((member) => member.userId === targetKey)) {\n throw new Error(\"User is already a group member\");\n }\n\n const projection = [\n ...currentProjection,\n userProjectionMember(\n input.targetUser.userId,\n input.isOrganizationAdminsGroup ? \"admin\" : \"member\",\n ),\n ];\n\n return isDirectGroupAdmin(input.currentPolicy, input.signerUserId)\n ? buildDirectAdminAddGroupUserPolicyRequest(\n input,\n projection,\n targetKey,\n )\n : buildRotatedKeyGroupPolicyRequest(input, projection, [\n ...input.currentUsers,\n input.targetUser,\n ]);\n });\n } finally {\n input.currentUserSecretKey.fill(0);\n }\n}\n\nexport async function buildRemoveGroupUserPolicyRequest(\n input: BuildGroupMembershipMutationInput & {\n readonly remainingUsers: ReadonlyArray<TrustedUserIdentity>;\n readonly removedUserId: string;\n },\n): Promise<PutPrincipalPolicyRequest> {\n input = { ...input, remainingUsers: structuredClone(input.remainingUsers) };\n return withVerifiedGroupMutation(input, async (input) => {\n const key = input.removedUserId;\n const projection = input.currentPolicy.currentProjection.filter(\n (member) => member.userId !== key,\n );\n\n if (projection.length === input.currentPolicy.currentProjection.length) {\n throw new Error(\"User is not a group member\");\n }\n\n if (\n hasAdmin(input.currentPolicy.currentProjection) &&\n !hasAdmin(projection)\n ) {\n throw new Error(\"Cannot remove the last group admin\");\n }\n\n return buildRotatedKeyGroupPolicyRequest(\n input,\n projection,\n input.remainingUsers,\n );\n });\n}\n\nexport async function buildGroupAccessSetShrinkPolicyRequest(\n input: BuildGroupMembershipMutationInput & {\n readonly currentUsers: ReadonlyArray<TrustedUserIdentity>;\n readonly revokedContainerId: string;\n },\n): Promise<PutPrincipalPolicyRequest> {\n input = { ...input, currentUsers: structuredClone(input.currentUsers) };\n return withVerifiedGroupMutation(input, async (input) => {\n return buildRotatedKeyGroupPolicyRequest(\n input,\n [...input.currentPolicy.currentProjection],\n input.currentUsers,\n input.currentPolicy.currentGrants.filter(\n (grant) => grant.containerId !== input.revokedContainerId,\n ),\n );\n });\n}\n\n/** Signs a complete successor grant projection without rotating group key material. */\nexport async function buildSetGroupContainerGrantPolicyRequest(\n input: BuildGroupMembershipMutationInput & {\n readonly accessLevel: PrincipalContainerGrantRequest[\"accessLevel\"];\n readonly containerId: string;\n },\n): Promise<PutPrincipalPolicyRequest> {\n return withVerifiedGroupMutation(input, async (input) => {\n const grants = [\n ...input.currentPolicy.currentGrants.filter(\n (grant) => grant.containerId !== input.containerId,\n ),\n { accessLevel: input.accessLevel, containerId: input.containerId },\n ];\n return signedGroupPolicyRequest({\n currentPolicy: input.currentPolicy,\n encapsulationPublicKey:\n input.currentPolicy.currentState.encapsulationPublicKey,\n externalAuthority: isDirectGroupAdmin(\n input.currentPolicy,\n input.signerUserId,\n )\n ? null\n : requireExternalAuthority(input.externalAuthority).currentHead,\n keyEpoch: input.currentPolicy.currentState.keyEpoch,\n keyFingerprint: input.currentPolicy.currentState.keyFingerprint,\n grants,\n memberEnvelopes: input.currentPolicy.currentMemberEnvelopes.envelopes,\n payloadCiphertext: input.currentPolicy.currentPayload.ciphertext,\n principalId: input.currentPolicy.currentState.principalId,\n projection: input.currentPolicy.currentProjection,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"loadPolicyHistoryDetails.js","sourceRoot":"","sources":["loadPolicyHistoryDetails.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { ReferencedPrincipalHead } from \"@tearleads/crypto\";\nimport type { DomainScope } from \"../../data/domainScope\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { reportKeyingVerificationErrorInCauseChain } from \"../../data/keyingProjectionVerification/error\";\nimport type { ReferencedPrincipalPolicyWarmer } from \"../../data/keyingProjectionVerification/types\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { RecoveredPrincipalHistoryPage } from \"../principals/loadRecoveredPrincipalHistoryPage\";\nimport { loadLocalOrganizationPolicyReference } from \"./localReadModelDetails\";\nimport { buildDetailedOrganizationPolicyHistory } from \"./organizationPolicyHistoryDetails\";\nimport {\n captureOrganizationPresentationAccessAttempt,\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n} from \"./organizationPresentationAccessState\";\nimport { isOrganizationPresentationAccessDeniedFailure } from \"./organizationPresentationFailures\";\nimport { denyPolicyHistoryAccess } from \"./policyHistoryAccessDenial\";\nimport {\n cachePolicyHistory,\n loadCachedPolicyHistory,\n} from \"./policyHistoryCache\";\nimport type { OrganizationPolicyHistory } from \"./policyHistoryTypes\";\n\nexport async function loadPolicyHistoryDetails(input: {\n apiClient: Pick<ApiClient, \"getOrganizationPolicyHistoryResult\">;\n currentUserId: string;\n domainScope: DomainScope;\n execSql: ExecSql;\n organizationId: string;\n head: ReferencedPrincipalHead;\n page: RecoveredPrincipalHistoryPage;\n history: OrganizationPolicyHistory;\n resolveHistory: NonNullable<\n ReferencedPrincipalPolicyWarmer[\"resolveProjectionHistory\"]\n >;\n stillCurrent: () => boolean;\n online: boolean;\n olderPage: boolean;\n reportSecurityIncident?: SecurityIncidentReporter | undefined;\n // Forwarded to denyPolicyHistoryAccess to report failed durable cleanup.\n logError: (message: string | Error, cause?: unknown) => void;\n}): Promise<OrganizationPolicyHistory | null> {\n const access = { ...input, requesterUserId: input.currentUserId };\n const attempt = captureOrganizationPresentationAccessAttempt(\n access,\n \"readModel\",\n );\n const current = () =>\n input.stillCurrent() &&\n isOrganizationPresentationAccessAttemptCurrent(access, attempt) &&\n isOrganizationPresentationAccessReadable(access, \"readModel\");\n if (!current()) return null;\n const beforeVersion = (input.page.entries.at(-1)?.state.version ?? 0) + 1;\n const cache = {\n domainScope: input.domainScope,\n access,\n stateHash: input.head.stateHash,\n beforeVersion,\n };\n const retain = async (history: OrganizationPolicyHistory) => {\n const latest = await loadLocalOrganizationPolicyReference({\n ...input,\n principalType: \"organization\",\n principalId: input.organizationId,\n });\n return current() && latest?.stateHash === input.head.stateHash\n ? history\n : null;\n };\n const cached = loadCachedPolicyHistory(cache);\n if (cached) return retain(cached);\n if (!input.online) return retain(input.history);\n try {\n const response = await input.apiClient.getOrganizationPolicyHistoryResult(\n input.organizationId,\n input.head.stateHash,\n { beforeVersion, reportErrors: false },\n );\n if (!input.stillCurrent()) return null;\n if (!response.ok) {\n if (isOrganizationPresentationAccessDeniedFailure(response)) {\n await denyPolicyHistoryAccess(access);\n return null;\n }\n response.report();\n if (input.olderPage) throw new Error(response.message);\n return retain(input.history);\n }\n const history = await buildDetailedOrganizationPolicyHistory({\n head: input.head,\n page: input.page,\n evidence: response.data,\n resolveHistory: input.resolveHistory,\n stillCurrent: current,\n });\n const retained = await retain(history);\n if (retained === history)\n cachePolicyHistory({ ...cache, attempt, history });\n return retained;\n } catch (error) {\n if (\n !input.olderPage &&\n error instanceof ProjectionDependencyUnavailableError\n )\n return retain(input.history);\n await reportKeyingVerificationErrorInCauseChain(\n error,\n input.reportSecurityIncident,\n {\n objectId: input.organizationId,\n objectKind: \"principal\",\n operation: \"organization.policy_history.load\",\n organizationId: input.organizationId,\n },\n );\n throw error;\n }\n}\n"]}
1
+ {"version":3,"file":"loadPolicyHistoryDetails.js","sourceRoot":"","sources":["loadPolicyHistoryDetails.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { ReferencedPrincipalHead } from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { reportKeyingVerificationErrorInCauseChain } from \"../../data/keyingProjectionVerification/error\";\nimport type { ReferencedPrincipalPolicyWarmer } from \"../../data/keyingProjectionVerification/types\";\nimport type { DomainScope } from \"../../data/shared/domainScope\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { RecoveredPrincipalHistoryPage } from \"../principals/loadRecoveredPrincipalHistoryPage\";\nimport { loadLocalOrganizationPolicyReference } from \"./localReadModelDetails\";\nimport { buildDetailedOrganizationPolicyHistory } from \"./organizationPolicyHistoryDetails\";\nimport {\n captureOrganizationPresentationAccessAttempt,\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n} from \"./organizationPresentationAccessState\";\nimport { isOrganizationPresentationAccessDeniedFailure } from \"./organizationPresentationFailures\";\nimport { denyPolicyHistoryAccess } from \"./policyHistoryAccessDenial\";\nimport {\n cachePolicyHistory,\n loadCachedPolicyHistory,\n} from \"./policyHistoryCache\";\nimport type { OrganizationPolicyHistory } from \"./policyHistoryTypes\";\n\nexport async function loadPolicyHistoryDetails(input: {\n apiClient: Pick<ApiClient, \"getOrganizationPolicyHistoryResult\">;\n currentUserId: string;\n domainScope: DomainScope;\n execSql: ExecSql;\n organizationId: string;\n head: ReferencedPrincipalHead;\n page: RecoveredPrincipalHistoryPage;\n history: OrganizationPolicyHistory;\n resolveHistory: NonNullable<\n ReferencedPrincipalPolicyWarmer[\"resolveProjectionHistory\"]\n >;\n stillCurrent: () => boolean;\n online: boolean;\n olderPage: boolean;\n reportSecurityIncident?: SecurityIncidentReporter | undefined;\n // Forwarded to denyPolicyHistoryAccess to report failed durable cleanup.\n logError: (message: string | Error, cause?: unknown) => void;\n}): Promise<OrganizationPolicyHistory | null> {\n const access = { ...input, requesterUserId: input.currentUserId };\n const attempt = captureOrganizationPresentationAccessAttempt(\n access,\n \"readModel\",\n );\n const current = () =>\n input.stillCurrent() &&\n isOrganizationPresentationAccessAttemptCurrent(access, attempt) &&\n isOrganizationPresentationAccessReadable(access, \"readModel\");\n if (!current()) return null;\n const beforeVersion = (input.page.entries.at(-1)?.state.version ?? 0) + 1;\n const cache = {\n domainScope: input.domainScope,\n access,\n stateHash: input.head.stateHash,\n beforeVersion,\n };\n const retain = async (history: OrganizationPolicyHistory) => {\n const latest = await loadLocalOrganizationPolicyReference({\n ...input,\n principalType: \"organization\",\n principalId: input.organizationId,\n });\n return current() && latest?.stateHash === input.head.stateHash\n ? history\n : null;\n };\n const cached = loadCachedPolicyHistory(cache);\n if (cached) return retain(cached);\n if (!input.online) return retain(input.history);\n try {\n const response = await input.apiClient.getOrganizationPolicyHistoryResult(\n input.organizationId,\n input.head.stateHash,\n { beforeVersion, reportErrors: false },\n );\n if (!input.stillCurrent()) return null;\n if (!response.ok) {\n if (isOrganizationPresentationAccessDeniedFailure(response)) {\n await denyPolicyHistoryAccess(access);\n return null;\n }\n response.report();\n if (input.olderPage) throw new Error(response.message);\n return retain(input.history);\n }\n const history = await buildDetailedOrganizationPolicyHistory({\n head: input.head,\n page: input.page,\n evidence: response.data,\n resolveHistory: input.resolveHistory,\n stillCurrent: current,\n });\n const retained = await retain(history);\n if (retained === history)\n cachePolicyHistory({ ...cache, attempt, history });\n return retained;\n } catch (error) {\n if (\n !input.olderPage &&\n error instanceof ProjectionDependencyUnavailableError\n )\n return retain(input.history);\n await reportKeyingVerificationErrorInCauseChain(\n error,\n input.reportSecurityIncident,\n {\n objectId: input.organizationId,\n objectKind: \"principal\",\n operation: \"organization.policy_history.load\",\n organizationId: input.organizationId,\n },\n );\n throw error;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"organizationGroupDirectory.js","sourceRoot":"","sources":["organizationGroupDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildPrincipalStateSigningInput,\n generateKemSeedAndKeyPair,\n normalizePrincipalProjectionMembers,\n type ReferencedPrincipalHead,\n type SigningKeyPair,\n signPrincipalState,\n toFingerprint,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n PrincipalProjectionMemberRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationGroupSummaryResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { persistLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport {\n encodeOrganizationAuthorityDescriptor,\n normalizeOrganizationGroupHeads,\n type OrganizationAuthorityDescriptor,\n type OrganizationGroupHead,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type {\n TrustedUserIdentity,\n TrustedUserIdentityResolver,\n} from \"../../data/trustedUserIdentity\";\nimport type { loadOrganizationExternalAdminPolicy } from \"../principals/externalAdminPolicy\";\nimport { assertGroupNameUniqueInDirectory } from \"./groupNameUniqueness\";\nimport {\n acknowledgeGroupPolicyState,\n acknowledgeInitialGroupPolicy,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { OrganizationPrincipalPolicyApi } from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { rewrapProjectionMemberEnvelopes } from \"./principalPolicyRecipients\";\nimport type {\n buildInitialGroupPolicyRequest,\n GroupPolicyNameReader,\n} from \"./principalPolicyRequest\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"./trustedOrganizationUsers\";\n\nfunction organizationGroupHead(\n head: ReferencedPrincipalHead,\n): OrganizationGroupHead {\n if (head.principalType !== \"group\") {\n throw new Error(\"Organization directory can contain only group heads\");\n }\n return { ...head, principalType: \"group\" };\n}\n\nexport function replaceOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly nextHead: ReferencedPrincipalHead;\n}): OrganizationGroupHead[] {\n const nextHead = organizationGroupHead(input.nextHead);\n return normalizeOrganizationGroupHeads([\n ...input.descriptor.groupHeads.filter(\n (head) => head.principalId !== nextHead.principalId,\n ),\n nextHead,\n ]);\n}\n\nexport function removeOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupId: string;\n}): OrganizationGroupHead[] {\n if (\n input.groupId === input.descriptor.adminGroupId ||\n input.groupId === input.descriptor.memberGroupId\n ) {\n throw new Error(\"Built-in groups cannot be removed from the directory\");\n }\n const groupHeads = input.descriptor.groupHeads.filter(\n (head) => head.principalId !== input.groupId,\n );\n if (groupHeads.length === input.descriptor.groupHeads.length) {\n throw new Error(\"Organization directory does not commit the deleted group\");\n }\n return normalizeOrganizationGroupHeads(groupHeads);\n}\n\nexport async function buildOrganizationGroupDirectoryPolicyRequest(input: {\n readonly adminProjection: readonly PrincipalProjectionMemberRequest[];\n readonly adminUsers: readonly TrustedUserIdentity[];\n readonly currentPolicy: Pick<PrincipalPolicyBundleResponse, \"currentState\">;\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupHeads: readonly OrganizationGroupHead[];\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<PutPrincipalPolicyRequest> {\n const projection = normalizePrincipalProjectionMembers(input.adminProjection);\n if (\n projection.length === 0 ||\n projection.some((member) => member.role !== \"admin\")\n ) {\n throw new Error(\"Organization policy must mirror the Admins projection\");\n }\n const organizationKem = generateKemSeedAndKeyPair();\n const memberEnvelopes = await rewrapProjectionMemberEnvelopes({\n projection,\n secretKey: organizationKem.secretKey,\n users: input.adminUsers,\n });\n const payloadCiphertext = encodeOrganizationAuthorityDescriptor({\n ...input.descriptor,\n groupHeads: input.groupHeads,\n });\n const state = await signPrincipalState(\n await buildPrincipalStateSigningInput({\n principalType: \"organization\",\n principalId: input.descriptor.organizationId,\n version: input.currentPolicy.currentState.version + 1,\n prevStateHash: input.currentPolicy.currentState.stateHash,\n keyEpoch: input.currentPolicy.currentState.keyEpoch + 1,\n encapsulationPublicKey: bytesToBase64(organizationKem.publicKey),\n keyFingerprint: await toFingerprint(organizationKem.publicKey),\n members: projection.map((member) => ({ userId: member.userId })),\n memberEnvelopes,\n projection,\n grants: [],\n payloadCiphertext,\n externalAuthority: null,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signerUserKeyFingerprint: input.signingFingerprint,\n }),\n input.signingKeyPair.signingPrivateKey,\n );\n\n return {\n encryptedPayload: {\n cipherSuite: \"aes-256-gcm\",\n ciphertext: payloadCiphertext,\n ciphertextHash: state.payloadCiphertextHash,\n },\n grants: [],\n memberEnvelopes,\n projection,\n state,\n };\n}\n\nexport async function commitCreatedGroupToDirectory(input: {\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly name: string;\n readonly readEncryptedName?: GroupPolicyNameReader;\n readonly apiClient: OrganizationPrincipalPolicyApi;\n readonly execSql: ExecSql;\n readonly externalAdminPolicy: NonNullable<\n Awaited<ReturnType<typeof loadOrganizationExternalAdminPolicy>>\n >;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly request: Awaited<ReturnType<typeof buildInitialGroupPolicyRequest>>;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<{\n readonly group: OrganizationGroupSummaryResponse;\n readonly head: ReferencedPrincipalHead;\n}> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n // Signed group names are unique per organization; refuse a collision before\n // anything reaches the server.\n await assertGroupNameUniqueInDirectory({\n apiClient: input.apiClient,\n descriptor: input.externalAdminPolicy.descriptor,\n execSql: input.execSql,\n externalAuthority: input.externalAdminPolicy.externalAuthority,\n name: input.name,\n readEncryptedName: input.readEncryptedName,\n organizationId: input.organizationId,\n reportSecurityIncident: input.reportSecurityIncident,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const expectedHead = await groupPolicyMutationHead(\n input.request.initialGroupPolicy,\n );\n const adminProjection =\n input.externalAdminPolicy.adminBundle.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n const organizationRequest =\n await buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: input.externalAdminPolicy.bundle,\n descriptor: input.externalAdminPolicy.descriptor,\n groupHeads: [\n ...input.externalAdminPolicy.descriptor.groupHeads,\n organizationGroupHead(expectedHead),\n ],\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n const stored = await input.apiClient.createOrganizationGroup(\n input.organizationId,\n { ...input.request, organizationPolicy: organizationRequest },\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!stored) {\n throw new Error(\"Group could not be created\");\n }\n const acknowledged = await acknowledgeInitialGroupPolicy({\n organizationId: input.organizationId,\n request: input.request,\n response: stored.group,\n stateHash: expectedHead.stateHash,\n });\n const organizationHead = await groupPolicyMutationHead(organizationRequest);\n const organizationPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy,\n });\n await persistLocallyAcknowledgedPrincipalPolicyBundles({\n entries: [\n { bundle: acknowledged.bundle, policy: acknowledged.policy },\n { bundle: organizationBundle, policy: organizationPolicy },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { group: stored.group, head: expectedHead };\n}\n"]}
1
+ {"version":3,"file":"organizationGroupDirectory.js","sourceRoot":"","sources":["organizationGroupDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n buildPrincipalStateSigningInput,\n generateKemSeedAndKeyPair,\n normalizePrincipalProjectionMembers,\n type ReferencedPrincipalHead,\n type SigningKeyPair,\n signPrincipalState,\n toFingerprint,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type {\n PrincipalProjectionMemberRequest,\n PutPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n OrganizationGroupSummaryResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { persistLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport {\n encodeOrganizationAuthorityDescriptor,\n normalizeOrganizationGroupHeads,\n type OrganizationAuthorityDescriptor,\n type OrganizationGroupHead,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type {\n TrustedUserIdentity,\n TrustedUserIdentityResolver,\n} from \"../../data/trustedUserIdentity\";\nimport type { loadOrganizationExternalAdminPolicy } from \"../principals/externalAdminPolicy\";\nimport { assertGroupNameUniqueInDirectory } from \"./groupNameUniqueness\";\nimport {\n acknowledgeGroupPolicyState,\n acknowledgeInitialGroupPolicy,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { OrganizationPrincipalPolicyApi } from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { rewrapProjectionMemberEnvelopes } from \"./principalPolicyRecipients\";\nimport type {\n buildInitialGroupPolicyRequest,\n GroupPolicyNameReader,\n} from \"./principalPolicyRequest\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"./trustedOrganizationUsers\";\n\nfunction organizationGroupHead(\n head: ReferencedPrincipalHead,\n): OrganizationGroupHead {\n if (head.principalType !== \"group\") {\n throw new Error(\"Organization directory can contain only group heads\");\n }\n return { ...head, principalType: \"group\" };\n}\n\nexport function replaceOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly nextHead: ReferencedPrincipalHead;\n}): OrganizationGroupHead[] {\n const nextHead = organizationGroupHead(input.nextHead);\n return normalizeOrganizationGroupHeads([\n ...input.descriptor.groupHeads.filter(\n (head) => head.principalId !== nextHead.principalId,\n ),\n nextHead,\n ]);\n}\n\nexport function removeOrganizationGroupHead(input: {\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupId: string;\n}): OrganizationGroupHead[] {\n if (\n input.groupId === input.descriptor.adminGroupId ||\n input.groupId === input.descriptor.memberGroupId\n ) {\n throw new Error(\"Built-in groups cannot be removed from the directory\");\n }\n const groupHeads = input.descriptor.groupHeads.filter(\n (head) => head.principalId !== input.groupId,\n );\n if (groupHeads.length === input.descriptor.groupHeads.length) {\n throw new Error(\"Organization directory does not commit the deleted group\");\n }\n return normalizeOrganizationGroupHeads(groupHeads);\n}\n\nexport async function buildOrganizationGroupDirectoryPolicyRequest(input: {\n readonly adminProjection: readonly PrincipalProjectionMemberRequest[];\n readonly adminUsers: readonly TrustedUserIdentity[];\n readonly currentPolicy: Pick<PrincipalPolicyBundleResponse, \"currentState\">;\n readonly descriptor: OrganizationAuthorityDescriptor;\n readonly groupHeads: readonly OrganizationGroupHead[];\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<PutPrincipalPolicyRequest> {\n const projection = normalizePrincipalProjectionMembers(input.adminProjection);\n if (\n projection.length === 0 ||\n projection.some((member) => member.role !== \"admin\")\n ) {\n throw new Error(\"Organization policy must mirror the Admins projection\");\n }\n const organizationKem = generateKemSeedAndKeyPair();\n const memberEnvelopes = await rewrapProjectionMemberEnvelopes({\n projection,\n secretKey: organizationKem.secretKey,\n users: input.adminUsers,\n });\n const payloadCiphertext = encodeOrganizationAuthorityDescriptor({\n ...input.descriptor,\n groupHeads: input.groupHeads,\n });\n const state = await signPrincipalState(\n await buildPrincipalStateSigningInput({\n principalType: \"organization\",\n principalId: input.descriptor.organizationId,\n version: input.currentPolicy.currentState.version + 1,\n prevStateHash: input.currentPolicy.currentState.stateHash,\n keyEpoch: input.currentPolicy.currentState.keyEpoch + 1,\n encapsulationPublicKey: bytesToBase64(organizationKem.publicKey),\n keyFingerprint: await toFingerprint(organizationKem.publicKey),\n members: projection.map((member) => ({ userId: member.userId })),\n memberEnvelopes,\n projection,\n grants: [],\n payloadCiphertext,\n externalAuthority: null,\n signedAt: new Date().toISOString(),\n signerUserId: input.signerUserId,\n signerUserKeyFingerprint: input.signingFingerprint,\n }),\n input.signingKeyPair.signingPrivateKey,\n );\n\n return {\n encryptedPayload: {\n cipherSuite: \"aes-256-gcm\",\n ciphertext: payloadCiphertext,\n ciphertextHash: state.payloadCiphertextHash,\n },\n grants: [],\n memberEnvelopes,\n projection,\n state,\n };\n}\n\nexport async function commitCreatedGroupToDirectory(input: {\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly name: string;\n readonly readEncryptedName?: GroupPolicyNameReader;\n readonly apiClient: OrganizationPrincipalPolicyApi;\n readonly execSql: ExecSql;\n readonly externalAdminPolicy: NonNullable<\n Awaited<ReturnType<typeof loadOrganizationExternalAdminPolicy>>\n >;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly request: Awaited<ReturnType<typeof buildInitialGroupPolicyRequest>>;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n}): Promise<{\n readonly group: OrganizationGroupSummaryResponse;\n readonly head: ReferencedPrincipalHead;\n}> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n // Signed group names are unique per organization; refuse a collision before\n // anything reaches the server.\n await assertGroupNameUniqueInDirectory({\n apiClient: input.apiClient,\n descriptor: input.externalAdminPolicy.descriptor,\n execSql: input.execSql,\n externalAuthority: input.externalAdminPolicy.externalAuthority,\n name: input.name,\n readEncryptedName: input.readEncryptedName,\n organizationId: input.organizationId,\n reportSecurityIncident: input.reportSecurityIncident,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n const expectedHead = await groupPolicyMutationHead(\n input.request.initialGroupPolicy,\n );\n const adminProjection =\n input.externalAdminPolicy.adminBundle.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n const organizationRequest =\n await buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: input.externalAdminPolicy.bundle,\n descriptor: input.externalAdminPolicy.descriptor,\n groupHeads: [\n ...input.externalAdminPolicy.descriptor.groupHeads,\n organizationGroupHead(expectedHead),\n ],\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n const stored = await input.apiClient.createOrganizationGroup(\n input.organizationId,\n { ...input.request, organizationPolicy: organizationRequest },\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!stored) {\n throw new Error(\"Group could not be created\");\n }\n const acknowledged = await acknowledgeInitialGroupPolicy({\n organizationId: input.organizationId,\n request: input.request,\n response: stored.group,\n stateHash: expectedHead.stateHash,\n });\n const organizationHead = await groupPolicyMutationHead(organizationRequest);\n const organizationPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: input.externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy,\n });\n await persistLocallyAcknowledgedPrincipalPolicyBundles({\n entries: [\n { bundle: acknowledged.bundle, policy: acknowledged.policy },\n { bundle: organizationBundle, policy: organizationPolicy },\n ],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { group: stored.group, head: expectedHead };\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  import { bytesToBase64 } from "../../internal/encoding/index.js";
2
2
  import { createDocument, exportAllUpdates } from "../../internal/loro/index.js";
3
- import { getScopedPeerSeed } from "../../data/crdtPeerSeed.js";
4
3
  import { ORGANIZATION_PROFILE_DOCUMENT_KIND } from "../../data/documents/documentConstants.js";
5
4
  import { initializeStoredDocumentKind, writeStoredDocumentFields, } from "../../data/documents/documentKinds.js";
6
5
  import { DOCUMENTS_APP_KIND } from "../../data/persistence/documents/documentsPersistence.js";
6
+ import { getScopedPeerSeed } from "../../data/sync/crdtPeerSeed.js";
7
7
  export { ORGANIZATION_PROFILE_DOCUMENT_KIND };
8
8
  export const DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME = "Personal Org";
9
9
  export function getOrganizationProfileDocumentLocalId(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"organizationProfile.js","sourceRoot":"","sources":["organizationProfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kCAAkC,EAAE,MAAM,wCAAwC,CAAC;AAC5F,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uDAAuD,CAAC;AAE3F,OAAO,EAAE,kCAAkC,EAAE,CAAC;AAC9C,MAAM,CAAC,MAAM,0CAA0C,GAAG,cAAc,CAAC;AAEzE,MAAM,UAAU,qCAAqC,CAAC,KAErD;IACC,OAAO,eAAe,KAAK,CAAC,cAAc,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,KAErD;IACC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4CAA4C,CAAC,KAElE;IAIC,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC9E,4BAA4B,CAAC,GAAG,EAAE,kCAAkC,CAAC,CAAC;IACtE,yBAAyB,CACvB,GAAG,EACH,kCAAkC,EAClC,qCAAqC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAC5D,CAAC;IAEF,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,OAAO;QACL,aAAa;QACb,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,gBAAsE;IAEtE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAEpD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACzD,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;QACd,CAAC,CAAC,IAAI,CAAC;AACX,CAAC","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { createDocument, exportAllUpdates } from \"@tearleads/loro\";\nimport { getScopedPeerSeed } from \"../../data/crdtPeerSeed\";\nimport { ORGANIZATION_PROFILE_DOCUMENT_KIND } from \"../../data/documents/documentConstants\";\nimport {\n initializeStoredDocumentKind,\n writeStoredDocumentFields,\n} from \"../../data/documents/documentKinds\";\nimport { DOCUMENTS_APP_KIND } from \"../../data/persistence/documents/documentsPersistence\";\n\nexport { ORGANIZATION_PROFILE_DOCUMENT_KIND };\nexport const DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME = \"Personal Org\";\n\nexport function getOrganizationProfileDocumentLocalId(input: {\n readonly organizationId: string;\n}): string {\n return `org-profile:${input.organizationId}`;\n}\n\nexport function buildOrganizationProfileDocumentPatch(input: {\n readonly name: string;\n}): Record<string, string | undefined> {\n return {\n name: input.name.trim(),\n };\n}\n\nexport async function createInitializedOrganizationProfileDocument(input: {\n readonly name: string;\n}): Promise<{\n readonly initialUpdate: Uint8Array;\n readonly snapshot: string;\n}> {\n const doc = await createDocument(await getScopedPeerSeed(DOCUMENTS_APP_KIND));\n initializeStoredDocumentKind(doc, ORGANIZATION_PROFILE_DOCUMENT_KIND);\n writeStoredDocumentFields(\n doc,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n buildOrganizationProfileDocumentPatch({ name: input.name }),\n );\n\n const initialUpdate = exportAllUpdates(doc);\n\n return {\n initialUpdate,\n snapshot: bytesToBase64(initialUpdate),\n };\n}\n\nexport function readOrganizationProfileName(\n structuredFields: Readonly<Record<string, unknown>> | null | undefined,\n): string | null {\n if (!structuredFields) {\n return null;\n }\n\n const value = Reflect.get(structuredFields, \"name\");\n\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : null;\n}\n"]}
1
+ {"version":3,"file":"organizationProfile.js","sourceRoot":"","sources":["organizationProfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,kCAAkC,EAAE,MAAM,wCAAwC,CAAC;AAC5F,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uDAAuD,CAAC;AAC3F,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,kCAAkC,EAAE,CAAC;AAC9C,MAAM,CAAC,MAAM,0CAA0C,GAAG,cAAc,CAAC;AAEzE,MAAM,UAAU,qCAAqC,CAAC,KAErD;IACC,OAAO,eAAe,KAAK,CAAC,cAAc,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,qCAAqC,CAAC,KAErD;IACC,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4CAA4C,CAAC,KAElE;IAIC,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC9E,4BAA4B,CAAC,GAAG,EAAE,kCAAkC,CAAC,CAAC;IACtE,yBAAyB,CACvB,GAAG,EACH,kCAAkC,EAClC,qCAAqC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAC5D,CAAC;IAEF,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAE5C,OAAO;QACL,aAAa;QACb,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,gBAAsE;IAEtE,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAEpD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACzD,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;QACd,CAAC,CAAC,IAAI,CAAC;AACX,CAAC","sourcesContent":["import { bytesToBase64 } from \"@tearleads/encoding\";\nimport { createDocument, exportAllUpdates } from \"@tearleads/loro\";\nimport { ORGANIZATION_PROFILE_DOCUMENT_KIND } from \"../../data/documents/documentConstants\";\nimport {\n initializeStoredDocumentKind,\n writeStoredDocumentFields,\n} from \"../../data/documents/documentKinds\";\nimport { DOCUMENTS_APP_KIND } from \"../../data/persistence/documents/documentsPersistence\";\nimport { getScopedPeerSeed } from \"../../data/sync/crdtPeerSeed\";\n\nexport { ORGANIZATION_PROFILE_DOCUMENT_KIND };\nexport const DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME = \"Personal Org\";\n\nexport function getOrganizationProfileDocumentLocalId(input: {\n readonly organizationId: string;\n}): string {\n return `org-profile:${input.organizationId}`;\n}\n\nexport function buildOrganizationProfileDocumentPatch(input: {\n readonly name: string;\n}): Record<string, string | undefined> {\n return {\n name: input.name.trim(),\n };\n}\n\nexport async function createInitializedOrganizationProfileDocument(input: {\n readonly name: string;\n}): Promise<{\n readonly initialUpdate: Uint8Array;\n readonly snapshot: string;\n}> {\n const doc = await createDocument(await getScopedPeerSeed(DOCUMENTS_APP_KIND));\n initializeStoredDocumentKind(doc, ORGANIZATION_PROFILE_DOCUMENT_KIND);\n writeStoredDocumentFields(\n doc,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n buildOrganizationProfileDocumentPatch({ name: input.name }),\n );\n\n const initialUpdate = exportAllUpdates(doc);\n\n return {\n initialUpdate,\n snapshot: bytesToBase64(initialUpdate),\n };\n}\n\nexport function readOrganizationProfileName(\n structuredFields: Readonly<Record<string, unknown>> | null | undefined,\n): string | null {\n if (!structuredFields) {\n return null;\n }\n\n const value = Reflect.get(structuredFields, \"name\");\n\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : null;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"policyHistoryCache.js","sourceRoot":"","sources":["policyHistoryCache.ts"],"names":[],"mappings":"AACA,OAAO,EACL,8CAA8C,EAC9C,wCAAwC,EAGxC,0BAA0B,GAC3B,MAAM,uCAAuC,CAAC;AAW/C,qEAAqE;AACrE,8EAA8E;AAC9E,MAAM,SAAS,GAAG,IAAI,OAAO,EAA2C,CAAC;AAEzE,MAAM,UAAU,uBAAuB,CAAC,KAKvC;IACC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,0BAA0B,CACpC,KAAK,CAAC,MAAM,CAAC,cAAc,EAC3B,KAAK,CAAC,MAAM,CAAC,eAAe,CAC7B,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IACE,MAAM,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO;QAC9C,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QACpC,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa;QAC5C,CAAC,8CAA8C,CAC7C,KAAK,CAAC,MAAM,EACZ,MAAM,CAAC,OAAO,CACf;QACD,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,EACpE,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAOlC;IACC,IACE,CAAC,8CAA8C,CAC7C,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,OAAO,CACd;QACD,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;QAEpE,OAAO;IACT,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,GAAG,CACP,0BAA0B,CACxB,KAAK,CAAC,MAAM,CAAC,cAAc,EAC3B,KAAK,CAAC,MAAM,CAAC,eAAe,CAC7B,EACD;QACE,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;YAC7B,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;YAC3C,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe;SAC9C;QACD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;QACvC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DomainScope } from \"../../data/domainScope\";\nimport {\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n type OrganizationPresentationAccessAttempt,\n type OrganizationPresentationAccessInput,\n organizationAccessScopeKey,\n} from \"./organizationPresentationAccessState\";\nimport type { OrganizationPolicyHistory } from \"./policyHistoryTypes\";\n\ninterface CachedHistory {\n readonly access: OrganizationPresentationAccessInput;\n readonly attempt: OrganizationPresentationAccessAttempt;\n readonly history: OrganizationPolicyHistory;\n readonly stateHash: string;\n readonly beforeVersion: number;\n}\n\n// Only one verified page per account/org is retained. Names and wire\n// evidence never enter this cache, and nothing here is written to a database.\nconst histories = new WeakMap<DomainScope, Map<string, CachedHistory>>();\n\nexport function loadCachedPolicyHistory(input: {\n domainScope: DomainScope;\n access: OrganizationPresentationAccessInput;\n stateHash: string;\n beforeVersion: number;\n}): OrganizationPolicyHistory | null {\n const byKey = histories.get(input.domainScope);\n const key = organizationAccessScopeKey(\n input.access.organizationId,\n input.access.requesterUserId,\n );\n const cached = byKey?.get(key);\n if (!cached) return null;\n if (\n cached.access.execSql !== input.access.execSql ||\n cached.stateHash !== input.stateHash ||\n cached.beforeVersion !== input.beforeVersion ||\n !isOrganizationPresentationAccessAttemptCurrent(\n input.access,\n cached.attempt,\n ) ||\n !isOrganizationPresentationAccessReadable(input.access, \"readModel\")\n ) {\n byKey?.delete(key);\n return null;\n }\n return structuredClone(cached.history);\n}\n\nexport function cachePolicyHistory(input: {\n domainScope: DomainScope;\n access: OrganizationPresentationAccessInput;\n attempt: OrganizationPresentationAccessAttempt;\n history: OrganizationPolicyHistory;\n stateHash: string;\n beforeVersion: number;\n}): void {\n if (\n !isOrganizationPresentationAccessAttemptCurrent(\n input.access,\n input.attempt,\n ) ||\n !isOrganizationPresentationAccessReadable(input.access, \"readModel\")\n )\n return;\n let byKey = histories.get(input.domainScope);\n if (!byKey) {\n byKey = new Map();\n histories.set(input.domainScope, byKey);\n }\n byKey.set(\n organizationAccessScopeKey(\n input.access.organizationId,\n input.access.requesterUserId,\n ),\n {\n access: {\n execSql: input.access.execSql,\n organizationId: input.access.organizationId,\n requesterUserId: input.access.requesterUserId,\n },\n attempt: input.attempt,\n history: structuredClone(input.history),\n stateHash: input.stateHash,\n beforeVersion: input.beforeVersion,\n },\n );\n}\n"]}
1
+ {"version":3,"file":"policyHistoryCache.js","sourceRoot":"","sources":["policyHistoryCache.ts"],"names":[],"mappings":"AACA,OAAO,EACL,8CAA8C,EAC9C,wCAAwC,EAGxC,0BAA0B,GAC3B,MAAM,uCAAuC,CAAC;AAW/C,qEAAqE;AACrE,8EAA8E;AAC9E,MAAM,SAAS,GAAG,IAAI,OAAO,EAA2C,CAAC;AAEzE,MAAM,UAAU,uBAAuB,CAAC,KAKvC;IACC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,0BAA0B,CACpC,KAAK,CAAC,MAAM,CAAC,cAAc,EAC3B,KAAK,CAAC,MAAM,CAAC,eAAe,CAC7B,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IACE,MAAM,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO;QAC9C,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QACpC,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa;QAC5C,CAAC,8CAA8C,CAC7C,KAAK,CAAC,MAAM,EACZ,MAAM,CAAC,OAAO,CACf;QACD,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,EACpE,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAOlC;IACC,IACE,CAAC,8CAA8C,CAC7C,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,OAAO,CACd;QACD,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;QAEpE,OAAO;IACT,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,GAAG,CACP,0BAA0B,CACxB,KAAK,CAAC,MAAM,CAAC,cAAc,EAC3B,KAAK,CAAC,MAAM,CAAC,eAAe,CAC7B,EACD;QACE,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;YAC7B,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;YAC3C,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe;SAC9C;QACD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;QACvC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DomainScope } from \"../../data/shared/domainScope\";\nimport {\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n type OrganizationPresentationAccessAttempt,\n type OrganizationPresentationAccessInput,\n organizationAccessScopeKey,\n} from \"./organizationPresentationAccessState\";\nimport type { OrganizationPolicyHistory } from \"./policyHistoryTypes\";\n\ninterface CachedHistory {\n readonly access: OrganizationPresentationAccessInput;\n readonly attempt: OrganizationPresentationAccessAttempt;\n readonly history: OrganizationPolicyHistory;\n readonly stateHash: string;\n readonly beforeVersion: number;\n}\n\n// Only one verified page per account/org is retained. Names and wire\n// evidence never enter this cache, and nothing here is written to a database.\nconst histories = new WeakMap<DomainScope, Map<string, CachedHistory>>();\n\nexport function loadCachedPolicyHistory(input: {\n domainScope: DomainScope;\n access: OrganizationPresentationAccessInput;\n stateHash: string;\n beforeVersion: number;\n}): OrganizationPolicyHistory | null {\n const byKey = histories.get(input.domainScope);\n const key = organizationAccessScopeKey(\n input.access.organizationId,\n input.access.requesterUserId,\n );\n const cached = byKey?.get(key);\n if (!cached) return null;\n if (\n cached.access.execSql !== input.access.execSql ||\n cached.stateHash !== input.stateHash ||\n cached.beforeVersion !== input.beforeVersion ||\n !isOrganizationPresentationAccessAttemptCurrent(\n input.access,\n cached.attempt,\n ) ||\n !isOrganizationPresentationAccessReadable(input.access, \"readModel\")\n ) {\n byKey?.delete(key);\n return null;\n }\n return structuredClone(cached.history);\n}\n\nexport function cachePolicyHistory(input: {\n domainScope: DomainScope;\n access: OrganizationPresentationAccessInput;\n attempt: OrganizationPresentationAccessAttempt;\n history: OrganizationPolicyHistory;\n stateHash: string;\n beforeVersion: number;\n}): void {\n if (\n !isOrganizationPresentationAccessAttemptCurrent(\n input.access,\n input.attempt,\n ) ||\n !isOrganizationPresentationAccessReadable(input.access, \"readModel\")\n )\n return;\n let byKey = histories.get(input.domainScope);\n if (!byKey) {\n byKey = new Map();\n histories.set(input.domainScope, byKey);\n }\n byKey.set(\n organizationAccessScopeKey(\n input.access.organizationId,\n input.access.requesterUserId,\n ),\n {\n access: {\n execSql: input.access.execSql,\n organizationId: input.access.organizationId,\n requesterUserId: input.access.requesterUserId,\n },\n attempt: input.attempt,\n history: structuredClone(input.history),\n stateHash: input.stateHash,\n beforeVersion: input.beforeVersion,\n },\n );\n}\n"]}
@@ -2,7 +2,7 @@ import { MAX_ROTATION_CONTAINER_REKEYS } from "../../internal/validators/util/in
2
2
  import { rememberVerifiedContainerHeads } from "../../data/containers/shared/heldContainerHeads.js";
3
3
  import { acknowledgeContainerMutationBatch } from "../../data/containers/shared/mutationAcknowledgement.js";
4
4
  import { getTargetContainerContext, readContainerState, } from "../../data/containers/shared/projection.js";
5
- import { verifyContainerWriterProjection, } from "../../data/keyingProjectionVerification.js";
5
+ import { verifyContainerWriterProjection, } from "../../data/keyingProjectionVerification/index.js";
6
6
  import { createProjectionUserKeyResolver } from "../../data/keyingProjectionVerification/userKeyResolver.js";
7
7
  import { rebaseOnDeepestAncestor } from "../containers/child/carriedDescendantRekeys.js";
8
8
  import { scheduleHeldDescendantRecitations } from "../containers/child/recite.js";
@@ -1 +1 @@
1
- {"version":3,"file":"principalContainerRematerializationPlanning.js","sourceRoot":"","sources":["principalContainerRematerializationPlanning.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalContainerGrant } from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport type { ContainerReciteApi } from \"../../data/containers/shared/reciteApi\";\nimport type { ContainerMutationAuthor } from \"../../data/containers/shared/types\";\nimport type {\n PrincipalPolicyCache,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport type { ResolvedPrincipalPolicyEvidence } from \"../../data/keyingProjectionVerification/types\";\nimport type { createProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification/userKeyResolver\";\nimport type { CurrentPolicyReferenceResolver } from \"../../data/principals/currentPolicyReferenceResolver\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport {\n planCarriedDescendantRekey,\n type SpeculativePath,\n} from \"../containers/child/carriedDescendantRekeys\";\nimport type { PlannedRematerialization } from \"./principalContainerRematerializationTargets\";\n\nexport interface RematerializationApi\n extends ContainerReciteApi,\n Pick<ApiClient, \"getContainerWriterProjectionResult\"> {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\nexport interface PrincipalRematerializationPredecessor {\n readonly authored?: readonly ResolvedPrincipalPolicyEvidence[] | undefined;\n readonly policies: readonly PrincipalPolicyCurrentEvidence[];\n readonly projections: readonly ContainerWriterProjectionResponse[];\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n}\n\nexport interface PrincipalContainerRematerializationInput {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly apiClient: RematerializationApi;\n readonly author: ContainerMutationAuthor;\n readonly execSql: ExecSql;\n readonly grants: readonly PrincipalContainerGrant[];\n readonly groupId: string;\n readonly nextPolicy: PrincipalPolicyCurrentEvidence;\n readonly resolveAuthoredPolicyReferences?:\n | CurrentPolicyReferenceResolver\n | undefined;\n readonly revokedContainerId?: string | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n readonly recitationStillCurrent?: (() => boolean) | undefined;\n readonly targetSecretKey: Uint8Array;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\n/** What the batch has signed so far, in the order it will be submitted. */\nexport interface BatchPlanning {\n /**\n * Keys the batch minted, by epoch id. A rotation wraps its successor to the\n * group at the head this batch commits, which no store can open yet; a\n * level planned beneath it opens that epoch with the key minted here, and\n * its keyring then opens the retired epoch the level below is pinned to.\n */\n readonly knownContainerKeks: Map<string, Uint8Array>;\n readonly plans: PlannedRematerialization[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n readonly rotatedAbove: SpeculativePath[];\n}\n\n/** How many rekeys the batch carries beyond its rematerializations. */\nfunction carriedCount(batch: BatchPlanning): number {\n return batch.plans.filter((entry) => entry.carried).length;\n}\n\n/**\n * Sign a rekey of `served` under the batch's rotations above it, and add it.\n * The server accepts at most `MAX_ROTATION_CONTAINER_REKEYS` carried entries;\n * past that a rematerialization below them could not be signed on a current\n * path, so the batch is refused here, before signing what the server would\n * refuse anyway, and the policy change has to wait for a lazy repair of the\n * tree. Groups granted that far apart on one chain are not a shape the SDK\n * creates.\n */\nexport async function carryLevel(\n batch: BatchPlanning,\n served: ContainerWriterProjectionResponse,\n): Promise<void> {\n const { rematerialization } = batch;\n if (carriedCount(batch) >= MAX_ROTATION_CONTAINER_REKEYS) {\n throw new Error(\n `Policy change would carry more than ${MAX_ROTATION_CONTAINER_REKEYS} descendant rekeys`,\n );\n }\n const planned = await planCarriedDescendantRekey({\n apiClient: rematerialization.apiClient,\n author: rematerialization.author,\n execSql: rematerialization.execSql,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n // Its path cites the policy this batch commits, so like every\n // rematerialized rotation it must cite the successor.\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n resolveAuthoredPolicyReferences:\n rematerialization.resolveAuthoredPolicyReferences,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n rotated: batch.rotatedAbove,\n served,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n });\n addPlan(batch, {\n carried: true,\n planned,\n rotated: planned.writerProjection,\n nextProjection: planned.writerProjection,\n });\n}\n\nexport function addPlan(\n batch: BatchPlanning,\n entry: PlannedRematerialization,\n): void {\n batch.plans.push(entry);\n if (!entry.rotated) return;\n batch.rotatedAbove.push(entry.rotated);\n const minted = entry.rotated.containerKeks.at(-1)?.containerKeyEpochId;\n if (minted) batch.knownContainerKeks.set(minted, entry.planned.containerKey);\n}\n\n/**\n * Levels of a re-rooted path pinned to an epoch the batch retires above them:\n * those strictly between the rotated ancestor the path was re-rooted on and\n * the target, parent-first, from the first stale one down. A rotation planned\n * above a target strands every level between the two, and each must be\n * re-keyed under the one above before the target can be signed. The batch\n * carries them without waiting to be told: they are proper ancestors of a\n * granted container, so the server would name them, and a refusal per level\n * is a round trip each. Anything stale above the rotated ancestor is not this\n * batch's doing and is left alone. `carryLevel` holds the count to the cap.\n */\nexport function staleLevelsAbove(\n projection: ContainerWriterProjectionResponse,\n rotatedAncestorId: string,\n): string[] {\n const keks = projection.containerKeks;\n const ancestor = keks.findIndex(\n (kek) => kek.containerId === rotatedAncestorId,\n );\n if (ancestor < 0) return [];\n const between = keks.slice(ancestor, -1);\n const firstStale = between.findIndex(\n (kek, index) =>\n index > 0 &&\n kek.parentContainerKeyEpochId !== between[index - 1]?.containerKeyEpochId,\n );\n return firstStale < 0\n ? []\n : between.slice(firstStale).map((kek) => kek.containerId);\n}\n"]}
1
+ {"version":3,"file":"principalContainerRematerializationPlanning.js","sourceRoot":"","sources":["principalContainerRematerializationPlanning.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAc3E,OAAO,EACL,0BAA0B,GAE3B,MAAM,6CAA6C,CAAC;AA2DrD,uEAAuE;AACvE,SAAS,YAAY,CAAC,KAAoB;IACxC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AAC7D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAoB,EACpB,MAAyC;IAEzC,MAAM,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC;IACpC,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,6BAA6B,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CACb,uCAAuC,6BAA6B,oBAAoB,CACzF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAAC;QAC/C,SAAS,EAAE,iBAAiB,CAAC,SAAS;QACtC,MAAM,EAAE,iBAAiB,CAAC,MAAM;QAChC,OAAO,EAAE,iBAAiB,CAAC,OAAO;QAClC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;QAChD,8DAA8D;QAC9D,sDAAsD;QACtD,0BAA0B,EAAE,iBAAiB,CAAC,UAAU;QACxD,+BAA+B,EAC7B,iBAAiB,CAAC,+BAA+B;QACnD,wBAAwB,EAAE,KAAK,CAAC,wBAAwB;QACxD,OAAO,EAAE,KAAK,CAAC,YAAY;QAC3B,MAAM;QACN,YAAY,EAAE,iBAAiB,CAAC,YAAY;QAC5C,eAAe,EAAE,iBAAiB,CAAC,eAAe;QAClD,+BAA+B,EAC7B,iBAAiB,CAAC,+BAA+B;KACpD,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,EAAE;QACb,OAAO,EAAE,IAAI;QACb,OAAO;QACP,OAAO,EAAE,OAAO,CAAC,gBAAgB;QACjC,cAAc,EAAE,OAAO,CAAC,gBAAgB;KACzC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,KAAoB,EACpB,KAA+B;IAE/B,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO;IAC3B,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC;IACvE,IAAI,MAAM;QAAE,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAA6C,EAC7C,iBAAyB;IAEzB,MAAM,IAAI,GAAG,UAAU,CAAC,aAAa,CAAC;IACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAC7B,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,KAAK,iBAAiB,CAC/C,CAAC;IACF,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAClC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CACb,KAAK,GAAG,CAAC;QACT,GAAG,CAAC,yBAAyB,KAAK,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,mBAAmB,CAC5E,CAAC;IACF,OAAO,UAAU,GAAG,CAAC;QACnB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalContainerGrant } from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { MAX_ROTATION_CONTAINER_REKEYS } from \"@tearleads/validators/util\";\nimport type { ContainerReciteApi } from \"../../data/containers/shared/reciteApi\";\nimport type { ContainerMutationAuthor } from \"../../data/containers/shared/types\";\nimport type {\n PrincipalPolicyCache,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport type { ResolvedPrincipalPolicyEvidence } from \"../../data/keyingProjectionVerification/types\";\nimport type { createProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification/userKeyResolver\";\nimport type { CurrentPolicyReferenceResolver } from \"../../data/principals/currentPolicyReferenceResolver\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../data/shared/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport {\n planCarriedDescendantRekey,\n type SpeculativePath,\n} from \"../containers/child/carriedDescendantRekeys\";\nimport type { PlannedRematerialization } from \"./principalContainerRematerializationTargets\";\n\nexport interface RematerializationApi\n extends ContainerReciteApi,\n Pick<ApiClient, \"getContainerWriterProjectionResult\"> {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\nexport interface PrincipalRematerializationPredecessor {\n readonly authored?: readonly ResolvedPrincipalPolicyEvidence[] | undefined;\n readonly policies: readonly PrincipalPolicyCurrentEvidence[];\n readonly projections: readonly ContainerWriterProjectionResponse[];\n readonly knownContainerKeks: ReadonlyMap<string, Uint8Array>;\n}\n\nexport interface PrincipalContainerRematerializationInput {\n readonly preceding?: PrincipalRematerializationPredecessor | undefined;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly apiClient: RematerializationApi;\n readonly author: ContainerMutationAuthor;\n readonly execSql: ExecSql;\n readonly grants: readonly PrincipalContainerGrant[];\n readonly groupId: string;\n readonly nextPolicy: PrincipalPolicyCurrentEvidence;\n readonly resolveAuthoredPolicyReferences?:\n | CurrentPolicyReferenceResolver\n | undefined;\n readonly revokedContainerId?: string | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n /** Session lifetime for best-effort work after durable acknowledgement. */\n readonly recitationStillCurrent?: (() => boolean) | undefined;\n readonly targetSecretKey: Uint8Array;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\n/** What the batch has signed so far, in the order it will be submitted. */\nexport interface BatchPlanning {\n /**\n * Keys the batch minted, by epoch id. A rotation wraps its successor to the\n * group at the head this batch commits, which no store can open yet; a\n * level planned beneath it opens that epoch with the key minted here, and\n * its keyring then opens the retired epoch the level below is pinned to.\n */\n readonly knownContainerKeks: Map<string, Uint8Array>;\n readonly plans: PlannedRematerialization[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly rematerialization: PrincipalContainerRematerializationInput;\n readonly resolveProjectionUserKey: ReturnType<\n typeof createProjectionUserKeyResolver\n >;\n readonly rotatedAbove: SpeculativePath[];\n}\n\n/** How many rekeys the batch carries beyond its rematerializations. */\nfunction carriedCount(batch: BatchPlanning): number {\n return batch.plans.filter((entry) => entry.carried).length;\n}\n\n/**\n * Sign a rekey of `served` under the batch's rotations above it, and add it.\n * The server accepts at most `MAX_ROTATION_CONTAINER_REKEYS` carried entries;\n * past that a rematerialization below them could not be signed on a current\n * path, so the batch is refused here, before signing what the server would\n * refuse anyway, and the policy change has to wait for a lazy repair of the\n * tree. Groups granted that far apart on one chain are not a shape the SDK\n * creates.\n */\nexport async function carryLevel(\n batch: BatchPlanning,\n served: ContainerWriterProjectionResponse,\n): Promise<void> {\n const { rematerialization } = batch;\n if (carriedCount(batch) >= MAX_ROTATION_CONTAINER_REKEYS) {\n throw new Error(\n `Policy change would carry more than ${MAX_ROTATION_CONTAINER_REKEYS} descendant rekeys`,\n );\n }\n const planned = await planCarriedDescendantRekey({\n apiClient: rematerialization.apiClient,\n author: rematerialization.author,\n execSql: rematerialization.execSql,\n knownContainerKeks: batch.knownContainerKeks,\n principalPolicyCache: batch.principalPolicyCache,\n // Its path cites the policy this batch commits, so like every\n // rematerialized rotation it must cite the successor.\n replacementPrincipalPolicy: rematerialization.nextPolicy,\n resolveAuthoredPolicyReferences:\n rematerialization.resolveAuthoredPolicyReferences,\n resolveProjectionUserKey: batch.resolveProjectionUserKey,\n rotated: batch.rotatedAbove,\n served,\n stillCurrent: rematerialization.stillCurrent,\n targetSecretKey: rematerialization.targetSecretKey,\n warmReferencedPrincipalPolicies:\n rematerialization.warmReferencedPrincipalPolicies,\n });\n addPlan(batch, {\n carried: true,\n planned,\n rotated: planned.writerProjection,\n nextProjection: planned.writerProjection,\n });\n}\n\nexport function addPlan(\n batch: BatchPlanning,\n entry: PlannedRematerialization,\n): void {\n batch.plans.push(entry);\n if (!entry.rotated) return;\n batch.rotatedAbove.push(entry.rotated);\n const minted = entry.rotated.containerKeks.at(-1)?.containerKeyEpochId;\n if (minted) batch.knownContainerKeks.set(minted, entry.planned.containerKey);\n}\n\n/**\n * Levels of a re-rooted path pinned to an epoch the batch retires above them:\n * those strictly between the rotated ancestor the path was re-rooted on and\n * the target, parent-first, from the first stale one down. A rotation planned\n * above a target strands every level between the two, and each must be\n * re-keyed under the one above before the target can be signed. The batch\n * carries them without waiting to be told: they are proper ancestors of a\n * granted container, so the server would name them, and a refusal per level\n * is a round trip each. Anything stale above the rotated ancestor is not this\n * batch's doing and is left alone. `carryLevel` holds the count to the cap.\n */\nexport function staleLevelsAbove(\n projection: ContainerWriterProjectionResponse,\n rotatedAncestorId: string,\n): string[] {\n const keks = projection.containerKeks;\n const ancestor = keks.findIndex(\n (kek) => kek.containerId === rotatedAncestorId,\n );\n if (ancestor < 0) return [];\n const between = keks.slice(ancestor, -1);\n const firstStale = between.findIndex(\n (kek, index) =>\n index > 0 &&\n kek.parentContainerKeyEpochId !== between[index - 1]?.containerKeyEpochId,\n );\n return firstStale < 0\n ? []\n : between.slice(firstStale).map((kek) => kek.containerId);\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { KeyingVerificationError } from "../../internal/crypto/index.js";
2
- import { canonicalKeyingJsonString } from "../../data/keyingCanonicalJson.js";
2
+ import { canonicalKeyingJsonString } from "../../data/keying/canonicalJson.js";
3
3
  import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
4
4
  import { clearPrincipalMutationJournal, loadPrincipalMutationJournal, } from "../../data/persistence/principalMutationJournalPersistence.js";
5
5
  import { openPrincipalMutation, principalMutationJournalScopeId, } from "../../data/principals/principalMutationJournal.js";
@@ -1 +1 @@
1
- {"version":3,"file":"principalMutationJournalManagement.js","sourceRoot":"","sources":["principalMutationJournalManagement.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { canonicalKeyingJsonString } from \"../../data/keyingCanonicalJson\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n clearPrincipalMutationJournal,\n loadPrincipalMutationJournal,\n} from \"../../data/persistence/principalMutationJournalPersistence\";\nimport {\n type AuthoredPrincipalMutation,\n openPrincipalMutation,\n principalMutationJournalScopeId,\n} from \"../../data/principals/principalMutationJournal\";\nimport {\n principalMutationJournalRecordId,\n UnreadablePrincipalMutationError,\n} from \"../../data/principals/principalMutationJournalRecord\";\nimport { getOrCreatePrincipalPolicyCoordinator } from \"../../data/principals/principalPolicyCoordinator\";\nimport type { PrincipalMutationJournalContext } from \"./principalMutationJournalSession\";\n\nexport interface PrincipalMutationRecoveryApi {\n readonly readPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<AuthoredPrincipalMutation | null>;\n readonly recoverPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<void>;\n readonly abandonPendingPrincipalMutation: (\n organizationId: string,\n mutation: AuthoredPrincipalMutation,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n readonly discardUnreadablePrincipalMutation: (\n organizationId: string,\n recordId: string,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n}\n\ntype JournalIdentity = Pick<\n PrincipalMutationJournalContext,\n \"execSql\" | \"scope\" | \"signingKeyPair\" | \"stillCurrent\"\n>;\n\nasync function loadAuthenticatedMutation(input: JournalIdentity) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return null;\n let mutation: AuthoredPrincipalMutation;\n try {\n mutation = await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!(error instanceof KeyingVerificationError)) throw error;\n const recordId = await principalMutationJournalRecordId(row);\n assertProjectionVerificationCurrent(input.stillCurrent);\n throw new UnreadablePrincipalMutationError(\n recordId,\n error.code === \"invalid_shape\" ? \"format\" : \"authentication\",\n );\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { row, mutation };\n}\n\n/** Discard only the inspected unreadable bytes; never parse them for submission. */\nexport async function discardUnreadableJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly recordId: string;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Discarding unreadable work requires acknowledging its unknown outcome\",\n );\n const expected = input.recordId;\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return false;\n if ((await principalMutationJournalRecordId(row)) !== expected)\n throw new Error(\n \"The unreadable principal mutation changed after inspection\",\n );\n let unreadable = false;\n try {\n await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n if (!(error instanceof KeyingVerificationError)) throw error;\n unreadable = true;\n }\n if (!unreadable)\n throw new Error(\n \"Readable principal mutations require ordinary abandonment\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The unreadable principal mutation changed during discard\",\n );\n return true;\n });\n}\n\n/** Inspect authenticated authored work without retrying it or changing checkpoints. */\nexport async function readJournaledPrincipalMutation(\n input: JournalIdentity,\n): Promise<AuthoredPrincipalMutation | null> {\n // Inspection may observe an owned dispatch; all mutations still use the lane.\n return (await loadAuthenticatedMutation(input))?.mutation ?? null;\n}\n\n/**\n * An explicit host/user choice to stop retries, not a claim that the write failed.\n * The exact inspected request must still own the lane; ordinary recovery never\n * calls this. Future authoring must still verify the latest policy state.\n */\nexport async function abandonJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly mutation: AuthoredPrincipalMutation;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Abandoning authored work requires acknowledging its unknown outcome\",\n );\n const expected = canonicalKeyingJsonString(\n JSON.parse(JSON.stringify(input.mutation)),\n \"inspected authored mutation\",\n );\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n const saved = await loadAuthenticatedMutation(input);\n if (!saved) return false;\n if (\n canonicalKeyingJsonString(saved.mutation, \"saved authored mutation\") !==\n expected\n )\n throw new Error(\n \"The pending principal mutation changed after inspection\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row: saved.row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The pending principal mutation changed during abandonment\",\n );\n return true;\n });\n}\n"]}
1
+ {"version":3,"file":"principalMutationJournalManagement.js","sourceRoot":"","sources":["principalMutationJournalManagement.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { canonicalKeyingJsonString } from \"../../data/keying/canonicalJson\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n clearPrincipalMutationJournal,\n loadPrincipalMutationJournal,\n} from \"../../data/persistence/principalMutationJournalPersistence\";\nimport {\n type AuthoredPrincipalMutation,\n openPrincipalMutation,\n principalMutationJournalScopeId,\n} from \"../../data/principals/principalMutationJournal\";\nimport {\n principalMutationJournalRecordId,\n UnreadablePrincipalMutationError,\n} from \"../../data/principals/principalMutationJournalRecord\";\nimport { getOrCreatePrincipalPolicyCoordinator } from \"../../data/principals/principalPolicyCoordinator\";\nimport type { PrincipalMutationJournalContext } from \"./principalMutationJournalSession\";\n\nexport interface PrincipalMutationRecoveryApi {\n readonly readPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<AuthoredPrincipalMutation | null>;\n readonly recoverPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<void>;\n readonly abandonPendingPrincipalMutation: (\n organizationId: string,\n mutation: AuthoredPrincipalMutation,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n readonly discardUnreadablePrincipalMutation: (\n organizationId: string,\n recordId: string,\n acknowledgeUnknownOutcome: true,\n ) => Promise<boolean>;\n}\n\ntype JournalIdentity = Pick<\n PrincipalMutationJournalContext,\n \"execSql\" | \"scope\" | \"signingKeyPair\" | \"stillCurrent\"\n>;\n\nasync function loadAuthenticatedMutation(input: JournalIdentity) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return null;\n let mutation: AuthoredPrincipalMutation;\n try {\n mutation = await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!(error instanceof KeyingVerificationError)) throw error;\n const recordId = await principalMutationJournalRecordId(row);\n assertProjectionVerificationCurrent(input.stillCurrent);\n throw new UnreadablePrincipalMutationError(\n recordId,\n error.code === \"invalid_shape\" ? \"format\" : \"authentication\",\n );\n }\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { row, mutation };\n}\n\n/** Discard only the inspected unreadable bytes; never parse them for submission. */\nexport async function discardUnreadableJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly recordId: string;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Discarding unreadable work requires acknowledging its unknown outcome\",\n );\n const expected = input.recordId;\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const row = await loadPrincipalMutationJournal(\n input.execSql,\n await principalMutationJournalScopeId(input.scope),\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!row) return false;\n if ((await principalMutationJournalRecordId(row)) !== expected)\n throw new Error(\n \"The unreadable principal mutation changed after inspection\",\n );\n let unreadable = false;\n try {\n await openPrincipalMutation({\n scope: input.scope,\n row,\n signingPublicKey: input.signingKeyPair.signingPublicKey,\n });\n } catch (error) {\n if (!(error instanceof KeyingVerificationError)) throw error;\n unreadable = true;\n }\n if (!unreadable)\n throw new Error(\n \"Readable principal mutations require ordinary abandonment\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The unreadable principal mutation changed during discard\",\n );\n return true;\n });\n}\n\n/** Inspect authenticated authored work without retrying it or changing checkpoints. */\nexport async function readJournaledPrincipalMutation(\n input: JournalIdentity,\n): Promise<AuthoredPrincipalMutation | null> {\n // Inspection may observe an owned dispatch; all mutations still use the lane.\n return (await loadAuthenticatedMutation(input))?.mutation ?? null;\n}\n\n/**\n * An explicit host/user choice to stop retries, not a claim that the write failed.\n * The exact inspected request must still own the lane; ordinary recovery never\n * calls this. Future authoring must still verify the latest policy state.\n */\nexport async function abandonJournaledPrincipalMutation(\n input: JournalIdentity & {\n readonly mutation: AuthoredPrincipalMutation;\n readonly acknowledgeUnknownOutcome: true;\n },\n): Promise<boolean> {\n if (input.acknowledgeUnknownOutcome !== true)\n throw new Error(\n \"Abandoning authored work requires acknowledging its unknown outcome\",\n );\n const expected = canonicalKeyingJsonString(\n JSON.parse(JSON.stringify(input.mutation)),\n \"inspected authored mutation\",\n );\n return getOrCreatePrincipalPolicyCoordinator(\n input.execSql,\n ).runJournalOperation(input.scope, async () => {\n const saved = await loadAuthenticatedMutation(input);\n if (!saved) return false;\n if (\n canonicalKeyingJsonString(saved.mutation, \"saved authored mutation\") !==\n expected\n )\n throw new Error(\n \"The pending principal mutation changed after inspection\",\n );\n const removed = await clearPrincipalMutationJournal({\n execSql: input.execSql,\n row: saved.row,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!removed)\n throw new Error(\n \"The pending principal mutation changed during abandonment\",\n );\n return true;\n });\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { computePrincipalStateHash } from "../../internal/crypto/index.js";
2
- import { canonicalKeyingJsonString } from "../../data/keyingCanonicalJson.js";
2
+ import { canonicalKeyingJsonString } from "../../data/keying/canonicalJson.js";
3
3
  import { assertPrincipalPolicyReceiptArtifacts } from "./principalPolicyReceiptArtifacts.js";
4
4
  /** A past commit acknowledgement is not evidence for advancing current pins. */
5
5
  export async function assertAuthoredPrincipalMutationReceipt(request, response) {
@@ -1 +1 @@
1
- {"version":3,"file":"principalMutationReceipt.js","sourceRoot":"","sources":["principalMutationReceipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,qCAAqC,EAAE,MAAM,mCAAmC,CAAC;AAE1F,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAC1D,OAA6C,EAC7C,QAA+C;IAE/C,KAAK,MAAM,IAAI,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAU,EAAE,CAAC;QAClE,MAAM,oCAAoC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QAClD,MAAM,oCAAoC,CACxC,OAAO,CAAC,YAAY,EACpB,QAAQ,CAAC,YAAY,CACtB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,QAA6D,EAC7D,QAA8D;IAE9D,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC;IAC7E,IACE,SAAS,KAAK,CAAC,MAAM,yBAAyB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC/D,yBAAyB,CAAC,KAAK,EAAE,kCAAkC,CAAC;YAClE,yBAAyB,CAAC,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAC;QAEvE,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,qCAAqC,CAAC;QACpC,OAAO,EAAE,QAAQ;QACjB,QAAQ,EAAE,QAAQ;QAClB,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE;KACtD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { computePrincipalStateHash } from \"@tearleads/crypto\";\nimport type { CommitOrganizationGroupPolicyRequest } from \"@tearleads/validators/request\";\nimport type { CommitOrganizationGroupPolicyResponse } from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../../data/keyingCanonicalJson\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\n/** A past commit acknowledgement is not evidence for advancing current pins. */\nexport async function assertAuthoredPrincipalMutationReceipt(\n request: CommitOrganizationGroupPolicyRequest,\n response: CommitOrganizationGroupPolicyResponse,\n): Promise<void> {\n for (const part of [\"groupPolicy\", \"organizationPolicy\"] as const) {\n await assertAuthoredPrincipalPolicyReceipt(request[part], response[part]);\n }\n if (Boolean(request.memberPolicy) !== Boolean(response.memberPolicy)) {\n throw new Error(\"Principal mutation receipt Members policy differs\");\n }\n if (request.memberPolicy && response.memberPolicy) {\n await assertAuthoredPrincipalPolicyReceipt(\n request.memberPolicy,\n response.memberPolicy,\n );\n }\n}\n\nexport async function assertAuthoredPrincipalPolicyReceipt(\n expected: CommitOrganizationGroupPolicyRequest[\"groupPolicy\"],\n observed: CommitOrganizationGroupPolicyResponse[\"groupPolicy\"],\n): Promise<void> {\n const { stateHash, createdAt: _createdAt, ...state } = observed.currentState;\n if (\n stateHash !== (await computePrincipalStateHash(expected.state)) ||\n canonicalKeyingJsonString(state, \"principal mutation receipt state\") !==\n canonicalKeyingJsonString(expected.state, \"authored principal state\")\n )\n throw new Error(\n \"Principal mutation receipt state differs from the authored request\",\n );\n assertPrincipalPolicyReceiptArtifacts({\n request: expected,\n response: observed,\n expectedHead: { ...observed.currentState, stateHash },\n });\n}\n"]}
1
+ {"version":3,"file":"principalMutationReceipt.js","sourceRoot":"","sources":["principalMutationReceipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,qCAAqC,EAAE,MAAM,mCAAmC,CAAC;AAE1F,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAC1D,OAA6C,EAC7C,QAA+C;IAE/C,KAAK,MAAM,IAAI,IAAI,CAAC,aAAa,EAAE,oBAAoB,CAAU,EAAE,CAAC;QAClE,MAAM,oCAAoC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;QAClD,MAAM,oCAAoC,CACxC,OAAO,CAAC,YAAY,EACpB,QAAQ,CAAC,YAAY,CACtB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oCAAoC,CACxD,QAA6D,EAC7D,QAA8D;IAE9D,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,GAAG,QAAQ,CAAC,YAAY,CAAC;IAC7E,IACE,SAAS,KAAK,CAAC,MAAM,yBAAyB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC/D,yBAAyB,CAAC,KAAK,EAAE,kCAAkC,CAAC;YAClE,yBAAyB,CAAC,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAC;QAEvE,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,qCAAqC,CAAC;QACpC,OAAO,EAAE,QAAQ;QACjB,QAAQ,EAAE,QAAQ;QAClB,YAAY,EAAE,EAAE,GAAG,QAAQ,CAAC,YAAY,EAAE,SAAS,EAAE;KACtD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { computePrincipalStateHash } from \"@tearleads/crypto\";\nimport type { CommitOrganizationGroupPolicyRequest } from \"@tearleads/validators/request\";\nimport type { CommitOrganizationGroupPolicyResponse } from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../../data/keying/canonicalJson\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\n/** A past commit acknowledgement is not evidence for advancing current pins. */\nexport async function assertAuthoredPrincipalMutationReceipt(\n request: CommitOrganizationGroupPolicyRequest,\n response: CommitOrganizationGroupPolicyResponse,\n): Promise<void> {\n for (const part of [\"groupPolicy\", \"organizationPolicy\"] as const) {\n await assertAuthoredPrincipalPolicyReceipt(request[part], response[part]);\n }\n if (Boolean(request.memberPolicy) !== Boolean(response.memberPolicy)) {\n throw new Error(\"Principal mutation receipt Members policy differs\");\n }\n if (request.memberPolicy && response.memberPolicy) {\n await assertAuthoredPrincipalPolicyReceipt(\n request.memberPolicy,\n response.memberPolicy,\n );\n }\n}\n\nexport async function assertAuthoredPrincipalPolicyReceipt(\n expected: CommitOrganizationGroupPolicyRequest[\"groupPolicy\"],\n observed: CommitOrganizationGroupPolicyResponse[\"groupPolicy\"],\n): Promise<void> {\n const { stateHash, createdAt: _createdAt, ...state } = observed.currentState;\n if (\n stateHash !== (await computePrincipalStateHash(expected.state)) ||\n canonicalKeyingJsonString(state, \"principal mutation receipt state\") !==\n canonicalKeyingJsonString(expected.state, \"authored principal state\")\n )\n throw new Error(\n \"Principal mutation receipt state differs from the authored request\",\n );\n assertPrincipalPolicyReceiptArtifacts({\n request: expected,\n response: observed,\n expectedHead: { ...observed.currentState, stateHash },\n });\n}\n"]}
@@ -2,7 +2,7 @@ export { createOrganizationGroup } from "./groupCreation.js";
2
2
  import type { ReferencedPrincipalHead, SigningKeyPair, VerifiedPrincipalPolicy } from "../../internal/crypto/index.js";
3
3
  import type { ContainerMutationRequest } from "../../internal/validators/request/index.js";
4
4
  import type { ContainerMutationResponse, PrincipalPolicyBundleResponse, PrincipalPolicyMutationResponse } from "../../internal/validators/response/index.js";
5
- import type { SecurityIncidentReporter } from "../../data/securityIncidents.js";
5
+ import type { SecurityIncidentReporter } from "../../data/shared/securityIncidents.js";
6
6
  import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
7
7
  import type { TrustedUserIdentityResolver } from "../../data/trustedUserIdentity/index.js";
8
8
  import { type PrincipalPolicyReadWriteApi } from "./groupPolicyMutationContext.js";