@tearleads/client-sdk 0.1.15 → 0.1.17

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 (244) hide show
  1. package/client/Tearleads.d.ts +2 -0
  2. package/client/Tearleads.js +1 -0
  3. package/client/Tearleads.js.map +1 -1
  4. package/client/index.d.ts +1 -1
  5. package/client/index.js.map +1 -1
  6. package/client/organizations/currentPrincipalMutations.js +96 -0
  7. package/client/organizations/currentPrincipalMutations.js.map +1 -0
  8. package/client/organizations/index.d.ts +4 -42
  9. package/client/organizations/index.js +17 -3
  10. package/client/organizations/index.js.map +1 -1
  11. package/client/organizations/organizationGroupHistory.js +44 -0
  12. package/client/organizations/organizationGroupHistory.js.map +1 -0
  13. package/client/organizations/organizationGroupNameHydration.js +14 -1
  14. package/client/organizations/organizationGroupNameHydration.js.map +1 -1
  15. package/client/organizations/organizationGroupPresentation.d.ts +1 -0
  16. package/client/organizations/organizationGroupPresentation.js +16 -2
  17. package/client/organizations/organizationGroupPresentation.js.map +1 -1
  18. package/client/organizations/organizationReadModels.d.ts +1 -1
  19. package/client/organizations/organizationReadModels.js +11 -1
  20. package/client/organizations/organizationReadModels.js.map +1 -1
  21. package/client/organizations/organizationsTypes.d.ts +50 -0
  22. package/client/organizations/organizationsTypes.js +2 -0
  23. package/client/organizations/organizationsTypes.js.map +1 -0
  24. package/client/organizations/principalContainerMutations.js +2 -0
  25. package/client/organizations/principalContainerMutations.js.map +1 -1
  26. package/client/organizations/principalMutationRecovery.d.ts +16 -0
  27. package/client/organizations/principalMutationRecovery.js +23 -0
  28. package/client/organizations/principalMutationRecovery.js.map +1 -0
  29. package/client/organizations/principalMutationScope.js +7 -2
  30. package/client/organizations/principalMutationScope.js.map +1 -1
  31. package/client/organizations/principalMutations.d.ts +4 -308
  32. package/client/organizations/principalMutations.js +165 -87
  33. package/client/organizations/principalMutations.js.map +1 -1
  34. package/client/principalMutationApi.d.ts +24 -0
  35. package/client/principalMutationApi.js +108 -0
  36. package/client/principalMutationApi.js.map +1 -0
  37. package/client/principalMutationDeadline.js +23 -0
  38. package/client/principalMutationDeadline.js.map +1 -0
  39. package/client/workflowRuntime.d.ts +3 -1
  40. package/client/workflowRuntime.js +44 -5
  41. package/client/workflowRuntime.js.map +1 -1
  42. package/data/persistence/principalCurrentAcknowledgementPersistence.d.ts +27 -0
  43. package/data/persistence/principalCurrentAcknowledgementPersistence.js +116 -0
  44. package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -0
  45. package/data/persistence/principalGrantRetirementPersistence.d.ts +3 -3
  46. package/data/persistence/principalGrantRetirementPersistence.js +4 -1
  47. package/data/persistence/principalGrantRetirementPersistence.js.map +1 -1
  48. package/data/persistence/principalKeyEnvelopeCandidates.js +12 -1
  49. package/data/persistence/principalKeyEnvelopeCandidates.js.map +1 -1
  50. package/data/persistence/principalMutationJournalPersistence.d.ts +19 -0
  51. package/data/persistence/principalMutationJournalPersistence.js +53 -0
  52. package/data/persistence/principalMutationJournalPersistence.js.map +1 -0
  53. package/data/persistence/verifiedPrincipalPolicyBundle.js +7 -51
  54. package/data/persistence/verifiedPrincipalPolicyBundle.js.map +1 -1
  55. package/data/persistence/verifiedPrincipalPolicyCurrent.js +56 -0
  56. package/data/persistence/verifiedPrincipalPolicyCurrent.js.map +1 -0
  57. package/data/principals/currentPolicyReferenceResolver.js +2 -0
  58. package/data/principals/currentPolicyReferenceResolver.js.map +1 -0
  59. package/data/principals/principalHistoryScopeProtection.js +23 -0
  60. package/data/principals/principalHistoryScopeProtection.js.map +1 -0
  61. package/data/principals/principalMutationJournal.d.ts +26 -0
  62. package/data/principals/principalMutationJournal.js +90 -0
  63. package/data/principals/principalMutationJournal.js.map +1 -0
  64. package/data/principals/principalMutationJournalRecord.d.ts +8 -0
  65. package/data/principals/principalMutationJournalRecord.js +25 -0
  66. package/data/principals/principalMutationJournalRecord.js.map +1 -0
  67. package/data/principals/principalPolicyAdminSigners.js.map +1 -1
  68. package/data/sqlite/principalHistoryStageSchema.js +3 -0
  69. package/data/sqlite/principalHistoryStageSchema.js.map +1 -1
  70. package/data/sqlite/principalMutationJournalSchema.d.ts +85 -0
  71. package/data/sqlite/principalMutationJournalSchema.js +13 -0
  72. package/data/sqlite/principalMutationJournalSchema.js.map +1 -0
  73. package/data/sqlite/schema.d.ts +83 -0
  74. package/data/sqlite/schema.js +3 -0
  75. package/data/sqlite/schema.js.map +1 -1
  76. package/index.d.ts +3 -3
  77. package/index.js +1 -1
  78. package/index.js.map +1 -1
  79. package/internal/crypto/index.d.ts +1 -1
  80. package/internal/crypto/index.js +1 -1
  81. package/internal/crypto/index.js.map +1 -1
  82. package/internal/crypto/keying/index.d.ts +3 -0
  83. package/internal/crypto/keying/index.js +3 -0
  84. package/internal/crypto/keying/index.js.map +1 -1
  85. package/internal/crypto/keying/principalPolicyCurrent.d.ts +1 -1
  86. package/internal/crypto/keying/principalPolicyCurrent.js +3 -3
  87. package/internal/crypto/keying/principalPolicyCurrent.js.map +1 -1
  88. package/internal/crypto/keying/principalPolicyCurrentEvidence.js +16 -0
  89. package/internal/crypto/keying/principalPolicyCurrentEvidence.js.map +1 -0
  90. package/internal/crypto/keying/principalPolicyCurrentMutation.d.ts +10 -0
  91. package/internal/crypto/keying/principalPolicyCurrentMutation.js +51 -0
  92. package/internal/crypto/keying/principalPolicyCurrentMutation.js.map +1 -0
  93. package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.d.ts +8 -0
  94. package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.js +46 -0
  95. package/internal/crypto/keying/principalPolicyCurrentPredecessorReferences.js.map +1 -0
  96. package/internal/crypto/keying/principalPolicyCurrentSuccessor.d.ts +10 -0
  97. package/internal/crypto/keying/principalPolicyCurrentSuccessor.js +60 -0
  98. package/internal/crypto/keying/principalPolicyCurrentSuccessor.js.map +1 -0
  99. package/internal/crypto/keying/principalPolicyHistory.js +4 -1
  100. package/internal/crypto/keying/principalPolicyHistory.js.map +1 -1
  101. package/internal/crypto/keying/principalPolicyHistoryReferences.js +1 -1
  102. package/internal/crypto/keying/principalPolicyHistoryReferences.js.map +1 -1
  103. package/internal/crypto/keying/principalPolicyHistoryTypes.d.ts +5 -2
  104. package/internal/crypto/keying/principalPolicyHistoryTypes.js +6 -3
  105. package/internal/crypto/keying/principalPolicyHistoryTypes.js.map +1 -1
  106. package/package.json +1 -1
  107. package/workflows/containers/child/carriedDescendantRekeys.js +9 -1
  108. package/workflows/containers/child/carriedDescendantRekeys.js.map +1 -1
  109. package/workflows/containers/child/replacementPrincipalPolicyReferences.js +19 -0
  110. package/workflows/containers/child/replacementPrincipalPolicyReferences.js.map +1 -0
  111. package/workflows/containers/child/share.js +4 -0
  112. package/workflows/containers/child/share.js.map +1 -1
  113. package/workflows/containers/child/sharePrincipalPolicy.d.ts +1 -0
  114. package/workflows/containers/child/sharePrincipalPolicy.js.map +1 -1
  115. package/workflows/organizations/acknowledgedDirectoryBindings.js +18 -0
  116. package/workflows/organizations/acknowledgedDirectoryBindings.js.map +1 -0
  117. package/workflows/organizations/commitCurrentGroupPolicyMutation.js +72 -0
  118. package/workflows/organizations/commitCurrentGroupPolicyMutation.js.map +1 -0
  119. package/workflows/organizations/createCurrentOrganizationGroup.js +85 -0
  120. package/workflows/organizations/createCurrentOrganizationGroup.js.map +1 -0
  121. package/workflows/organizations/currentGroupMetadataAuthority.js +53 -0
  122. package/workflows/organizations/currentGroupMetadataAuthority.js.map +1 -0
  123. package/workflows/organizations/currentGroupMutationReferences.js +35 -0
  124. package/workflows/organizations/currentGroupMutationReferences.js.map +1 -0
  125. package/workflows/organizations/currentGroupPolicyMutationContext.js +79 -0
  126. package/workflows/organizations/currentGroupPolicyMutationContext.js.map +1 -0
  127. package/workflows/organizations/currentOrganizationAuthority.js +88 -0
  128. package/workflows/organizations/currentOrganizationAuthority.js.map +1 -0
  129. package/workflows/organizations/currentOrganizationGroupNames.js +72 -0
  130. package/workflows/organizations/currentOrganizationGroupNames.js.map +1 -0
  131. package/workflows/organizations/currentOrganizationMutationAuthority.js +16 -0
  132. package/workflows/organizations/currentOrganizationMutationAuthority.js.map +1 -0
  133. package/workflows/organizations/currentOrganizationMutationRetention.js +53 -0
  134. package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -0
  135. package/workflows/organizations/currentPolicyMutationAcknowledgement.js +65 -0
  136. package/workflows/organizations/currentPolicyMutationAcknowledgement.js.map +1 -0
  137. package/workflows/organizations/currentPrincipalMutationLease.js +38 -0
  138. package/workflows/organizations/currentPrincipalMutationLease.js.map +1 -0
  139. package/workflows/organizations/deleteCurrentOrganizationGroup.js +35 -0
  140. package/workflows/organizations/deleteCurrentOrganizationGroup.js.map +1 -0
  141. package/workflows/organizations/deleteOrganizationGroup.d.ts +1 -0
  142. package/workflows/organizations/deleteOrganizationGroup.js +11 -0
  143. package/workflows/organizations/deleteOrganizationGroup.js.map +1 -1
  144. package/workflows/organizations/groupCreation.d.ts +1 -0
  145. package/workflows/organizations/groupCreation.js +9 -0
  146. package/workflows/organizations/groupCreation.js.map +1 -1
  147. package/workflows/organizations/groupMembershipName.d.ts +1 -1
  148. package/workflows/organizations/groupMembershipName.js.map +1 -1
  149. package/workflows/organizations/groupMetadataAccess.d.ts +2 -2
  150. package/workflows/organizations/groupMetadataAccess.js +1 -1
  151. package/workflows/organizations/groupMetadataAccess.js.map +1 -1
  152. package/workflows/organizations/groupMetadataBinding.js.map +1 -1
  153. package/workflows/organizations/groupMetadataContainerAuthority.js +2 -47
  154. package/workflows/organizations/groupMetadataContainerAuthority.js.map +1 -1
  155. package/workflows/organizations/groupMetadataRootBinding.js +51 -0
  156. package/workflows/organizations/groupMetadataRootBinding.js.map +1 -0
  157. package/workflows/organizations/groupMetadataRuntime.js +26 -10
  158. package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
  159. package/workflows/organizations/groupMutationAuthorization.js.map +1 -1
  160. package/workflows/organizations/groupNameUniqueness.js +1 -1
  161. package/workflows/organizations/groupNameUniqueness.js.map +1 -1
  162. package/workflows/organizations/groupPolicyHistoryPage.js +31 -0
  163. package/workflows/organizations/groupPolicyHistoryPage.js.map +1 -0
  164. package/workflows/organizations/groupPolicyMutationAcknowledgement.js +10 -75
  165. package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +1 -1
  166. package/workflows/organizations/groupPolicyMutationContext.d.ts +23 -13
  167. package/workflows/organizations/groupPolicyMutationContext.js +2 -1
  168. package/workflows/organizations/groupPolicyMutationContext.js.map +1 -1
  169. package/workflows/organizations/groupPolicyMutationEvidence.d.ts +26 -0
  170. package/workflows/organizations/groupPolicyMutationEvidence.js +64 -0
  171. package/workflows/organizations/groupPolicyMutationEvidence.js.map +1 -0
  172. package/workflows/organizations/groupPolicyMutationHead.js.map +1 -1
  173. package/workflows/organizations/groupPolicyRequests.js +69 -63
  174. package/workflows/organizations/groupPolicyRequests.js.map +1 -1
  175. package/workflows/organizations/index.d.ts +6 -0
  176. package/workflows/organizations/index.js +5 -0
  177. package/workflows/organizations/index.js.map +1 -1
  178. package/workflows/organizations/initialPrincipalCurrentPublication.js +83 -0
  179. package/workflows/organizations/initialPrincipalCurrentPublication.js.map +1 -0
  180. package/workflows/organizations/organizationGroupDirectory.js +6 -0
  181. package/workflows/organizations/organizationGroupDirectory.js.map +1 -1
  182. package/workflows/organizations/organizationGroupNames.js +7 -0
  183. package/workflows/organizations/organizationGroupNames.js.map +1 -1
  184. package/workflows/organizations/policyHistoryTypes.d.ts +2 -0
  185. package/workflows/organizations/policyHistoryTypes.js.map +1 -1
  186. package/workflows/organizations/principalContainerRematerialization.js +12 -2
  187. package/workflows/organizations/principalContainerRematerialization.js.map +1 -1
  188. package/workflows/organizations/principalContainerRematerializationPlanning.js +1 -0
  189. package/workflows/organizations/principalContainerRematerializationPlanning.js.map +1 -1
  190. package/workflows/organizations/principalContainerRematerializationTargets.js.map +1 -1
  191. package/workflows/organizations/principalCurrentPublicationSeal.js +51 -0
  192. package/workflows/organizations/principalCurrentPublicationSeal.js.map +1 -0
  193. package/workflows/organizations/principalMutationJournalLane.js +26 -0
  194. package/workflows/organizations/principalMutationJournalLane.js.map +1 -0
  195. package/workflows/organizations/principalMutationJournalManagement.d.ts +26 -0
  196. package/workflows/organizations/principalMutationJournalManagement.js +104 -0
  197. package/workflows/organizations/principalMutationJournalManagement.js.map +1 -0
  198. package/workflows/organizations/principalMutationJournalSession.d.ts +26 -0
  199. package/workflows/organizations/principalMutationJournalSession.js +85 -0
  200. package/workflows/organizations/principalMutationJournalSession.js.map +1 -0
  201. package/workflows/organizations/principalMutationReceipt.js +21 -0
  202. package/workflows/organizations/principalMutationReceipt.js.map +1 -0
  203. package/workflows/organizations/principalPolicyReceiptArtifacts.js +74 -0
  204. package/workflows/organizations/principalPolicyReceiptArtifacts.js.map +1 -0
  205. package/workflows/organizations/principalPolicyRequest.d.ts +5 -4
  206. package/workflows/organizations/principalPolicyRequest.js.map +1 -1
  207. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +23 -0
  208. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +159 -0
  209. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -0
  210. package/workflows/organizations/runtimeCurrentGroupMutation.js +85 -0
  211. package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -0
  212. package/workflows/organizations/runtimeCurrentOrganizationMutation.js +48 -0
  213. package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +1 -0
  214. package/workflows/principals/loadRecoveredPrincipalHistoryPage.d.ts +11 -0
  215. package/workflows/principals/loadRecoveredPrincipalHistoryPage.js +120 -0
  216. package/workflows/principals/loadRecoveredPrincipalHistoryPage.js.map +1 -0
  217. package/workflows/principals/principalCurrentRecoveryBatch.js +14 -0
  218. package/workflows/principals/principalCurrentRecoveryBatch.js.map +1 -0
  219. package/workflows/principals/principalHistoryRecoveryReferences.js +8 -0
  220. package/workflows/principals/principalHistoryRecoveryReferences.js.map +1 -1
  221. package/workflows/principals/principalRecoveryDirectory.d.ts +1 -1
  222. package/workflows/principals/principalRecoveryDirectory.js +32 -12
  223. package/workflows/principals/principalRecoveryDirectory.js.map +1 -1
  224. package/workflows/principals/principalRecoveryDiscoveryPage.js +36 -0
  225. package/workflows/principals/principalRecoveryDiscoveryPage.js.map +1 -0
  226. package/workflows/principals/principalRecoveryLocalPreference.js +29 -0
  227. package/workflows/principals/principalRecoveryLocalPreference.js.map +1 -0
  228. package/workflows/principals/principalRecoveryMemo.d.ts +16 -0
  229. package/workflows/principals/principalRecoveryMemo.js +88 -16
  230. package/workflows/principals/principalRecoveryMemo.js.map +1 -1
  231. package/workflows/principals/recoverCurrentOrganizationPolicy.js +33 -0
  232. package/workflows/principals/recoverCurrentOrganizationPolicy.js.map +1 -0
  233. package/workflows/principals/recoverPrincipalHistoryPage.js +30 -0
  234. package/workflows/principals/recoverPrincipalHistoryPage.js.map +1 -0
  235. package/workflows/principals/recoverPrincipalPolicyHistory.d.ts +2 -0
  236. package/workflows/principals/recoverPrincipalPolicyHistory.js +14 -2
  237. package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
  238. package/workflows/principals/recoverScopedPrincipalPolicyHistory.d.ts +8 -1
  239. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +30 -20
  240. package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
  241. package/workflows/principals/runtimePolicyRecovery.js +36 -9
  242. package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
  243. package/workflows/principals/runtimePolicyWarmer.js +2 -2
  244. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
@@ -0,0 +1,53 @@
1
+ import { KeyingVerificationError, } from "../../internal/crypto/index.js";
2
+ import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
3
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
4
+ import { principalHeadMatchesReference } from "../../data/principals/organizationAuthorityDescriptor.js";
5
+ import { loadCurrentOrganizationAuthority } from "./currentOrganizationAuthority.js";
6
+ import { assertMetadataRootBinding } from "./groupMetadataRootBinding.js";
7
+ /** Authenticate metadata-root grants with current policies and only its cited predecessors. */
8
+ export function createCurrentGroupMetadataContainerVerifier(input) {
9
+ return async (state, organizationReference) => {
10
+ assertProjectionVerificationCurrent(input.stillCurrent);
11
+ const authority = await loadCurrentOrganizationAuthority({
12
+ ...input,
13
+ organizationReference,
14
+ });
15
+ await createSelectedCurrentGroupMetadataContainerVerifier({
16
+ authority,
17
+ organizationId: input.organizationId,
18
+ stillCurrent: input.stillCurrent,
19
+ })(state, organizationReference);
20
+ };
21
+ }
22
+ /** Reuse one mutation's verified authority without broadening its lease or scope. */
23
+ export function createSelectedCurrentGroupMetadataContainerVerifier(input) {
24
+ return async (state, organizationReference) => {
25
+ const { authority } = input;
26
+ const stillCurrent = () => input.stillCurrent() && authority.stillCurrent();
27
+ assertProjectionVerificationCurrent(stillCurrent);
28
+ if (organizationReference) {
29
+ if (organizationReference.principalType !== "organization" ||
30
+ organizationReference.principalId !== input.organizationId)
31
+ throw new KeyingVerificationError("object_mismatch", "Current policy reference is outside its scope");
32
+ if (!principalHeadMatchesReference(authority.directory.policy.state, organizationReference))
33
+ throw new ProjectionDependencyUnavailableError("Metadata root belongs to a changed organization directory");
34
+ }
35
+ const { adminGroupId, memberGroupId } = authority.descriptor;
36
+ const citation = (groupId) => state.referencedPrincipalHeads.find((head) => head.principalType === "group" && head.principalId === groupId);
37
+ const admins = await authority.readGroup(adminGroupId, citation(adminGroupId));
38
+ const members = await authority.readGroup(memberGroupId, citation(memberGroupId));
39
+ assertMetadataRootBinding({
40
+ organizationId: input.organizationId,
41
+ authority: {
42
+ descriptor: authority.descriptor,
43
+ adminGroupId,
44
+ memberGroupId,
45
+ adminPolicy: admins.policy,
46
+ },
47
+ members,
48
+ state,
49
+ });
50
+ assertProjectionVerificationCurrent(() => stillCurrent() && admins.stillCurrent() && members.stillCurrent());
51
+ };
52
+ }
53
+ //# sourceMappingURL=currentGroupMetadataAuthority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentGroupMetadataAuthority.js","sourceRoot":"","sources":["currentGroupMetadataAuthority.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,uBAAuB,GAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AAEvE,+FAA+F;AAC/F,MAAM,UAAU,2CAA2C,CACzD,KAGC;IAED,OAAO,KAAK,EACV,KAAmC,EACnC,qBAA+C,EAChC,EAAE;QACjB,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,SAAS,GAAG,MAAM,gCAAgC,CAAC;YACvD,GAAG,KAAK;YACR,qBAAqB;SACtB,CAAC,CAAC;QACH,MAAM,mDAAmD,CAAC;YACxD,SAAS;YACT,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IACnC,CAAC,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mDAAmD,CAAC,KAMnE;IACC,OAAO,KAAK,EACV,KAAmC,EACnC,qBAA+C,EAChC,EAAE;QACjB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAC5B,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;QAC5E,mCAAmC,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,qBAAqB,EAAE,CAAC;YAC1B,IACE,qBAAqB,CAAC,aAAa,KAAK,cAAc;gBACtD,qBAAqB,CAAC,WAAW,KAAK,KAAK,CAAC,cAAc;gBAE1D,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,+CAA+C,CAChD,CAAC;YACJ,IACE,CAAC,6BAA6B,CAC5B,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAChC,qBAAqB,CACtB;gBAED,MAAM,IAAI,oCAAoC,CAC5C,2DAA2D,CAC5D,CAAC;QACN,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC;QAC7D,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAE,EAAE,CACnC,KAAK,CAAC,wBAAwB,CAAC,IAAI,CACjC,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,aAAa,KAAK,OAAO,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,CACjE,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,SAAS,CACtC,YAAY,EACZ,QAAQ,CAAC,YAAY,CAAC,CACvB,CAAC;QACF,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,SAAS,CACvC,aAAa,EACb,QAAQ,CAAC,aAAa,CAAC,CACxB,CAAC;QACF,yBAAyB,CAAC;YACxB,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,SAAS,EAAE;gBACT,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,YAAY;gBACZ,aAAa;gBACb,WAAW,EAAE,MAAM,CAAC,MAAM;aAC3B;YACD,OAAO;YACP,KAAK;SACN,CAAC,CAAC;QACH,mCAAmC,CACjC,GAAG,EAAE,CAAC,YAAY,EAAE,IAAI,MAAM,CAAC,YAAY,EAAE,IAAI,OAAO,CAAC,YAAY,EAAE,CACxE,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import {\n type ContainerAccessManifestState,\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { principalHeadMatchesReference } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { loadCurrentOrganizationAuthority } from \"./currentOrganizationAuthority\";\nimport { assertMetadataRootBinding } from \"./groupMetadataRootBinding\";\n\n/** Authenticate metadata-root grants with current policies and only its cited predecessors. */\nexport function createCurrentGroupMetadataContainerVerifier(\n input: Omit<\n Parameters<typeof loadCurrentOrganizationAuthority>[0],\n \"organizationReference\"\n >,\n) {\n return async (\n state: ContainerAccessManifestState,\n organizationReference?: ReferencedPrincipalHead,\n ): Promise<void> => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const authority = await loadCurrentOrganizationAuthority({\n ...input,\n organizationReference,\n });\n await createSelectedCurrentGroupMetadataContainerVerifier({\n authority,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n })(state, organizationReference);\n };\n}\n\n/** Reuse one mutation's verified authority without broadening its lease or scope. */\nexport function createSelectedCurrentGroupMetadataContainerVerifier(input: {\n readonly authority: Awaited<\n ReturnType<typeof loadCurrentOrganizationAuthority>\n >;\n readonly organizationId: string;\n readonly stillCurrent: () => boolean;\n}) {\n return async (\n state: ContainerAccessManifestState,\n organizationReference?: ReferencedPrincipalHead,\n ): Promise<void> => {\n const { authority } = input;\n const stillCurrent = () => input.stillCurrent() && authority.stillCurrent();\n assertProjectionVerificationCurrent(stillCurrent);\n if (organizationReference) {\n if (\n organizationReference.principalType !== \"organization\" ||\n organizationReference.principalId !== input.organizationId\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Current policy reference is outside its scope\",\n );\n if (\n !principalHeadMatchesReference(\n authority.directory.policy.state,\n organizationReference,\n )\n )\n throw new ProjectionDependencyUnavailableError(\n \"Metadata root belongs to a changed organization directory\",\n );\n }\n const { adminGroupId, memberGroupId } = authority.descriptor;\n const citation = (groupId: string) =>\n state.referencedPrincipalHeads.find(\n (head) =>\n head.principalType === \"group\" && head.principalId === groupId,\n );\n const admins = await authority.readGroup(\n adminGroupId,\n citation(adminGroupId),\n );\n const members = await authority.readGroup(\n memberGroupId,\n citation(memberGroupId),\n );\n assertMetadataRootBinding({\n organizationId: input.organizationId,\n authority: {\n descriptor: authority.descriptor,\n adminGroupId,\n memberGroupId,\n adminPolicy: admins.policy,\n },\n members,\n state,\n });\n assertProjectionVerificationCurrent(\n () => stillCurrent() && admins.stillCurrent() && members.stillCurrent(),\n );\n };\n}\n"]}
@@ -0,0 +1,35 @@
1
+ import { selectPrincipalPolicyCurrentPredecessorReferences, } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ /** Select only this path's old citations, preserving the authored membership. */
4
+ export async function resolveCurrentGroupMutationReferences(input) {
5
+ assertProjectionVerificationCurrent(input.stillCurrent);
6
+ const references = structuredClone(input.references);
7
+ const select = (current, predecessor, selected) => selectPrincipalPolicyCurrentPredecessorReferences({
8
+ current,
9
+ predecessor,
10
+ references: selected,
11
+ });
12
+ // Normalize and bound the entire request before any per-reference I/O.
13
+ const initial = select(input.current, input.predecessor, references);
14
+ if (initial.ok)
15
+ return initial.value;
16
+ if (initial.error.code !== "missing_dependency")
17
+ throw initial.error;
18
+ let current = input.current;
19
+ const selected = [];
20
+ for (const reference of references) {
21
+ assertProjectionVerificationCurrent(input.stillCurrent);
22
+ selected.push(reference);
23
+ let result = select(current, input.predecessor, selected);
24
+ if (!result.ok && result.error.code === "missing_dependency") {
25
+ const predecessor = await input.readPredecessorReference(reference);
26
+ assertProjectionVerificationCurrent(input.stillCurrent);
27
+ result = select(current, predecessor, selected);
28
+ }
29
+ if (!result.ok)
30
+ throw result.error;
31
+ current = result.value;
32
+ }
33
+ return current;
34
+ }
35
+ //# sourceMappingURL=currentGroupMutationReferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentGroupMutationReferences.js","sourceRoot":"","sources":["currentGroupMutationReferences.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iDAAiD,GAElD,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AAEpG,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,qCAAqC,CAAC,KAQ3D;IACC,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,CACb,OAAuC,EACvC,WAA2C,EAC3C,QAA4C,EAC5C,EAAE,CACF,iDAAiD,CAAC;QAChD,OAAO;QACP,WAAW;QACX,UAAU,EAAE,QAAQ;KACrB,CAAC,CAAC;IACL,uEAAuE;IACvE,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACrE,IAAI,OAAO,CAAC,EAAE;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC;IACrC,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB;QAAE,MAAM,OAAO,CAAC,KAAK,CAAC;IACrE,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC5B,MAAM,QAAQ,GAA8B,EAAE,CAAC;IAC/C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YAC7D,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;YACpE,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACxD,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,MAAM,CAAC,KAAK,CAAC;QACnC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;IACzB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import {\n type ReferencedPrincipalHead,\n selectPrincipalPolicyCurrentPredecessorReferences,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\n\n/** Select only this path's old citations, preserving the authored membership. */\nexport async function resolveCurrentGroupMutationReferences(input: {\n readonly current: VerifiedPrincipalPolicyCurrent;\n readonly predecessor: VerifiedPrincipalPolicyCurrent;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly readPredecessorReference: (\n reference: ReferencedPrincipalHead,\n ) => Promise<VerifiedPrincipalPolicyCurrent>;\n readonly stillCurrent: () => boolean;\n}): Promise<VerifiedPrincipalPolicyCurrent> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const references = structuredClone(input.references);\n const select = (\n current: VerifiedPrincipalPolicyCurrent,\n predecessor: VerifiedPrincipalPolicyCurrent,\n selected: readonly ReferencedPrincipalHead[],\n ) =>\n selectPrincipalPolicyCurrentPredecessorReferences({\n current,\n predecessor,\n references: selected,\n });\n // Normalize and bound the entire request before any per-reference I/O.\n const initial = select(input.current, input.predecessor, references);\n if (initial.ok) return initial.value;\n if (initial.error.code !== \"missing_dependency\") throw initial.error;\n let current = input.current;\n const selected: ReferencedPrincipalHead[] = [];\n for (const reference of references) {\n assertProjectionVerificationCurrent(input.stillCurrent);\n selected.push(reference);\n let result = select(current, input.predecessor, selected);\n if (!result.ok && result.error.code === \"missing_dependency\") {\n const predecessor = await input.readPredecessorReference(reference);\n assertProjectionVerificationCurrent(input.stillCurrent);\n result = select(current, predecessor, selected);\n }\n if (!result.ok) throw result.error;\n current = result.value;\n }\n return current;\n}\n"]}
@@ -0,0 +1,79 @@
1
+ import { serializeKeyingCanonicalJson, } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ import { advanceKeyingCheckpointsAtomically } from "../../data/persistence/keyingCheckpointAdvancePersistence.js";
4
+ import { requireOrganizationGroupHead } from "../../data/principals/organizationAuthorityDescriptor.js";
5
+ import { createSelectedCurrentGroupMetadataContainerVerifier } from "./currentGroupMetadataAuthority.js";
6
+ import { loadCurrentOrganizationMutationAuthority } from "./currentOrganizationMutationAuthority.js";
7
+ import { assertGroupMetadataBinding } from "./groupMetadataBinding.js";
8
+ import { requireSignerCanManageGroup } from "./groupMutationAuthorization.js";
9
+ /** Exact current directory, strict Admins and group evidence for one mutation. */
10
+ export async function loadCurrentGroupPolicyMutationContext(input) {
11
+ input = { ...input };
12
+ const { authority, currentOrgAdminUserIds } = await loadCurrentOrganizationMutationAuthority(input);
13
+ const group = await authority.readGroup(input.groupId);
14
+ const stillCurrent = () => input.stillCurrent() && authority.stillCurrent() && group.stillCurrent();
15
+ assertProjectionVerificationCurrent(stillCurrent);
16
+ assertGroupMetadataBinding(group.current, authority.descriptor);
17
+ requireSignerCanManageGroup(group.current, currentOrgAdminUserIds, input.signerUserId);
18
+ await advanceKeyingCheckpointsAtomically({
19
+ access: [],
20
+ execSql: input.execSql,
21
+ organizationId: input.organizationId,
22
+ policies: [...group.dependencies, group.policy],
23
+ stillCurrent,
24
+ });
25
+ assertProjectionVerificationCurrent(stillCurrent);
26
+ const adminHead = requireOrganizationGroupHead(authority.descriptor, authority.descriptor.adminGroupId);
27
+ const externalAuthority = {
28
+ currentHead: adminHead,
29
+ states: [
30
+ { head: adminHead, projection: authority.admins.policy.projection },
31
+ ],
32
+ };
33
+ const references = new Map();
34
+ return {
35
+ adminGroupId: authority.descriptor.adminGroupId,
36
+ adminCurrent: authority.admins,
37
+ currentPolicy: group.current,
38
+ verifiedCurrentPolicy: group.policy,
39
+ verifyMetadataContainer: createSelectedCurrentGroupMetadataContainerVerifier({
40
+ authority,
41
+ organizationId: input.organizationId,
42
+ stillCurrent,
43
+ }),
44
+ currentOrgAdminUserIds,
45
+ externalAuthority,
46
+ isOrganizationAdminsGroup: input.groupId === authority.descriptor.adminGroupId,
47
+ localPolicyCheckpoint: group.policy.checkpoint,
48
+ memberGroupId: authority.descriptor.memberGroupId,
49
+ organizationDescriptor: authority.descriptor,
50
+ organizationCurrent: authority.directory,
51
+ async readPredecessorReference(reference) {
52
+ assertProjectionVerificationCurrent(stillCurrent);
53
+ const owned = structuredClone(reference);
54
+ const key = serializeKeyingCanonicalJson({ ...owned });
55
+ let pending = references.get(key);
56
+ if (!pending) {
57
+ // Keep at most one bounded selection's citations, even across many paths.
58
+ if (references.size === 128) {
59
+ const oldest = references.keys().next().value;
60
+ if (oldest !== undefined)
61
+ references.delete(oldest);
62
+ }
63
+ pending = authority
64
+ .readGroup(input.groupId, owned)
65
+ .then((selected) => selected.policy);
66
+ references.set(key, pending);
67
+ }
68
+ const policy = await pending.catch((error) => {
69
+ if (references.get(key) === pending)
70
+ references.delete(key);
71
+ throw error;
72
+ });
73
+ assertProjectionVerificationCurrent(stillCurrent);
74
+ return policy;
75
+ },
76
+ stillCurrent,
77
+ };
78
+ }
79
+ //# sourceMappingURL=currentGroupPolicyMutationContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentGroupPolicyMutationContext.js","sourceRoot":"","sources":["currentGroupPolicyMutationContext.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type PrincipalPolicyExternalAuthority,\n type ReferencedPrincipalHead,\n serializeKeyingCanonicalJson,\n type VerifiedPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { advanceKeyingCheckpointsAtomically } from \"../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { requireOrganizationGroupHead } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { createRuntimePrincipalPolicyCurrentResolver } from \"../principals/runtimePolicyRecovery\";\nimport { createSelectedCurrentGroupMetadataContainerVerifier } from \"./currentGroupMetadataAuthority\";\nimport { loadCurrentOrganizationMutationAuthority } from \"./currentOrganizationMutationAuthority\";\nimport { assertGroupMetadataBinding } from \"./groupMetadataBinding\";\nimport { requireSignerCanManageGroup } from \"./groupMutationAuthorization\";\n\n/** Exact current directory, strict Admins and group evidence for one mutation. */\nexport async function loadCurrentGroupPolicyMutationContext(input: {\n readonly execSql: ExecSql;\n readonly groupId: string;\n readonly organizationId: string;\n readonly signerUserId: string;\n readonly resolveCurrentPolicy: NonNullable<\n ReturnType<typeof createRuntimePrincipalPolicyCurrentResolver>\n >;\n readonly recoverPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<void>;\n readonly stillCurrent: () => boolean;\n}) {\n input = { ...input };\n const { authority, currentOrgAdminUserIds } =\n await loadCurrentOrganizationMutationAuthority(input);\n const group = await authority.readGroup(input.groupId);\n const stillCurrent = () =>\n input.stillCurrent() && authority.stillCurrent() && group.stillCurrent();\n assertProjectionVerificationCurrent(stillCurrent);\n assertGroupMetadataBinding(group.current, authority.descriptor);\n requireSignerCanManageGroup(\n group.current,\n currentOrgAdminUserIds,\n input.signerUserId,\n );\n await advanceKeyingCheckpointsAtomically({\n access: [],\n execSql: input.execSql,\n organizationId: input.organizationId,\n policies: [...group.dependencies, group.policy],\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const adminHead = requireOrganizationGroupHead(\n authority.descriptor,\n authority.descriptor.adminGroupId,\n );\n const externalAuthority: PrincipalPolicyExternalAuthority = {\n currentHead: adminHead,\n states: [\n { head: adminHead, projection: authority.admins.policy.projection },\n ],\n };\n const references = new Map<string, Promise<VerifiedPrincipalPolicyCurrent>>();\n return {\n adminGroupId: authority.descriptor.adminGroupId,\n adminCurrent: authority.admins,\n currentPolicy: group.current,\n verifiedCurrentPolicy: group.policy,\n verifyMetadataContainer:\n createSelectedCurrentGroupMetadataContainerVerifier({\n authority,\n organizationId: input.organizationId,\n stillCurrent,\n }),\n currentOrgAdminUserIds,\n externalAuthority,\n isOrganizationAdminsGroup:\n input.groupId === authority.descriptor.adminGroupId,\n localPolicyCheckpoint: group.policy.checkpoint,\n memberGroupId: authority.descriptor.memberGroupId,\n organizationDescriptor: authority.descriptor,\n organizationCurrent: authority.directory,\n async readPredecessorReference(reference: ReferencedPrincipalHead) {\n assertProjectionVerificationCurrent(stillCurrent);\n const owned = structuredClone(reference);\n const key = serializeKeyingCanonicalJson({ ...owned });\n let pending = references.get(key);\n if (!pending) {\n // Keep at most one bounded selection's citations, even across many paths.\n if (references.size === 128) {\n const oldest = references.keys().next().value;\n if (oldest !== undefined) references.delete(oldest);\n }\n pending = authority\n .readGroup(input.groupId, owned)\n .then((selected) => selected.policy);\n references.set(key, pending);\n }\n const policy = await pending.catch((error: unknown) => {\n if (references.get(key) === pending) references.delete(key);\n throw error;\n });\n assertProjectionVerificationCurrent(stillCurrent);\n return policy;\n },\n stillCurrent,\n };\n}\n"]}
@@ -0,0 +1,88 @@
1
+ import { KeyingVerificationError, } from "../../internal/crypto/index.js";
2
+ import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
3
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
4
+ import { validateKeyingCheckpointsAtomically } from "../../data/persistence/keyingCheckpointAdvancePersistence.js";
5
+ import { assertCurrentMatchesVerifiedPolicy } from "../../data/persistence/verifiedPrincipalPolicyCurrent.js";
6
+ import { parseOrganizationAuthorityDescriptor, principalHeadMatchesReference, requireOrganizationGroupHead, } from "../../data/principals/organizationAuthorityDescriptor.js";
7
+ /** One directory view with bounded, authenticated current artifacts for its groups. */
8
+ export async function loadCurrentOrganizationAuthority(input) {
9
+ if (input.organizationReference)
10
+ assertReferenceScope(input.organizationReference, "organization", input.organizationId);
11
+ const recoveryBatch = input.recoveryBatch ?? {};
12
+ const resolve = (reference) => input.resolveCurrentPolicy({
13
+ organizationId: input.organizationId,
14
+ reference: reference ?? undefined,
15
+ preferLocalCurrent: true,
16
+ recoveryBatch,
17
+ stillCurrent: input.stillCurrent,
18
+ });
19
+ const directory = await resolve(input.organizationReference);
20
+ await assertExactCurrent(directory, input.organizationReference ?? directory.policy.state);
21
+ const descriptor = parseOrganizationAuthorityDescriptor(directory.current.currentPayload.ciphertext);
22
+ if (descriptor.organizationId !== input.organizationId)
23
+ throw new KeyingVerificationError("object_mismatch", "Organization current policy payload is outside its scope");
24
+ const adminHead = requireOrganizationGroupHead(descriptor, descriptor.adminGroupId);
25
+ const admins = await resolve(adminHead);
26
+ await assertExactCurrent(admins, adminHead);
27
+ assertDirectoryDependency(admins, directory);
28
+ const stillCurrent = () => input.stillCurrent() && directory.stillCurrent() && admins.stillCurrent();
29
+ const validate = async (value) => {
30
+ assertProjectionVerificationCurrent(stillCurrent);
31
+ await validateKeyingCheckpointsAtomically({
32
+ access: [],
33
+ execSql: input.execSql,
34
+ policies: [...value.dependencies, value.policy],
35
+ stillCurrent: () => stillCurrent() && value.stillCurrent(),
36
+ });
37
+ assertProjectionVerificationCurrent(() => stillCurrent() && value.stillCurrent());
38
+ };
39
+ await validate(admins);
40
+ return {
41
+ admins,
42
+ descriptor,
43
+ directory,
44
+ stillCurrent,
45
+ async readGroup(groupId, reference) {
46
+ assertProjectionVerificationCurrent(stillCurrent);
47
+ const head = requireOrganizationGroupHead(descriptor, groupId);
48
+ const selected = reference ?? head;
49
+ assertReferenceScope(selected, "group", groupId);
50
+ const result = groupId === descriptor.adminGroupId &&
51
+ principalHeadMatchesReference(admins.policy.state, selected)
52
+ ? admins
53
+ : await resolve(selected);
54
+ await assertExactCurrent(result, head);
55
+ assertDirectoryDependency(result, directory);
56
+ if (groupId !== descriptor.adminGroupId)
57
+ assertAdminsDependency(result, adminHead);
58
+ await validate(result);
59
+ return result;
60
+ },
61
+ };
62
+ }
63
+ function assertReferenceScope(reference, principalType, principalId) {
64
+ if (reference.principalType !== principalType ||
65
+ reference.principalId !== principalId)
66
+ throw new KeyingVerificationError("object_mismatch", "Current policy reference is outside its scope");
67
+ }
68
+ async function assertExactCurrent(value, expected) {
69
+ assertProjectionVerificationCurrent(value.stillCurrent);
70
+ await assertCurrentMatchesVerifiedPolicy(value);
71
+ if (!principalHeadMatchesReference(value.policy.state, expected))
72
+ throw new ProjectionDependencyUnavailableError("Current policy changed from the selected organization directory");
73
+ assertProjectionVerificationCurrent(value.stillCurrent);
74
+ }
75
+ function assertDirectoryDependency(value, directory) {
76
+ const dependency = value.dependencies.find((policy) => policy.principalType === "organization" &&
77
+ policy.principalId === directory.policy.principalId);
78
+ if (!dependency ||
79
+ !principalHeadMatchesReference(dependency.state, directory.policy.state))
80
+ throw new ProjectionDependencyUnavailableError("Current policy belongs to a changed organization directory");
81
+ }
82
+ function assertAdminsDependency(value, expected) {
83
+ const authority = value.dependencies.find((policy) => policy.principalType === "group" &&
84
+ policy.principalId === expected.principalId);
85
+ if (!authority || !principalHeadMatchesReference(authority.state, expected))
86
+ throw new KeyingVerificationError("missing_dependency", "Current group policy omits its exact Admins dependency");
87
+ }
88
+ //# sourceMappingURL=currentOrganizationAuthority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentOrganizationAuthority.js","sourceRoot":"","sources":["currentOrganizationAuthority.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { validateKeyingCheckpointsAtomically } from \"../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { assertCurrentMatchesVerifiedPolicy } from \"../../data/persistence/verifiedPrincipalPolicyCurrent\";\nimport {\n parseOrganizationAuthorityDescriptor,\n principalHeadMatchesReference,\n requireOrganizationGroupHead,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type {\n createRuntimePrincipalPolicyCurrentResolver,\n ResolvedPrincipalPolicyCurrent,\n} from \"../principals/runtimePolicyRecovery\";\n\ntype CurrentPolicyResolver = NonNullable<\n ReturnType<typeof createRuntimePrincipalPolicyCurrentResolver>\n>;\n\ninterface CurrentOrganizationAuthorityInput {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly organizationReference?: ReferencedPrincipalHead | null | undefined;\n readonly resolveCurrentPolicy: CurrentPolicyResolver;\n readonly recoveryBatch?: object | undefined;\n readonly stillCurrent: () => boolean;\n}\n\n/** One directory view with bounded, authenticated current artifacts for its groups. */\nexport async function loadCurrentOrganizationAuthority(\n input: CurrentOrganizationAuthorityInput,\n) {\n if (input.organizationReference)\n assertReferenceScope(\n input.organizationReference,\n \"organization\",\n input.organizationId,\n );\n const recoveryBatch = input.recoveryBatch ?? {};\n const resolve = (reference?: ReferencedPrincipalHead | null) =>\n input.resolveCurrentPolicy({\n organizationId: input.organizationId,\n reference: reference ?? undefined,\n preferLocalCurrent: true,\n recoveryBatch,\n stillCurrent: input.stillCurrent,\n });\n const directory = await resolve(input.organizationReference);\n await assertExactCurrent(\n directory,\n input.organizationReference ?? directory.policy.state,\n );\n const descriptor = parseOrganizationAuthorityDescriptor(\n directory.current.currentPayload.ciphertext,\n );\n if (descriptor.organizationId !== input.organizationId)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Organization current policy payload is outside its scope\",\n );\n const adminHead = requireOrganizationGroupHead(\n descriptor,\n descriptor.adminGroupId,\n );\n const admins = await resolve(adminHead);\n await assertExactCurrent(admins, adminHead);\n assertDirectoryDependency(admins, directory);\n const stillCurrent = () =>\n input.stillCurrent() && directory.stillCurrent() && admins.stillCurrent();\n const validate = async (value: ResolvedPrincipalPolicyCurrent) => {\n assertProjectionVerificationCurrent(stillCurrent);\n await validateKeyingCheckpointsAtomically({\n access: [],\n execSql: input.execSql,\n policies: [...value.dependencies, value.policy],\n stillCurrent: () => stillCurrent() && value.stillCurrent(),\n });\n assertProjectionVerificationCurrent(\n () => stillCurrent() && value.stillCurrent(),\n );\n };\n await validate(admins);\n return {\n admins,\n descriptor,\n directory,\n stillCurrent,\n async readGroup(groupId: string, reference?: ReferencedPrincipalHead) {\n assertProjectionVerificationCurrent(stillCurrent);\n const head = requireOrganizationGroupHead(descriptor, groupId);\n const selected = reference ?? head;\n assertReferenceScope(selected, \"group\", groupId);\n const result =\n groupId === descriptor.adminGroupId &&\n principalHeadMatchesReference(admins.policy.state, selected)\n ? admins\n : await resolve(selected);\n await assertExactCurrent(result, head);\n assertDirectoryDependency(result, directory);\n if (groupId !== descriptor.adminGroupId)\n assertAdminsDependency(result, adminHead);\n await validate(result);\n return result;\n },\n };\n}\n\nfunction assertReferenceScope(\n reference: ReferencedPrincipalHead,\n principalType: ReferencedPrincipalHead[\"principalType\"],\n principalId: string,\n) {\n if (\n reference.principalType !== principalType ||\n reference.principalId !== principalId\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Current policy reference is outside its scope\",\n );\n}\n\nasync function assertExactCurrent(\n value: ResolvedPrincipalPolicyCurrent,\n expected: ReferencedPrincipalHead,\n) {\n assertProjectionVerificationCurrent(value.stillCurrent);\n await assertCurrentMatchesVerifiedPolicy(value);\n if (!principalHeadMatchesReference(value.policy.state, expected))\n throw new ProjectionDependencyUnavailableError(\n \"Current policy changed from the selected organization directory\",\n );\n assertProjectionVerificationCurrent(value.stillCurrent);\n}\n\nfunction assertDirectoryDependency(\n value: ResolvedPrincipalPolicyCurrent,\n directory: ResolvedPrincipalPolicyCurrent,\n) {\n const dependency = value.dependencies.find(\n (policy) =>\n policy.principalType === \"organization\" &&\n policy.principalId === directory.policy.principalId,\n );\n if (\n !dependency ||\n !principalHeadMatchesReference(dependency.state, directory.policy.state)\n )\n throw new ProjectionDependencyUnavailableError(\n \"Current policy belongs to a changed organization directory\",\n );\n}\n\nfunction assertAdminsDependency(\n value: ResolvedPrincipalPolicyCurrent,\n expected: ReferencedPrincipalHead,\n) {\n const authority = value.dependencies.find(\n (policy) =>\n policy.principalType === \"group\" &&\n policy.principalId === expected.principalId,\n );\n if (!authority || !principalHeadMatchesReference(authority.state, expected))\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Current group policy omits its exact Admins dependency\",\n );\n}\n"]}
@@ -0,0 +1,72 @@
1
+ import { KeyingVerificationError } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ import { advanceKeyingCheckpointsAtomically } from "../../data/persistence/keyingCheckpointAdvancePersistence.js";
4
+ import { saveOrganizationGroupDisplayNames } from "../../data/persistence/organizations/organizationGroupNamePersistence.js";
5
+ import { loadCurrentOrganizationAuthority } from "./currentOrganizationAuthority.js";
6
+ import { GroupMetadataUnreadableError } from "./groupMetadataAccess.js";
7
+ import { assertGroupMetadataBinding } from "./groupMetadataBinding.js";
8
+ import { readGroupPolicyPayloadName, } from "./principalPolicyRequest.js";
9
+ /** Names consume verified current artifacts; paged recovery retains their separate evidence. */
10
+ export async function hydrateCurrentOrganizationGroupNames(input) {
11
+ const authority = await loadCurrentOrganizationAuthority(input);
12
+ const nameInput = {
13
+ ...input,
14
+ readEncryptedName: input.createCurrentNameReader?.(authority) ?? input.readEncryptedName,
15
+ };
16
+ const names = [];
17
+ const unreadable = new Set();
18
+ const lifetimes = [authority.stillCurrent];
19
+ for (const group of input.directory.groups) {
20
+ const head = authority.descriptor.groupHeads.find((head) => head.principalId === group.groupId);
21
+ if (!head || head.stateHash !== group.currentState?.stateHash)
22
+ throw new Error("Group listing does not match the signed directory");
23
+ const verified = await authority.readGroup(group.groupId);
24
+ lifetimes.push(verified.stillCurrent);
25
+ assertGroupMetadataBinding(verified.current, authority.descriptor);
26
+ const name = await readCurrentGroupName(nameInput, verified.current);
27
+ if (name === null)
28
+ unreadable.add(group.groupId);
29
+ else
30
+ names.push({ groupId: group.groupId, name, stateHash: head.stateHash });
31
+ }
32
+ const stillCurrent = () => input.stillCurrent() && lifetimes.every((current) => current());
33
+ assertProjectionVerificationCurrent(stillCurrent);
34
+ // Match the authority admission performed by the full-bundle path. Group
35
+ // name reads alone do not move group checkpoints.
36
+ await advanceKeyingCheckpointsAtomically({
37
+ access: [],
38
+ execSql: input.execSql,
39
+ organizationId: input.organizationId,
40
+ policies: [authority.directory.policy, authority.admins.policy],
41
+ stillCurrent,
42
+ });
43
+ await saveOrganizationGroupDisplayNames({ ...input, names, stillCurrent });
44
+ assertProjectionVerificationCurrent(stillCurrent);
45
+ const byId = new Map(names.map((entry) => [entry.groupId, entry.name]));
46
+ return {
47
+ ...input.directory,
48
+ groups: input.directory.groups.map((group) => ({
49
+ ...group,
50
+ name: byId.get(group.groupId) ?? "",
51
+ nameUnreadable: unreadable.has(group.groupId),
52
+ })),
53
+ };
54
+ }
55
+ async function readCurrentGroupName(input, current) {
56
+ try {
57
+ return await readGroupPolicyPayloadName(current, input.readEncryptedName);
58
+ }
59
+ catch (error) {
60
+ if (!(error instanceof GroupMetadataUnreadableError))
61
+ throw error;
62
+ await input.reportSecurityIncident(new KeyingVerificationError("invalid_shape", "Signed group name does not open under the cited metadata key"), {
63
+ evidenceHashes: { stateHash: current.currentState.stateHash },
64
+ objectId: current.currentState.principalId,
65
+ objectKind: "principal",
66
+ operation: "organization.groupName",
67
+ organizationId: input.organizationId,
68
+ });
69
+ return null;
70
+ }
71
+ }
72
+ //# sourceMappingURL=currentOrganizationGroupNames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentOrganizationGroupNames.js","sourceRoot":"","sources":["currentOrganizationGroupNames.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { advanceKeyingCheckpointsAtomically } from \"../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { saveOrganizationGroupDisplayNames } from \"../../data/persistence/organizations/organizationGroupNamePersistence\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport { loadCurrentOrganizationAuthority } from \"./currentOrganizationAuthority\";\nimport { GroupMetadataUnreadableError } from \"./groupMetadataAccess\";\nimport { assertGroupMetadataBinding } from \"./groupMetadataBinding\";\nimport {\n type GroupPolicyNameReader,\n readGroupPolicyPayloadName,\n} from \"./principalPolicyRequest\";\nimport type { OrganizationDirectoryAndGroups } from \"./readModel\";\n\ntype Input = Parameters<typeof loadCurrentOrganizationAuthority>[0] & {\n readonly directory: OrganizationDirectoryAndGroups;\n readonly readEncryptedName?: GroupPolicyNameReader | undefined;\n readonly createCurrentNameReader?:\n | ((\n authority: Awaited<ReturnType<typeof loadCurrentOrganizationAuthority>>,\n ) => GroupPolicyNameReader)\n | undefined;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n};\n\n/** Names consume verified current artifacts; paged recovery retains their separate evidence. */\nexport async function hydrateCurrentOrganizationGroupNames(\n input: Input,\n): Promise<OrganizationDirectoryAndGroups> {\n const authority = await loadCurrentOrganizationAuthority(input);\n const nameInput = {\n ...input,\n readEncryptedName:\n input.createCurrentNameReader?.(authority) ?? input.readEncryptedName,\n };\n const names: { groupId: string; name: string; stateHash: string }[] = [];\n const unreadable = new Set<string>();\n const lifetimes: (() => boolean)[] = [authority.stillCurrent];\n for (const group of input.directory.groups) {\n const head = authority.descriptor.groupHeads.find(\n (head) => head.principalId === group.groupId,\n );\n if (!head || head.stateHash !== group.currentState?.stateHash)\n throw new Error(\"Group listing does not match the signed directory\");\n const verified = await authority.readGroup(group.groupId);\n lifetimes.push(verified.stillCurrent);\n assertGroupMetadataBinding(verified.current, authority.descriptor);\n const name = await readCurrentGroupName(nameInput, verified.current);\n if (name === null) unreadable.add(group.groupId);\n else\n names.push({ groupId: group.groupId, name, stateHash: head.stateHash });\n }\n const stillCurrent = () =>\n input.stillCurrent() && lifetimes.every((current) => current());\n assertProjectionVerificationCurrent(stillCurrent);\n // Match the authority admission performed by the full-bundle path. Group\n // name reads alone do not move group checkpoints.\n await advanceKeyingCheckpointsAtomically({\n access: [],\n execSql: input.execSql,\n organizationId: input.organizationId,\n policies: [authority.directory.policy, authority.admins.policy],\n stillCurrent,\n });\n await saveOrganizationGroupDisplayNames({ ...input, names, stillCurrent });\n assertProjectionVerificationCurrent(stillCurrent);\n const byId = new Map(names.map((entry) => [entry.groupId, entry.name]));\n return {\n ...input.directory,\n groups: input.directory.groups.map((group) => ({\n ...group,\n name: byId.get(group.groupId) ?? \"\",\n nameUnreadable: unreadable.has(group.groupId),\n })),\n };\n}\n\nasync function readCurrentGroupName(\n input: Input,\n current: Parameters<GroupPolicyNameReader>[0],\n) {\n try {\n return await readGroupPolicyPayloadName(current, input.readEncryptedName);\n } catch (error) {\n if (!(error instanceof GroupMetadataUnreadableError)) throw error;\n await input.reportSecurityIncident(\n new KeyingVerificationError(\n \"invalid_shape\",\n \"Signed group name does not open under the cited metadata key\",\n ),\n {\n evidenceHashes: { stateHash: current.currentState.stateHash },\n objectId: current.currentState.principalId,\n objectKind: \"principal\",\n operation: \"organization.groupName\",\n organizationId: input.organizationId,\n },\n );\n return null;\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
2
+ import { organizationAdminSignerUserIds } from "../../data/principals/principalPolicyAdminSigners.js";
3
+ import { loadCurrentOrganizationAuthority } from "./currentOrganizationAuthority.js";
4
+ /** Resolve uncertain work and verify the signing administrator before any mutation pins. */
5
+ export async function loadCurrentOrganizationMutationAuthority(input) {
6
+ const owned = { ...input };
7
+ assertProjectionVerificationCurrent(owned.stillCurrent);
8
+ await owned.recoverPendingPrincipalMutation(owned.organizationId);
9
+ assertProjectionVerificationCurrent(owned.stillCurrent);
10
+ const authority = await loadCurrentOrganizationAuthority(owned);
11
+ const currentOrgAdminUserIds = organizationAdminSignerUserIds(authority.admins.policy);
12
+ if (!currentOrgAdminUserIds.includes(owned.signerUserId))
13
+ throw new Error("Organization admin authority is required");
14
+ return { authority, currentOrgAdminUserIds };
15
+ }
16
+ //# sourceMappingURL=currentOrganizationMutationAuthority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentOrganizationMutationAuthority.js","sourceRoot":"","sources":["currentOrganizationMutationAuthority.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,8BAA8B,EAAE,MAAM,mDAAmD,CAAC;AACnG,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAElF,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAC5D,KAQC;IAED,MAAM,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;IAC3B,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,CAAC,+BAA+B,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAClE,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,gCAAgC,CAAC,KAAK,CAAC,CAAC;IAChE,MAAM,sBAAsB,GAAG,8BAA8B,CAC3D,SAAS,CAAC,MAAM,CAAC,MAAM,CACxB,CAAC;IACF,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,CAAC;AAC/C,CAAC","sourcesContent":["import { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { organizationAdminSignerUserIds } from \"../../data/principals/principalPolicyAdminSigners\";\nimport { loadCurrentOrganizationAuthority } from \"./currentOrganizationAuthority\";\n\n/** Resolve uncertain work and verify the signing administrator before any mutation pins. */\nexport async function loadCurrentOrganizationMutationAuthority(\n input: Omit<\n Parameters<typeof loadCurrentOrganizationAuthority>[0],\n \"organizationReference\"\n > & {\n readonly signerUserId: string;\n readonly recoverPendingPrincipalMutation: (\n organizationId: string,\n ) => Promise<void>;\n },\n) {\n const owned = { ...input };\n assertProjectionVerificationCurrent(owned.stillCurrent);\n await owned.recoverPendingPrincipalMutation(owned.organizationId);\n assertProjectionVerificationCurrent(owned.stillCurrent);\n const authority = await loadCurrentOrganizationAuthority(owned);\n const currentOrgAdminUserIds = organizationAdminSignerUserIds(\n authority.admins.policy,\n );\n if (!currentOrgAdminUserIds.includes(owned.signerUserId))\n throw new Error(\"Organization admin authority is required\");\n return { authority, currentOrgAdminUserIds };\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
2
+ import { scopedGroupHistoryProtection } from "../../data/principals/principalHistoryScopeProtection.js";
3
+ import { principalPolicyReferenceFromBundle } from "../../data/principals/principalPolicyAdminSigners.js";
4
+ import { retainAcknowledgedPrincipalCurrents, } from "./retainAcknowledgedPrincipalCurrents.js";
5
+ /** Couple directory acknowledgements to any newly created group under the same lease. */
6
+ export function createCurrentOrganizationMutationRetention(input) {
7
+ const retain = async (entries) => {
8
+ assertProjectionVerificationCurrent(input.stillCurrent);
9
+ await retainAcknowledgedPrincipalCurrents({
10
+ execSql: input.runtime.infra.execSql,
11
+ organizationId: input.organizationId,
12
+ entries,
13
+ stillCurrent: input.stillCurrent,
14
+ });
15
+ };
16
+ return {
17
+ retainDirectory: (request, response) => retain([{ request, response, recovery: input.directoryRecovery }]),
18
+ retainCreatedGroup: (receipt) => {
19
+ const adminHead = {
20
+ ...principalPolicyReferenceFromBundle(input.authority.admins.current),
21
+ principalType: "group",
22
+ };
23
+ return retain([
24
+ {
25
+ initialGroup: true,
26
+ request: receipt.request,
27
+ response: receipt.response,
28
+ recovery: {
29
+ apiClient: { getPrincipalPolicyPages: input.readPages },
30
+ expectedHead: principalPolicyReferenceFromBundle(receipt.response),
31
+ protection: scopedGroupHistoryProtection(input.protection, input.organizationId, input.authority.descriptor.adminGroupId),
32
+ resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
33
+ loadExternalAuthority: async () => ({
34
+ currentHead: adminHead,
35
+ states: [
36
+ {
37
+ head: adminHead,
38
+ projection: input.authority.admins.policy.projection,
39
+ },
40
+ ],
41
+ }),
42
+ },
43
+ },
44
+ {
45
+ request: receipt.organizationRequest,
46
+ response: receipt.organizationResponse,
47
+ recovery: input.directoryRecovery,
48
+ },
49
+ ]);
50
+ },
51
+ };
52
+ }
53
+ //# sourceMappingURL=currentOrganizationMutationRetention.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentOrganizationMutationRetention.js","sourceRoot":"","sources":["currentOrganizationMutationRetention.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,4BAA4B,EAAE,MAAM,uDAAuD,CAAC;AACrG,OAAO,EAAE,kCAAkC,EAAE,MAAM,mDAAmD,CAAC;AAGvG,OAAO,EAEL,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAE/C,yFAAyF;AACzF,MAAM,UAAU,0CAA0C,CAAC,KAU1D;IACC,MAAM,MAAM,GAAG,KAAK,EAClB,OAAqD,EACrD,EAAE;QACF,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,mCAAmC,CAAC;YACxC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACpC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,OAAO;YACP,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO;QACL,eAAe,EAAE,CACf,OAAkC,EAClC,QAAyC,EACzC,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACvE,kBAAkB,EAAE,CAAC,OAKpB,EAAE,EAAE;YACH,MAAM,SAAS,GAAG;gBAChB,GAAG,kCAAkC,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;gBACrE,aAAa,EAAE,OAAgB;aAChC,CAAC;YACF,OAAO,MAAM,CAAC;gBACZ;oBACE,YAAY,EAAE,IAAI;oBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE;wBACR,SAAS,EAAE,EAAE,uBAAuB,EAAE,KAAK,CAAC,SAAS,EAAE;wBACvD,YAAY,EAAE,kCAAkC,CAAC,OAAO,CAAC,QAAQ,CAAC;wBAClE,UAAU,EAAE,4BAA4B,CACtC,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CACxC;wBACD,0BAA0B,EACxB,KAAK,CAAC,OAAO,CAAC,0BAA0B;wBAC1C,qBAAqB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;4BAClC,WAAW,EAAE,SAAS;4BACtB,MAAM,EAAE;gCACN;oCACE,IAAI,EAAE,SAAS;oCACf,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU;iCACrD;6BACF;yBACF,CAAC;qBACH;iBACF;gBACD;oBACE,OAAO,EAAE,OAAO,CAAC,mBAAmB;oBACpC,QAAQ,EAAE,OAAO,CAAC,oBAAoB;oBACtC,QAAQ,EAAE,KAAK,CAAC,iBAAiB;iBAClC;aACF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { PrincipalPolicyHistoryProgressOptions } from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { scopedGroupHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { PrincipalPolicyRecoveryRuntime } from \"../principals/runtimePolicyRecovery\";\nimport type { loadCurrentOrganizationAuthority } from \"./currentOrganizationAuthority\";\nimport {\n type AcknowledgedPrincipalCurrentInput,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\n\n/** Couple directory acknowledgements to any newly created group under the same lease. */\nexport function createCurrentOrganizationMutationRetention(input: {\n readonly runtime: PrincipalPolicyRecoveryRuntime;\n readonly authority: Awaited<\n ReturnType<typeof loadCurrentOrganizationAuthority>\n >;\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly readPages: ApiClient[\"getPrincipalPolicyPages\"];\n readonly organizationId: string;\n readonly directoryRecovery: AcknowledgedPrincipalCurrentInput[\"recovery\"];\n readonly stillCurrent: () => boolean;\n}) {\n const retain = async (\n entries: readonly AcknowledgedPrincipalCurrentInput[],\n ) => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n await retainAcknowledgedPrincipalCurrents({\n execSql: input.runtime.infra.execSql,\n organizationId: input.organizationId,\n entries,\n stillCurrent: input.stillCurrent,\n });\n };\n return {\n retainDirectory: (\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n ) => retain([{ request, response, recovery: input.directoryRecovery }]),\n retainCreatedGroup: (receipt: {\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly organizationResponse: PrincipalPolicyMutationResponse;\n }) => {\n const adminHead = {\n ...principalPolicyReferenceFromBundle(input.authority.admins.current),\n principalType: \"group\" as const,\n };\n return retain([\n {\n initialGroup: true,\n request: receipt.request,\n response: receipt.response,\n recovery: {\n apiClient: { getPrincipalPolicyPages: input.readPages },\n expectedHead: principalPolicyReferenceFromBundle(receipt.response),\n protection: scopedGroupHistoryProtection(\n input.protection,\n input.organizationId,\n input.authority.descriptor.adminGroupId,\n ),\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n loadExternalAuthority: async () => ({\n currentHead: adminHead,\n states: [\n {\n head: adminHead,\n projection: input.authority.admins.policy.projection,\n },\n ],\n }),\n },\n },\n {\n request: receipt.organizationRequest,\n response: receipt.organizationResponse,\n recovery: input.directoryRecovery,\n },\n ]);\n },\n };\n}\n"]}
@@ -0,0 +1,65 @@
1
+ import { verifyPrincipalPolicyCheckpoint, verifyPrincipalPolicyCurrentSuccessor, } from "../../internal/crypto/index.js";
2
+ import { canonicalKeyingJsonString } from "../../data/keyingCanonicalJson.js";
3
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
4
+ import { assertPrincipalPolicyCurrentStateMatchesHead } from "./groupPolicyMutationHead.js";
5
+ /** Verify a single authored successor; this neither admits it nor persists a pin. */
6
+ export async function verifyCurrentPolicyMutation(input, acknowledgedState) {
7
+ const previous = input.verifiedCurrentPolicy;
8
+ const stillCurrent = input.stillCurrent;
9
+ const owned = structuredClone({
10
+ expectedHead: input.expectedHead,
11
+ request: input.request,
12
+ signerPublicKeys: input.signerPublicKeys,
13
+ externalAuthority: input.externalAuthority,
14
+ localPolicyCheckpoint: input.localPolicyCheckpoint,
15
+ acknowledgedState,
16
+ });
17
+ assertProjectionVerificationCurrent(stillCurrent);
18
+ const { request, expectedHead } = owned;
19
+ const state = owned.acknowledgedState ?? {
20
+ ...request.state,
21
+ stateHash: expectedHead.stateHash,
22
+ createdAt: request.state.signedAt,
23
+ };
24
+ if (owned.acknowledgedState) {
25
+ const { createdAt: _createdAt, stateHash, ...responseState } = state;
26
+ if (stateHash !== expectedHead.stateHash ||
27
+ canonicalKeyingJsonString(responseState, "stored group policy state") !==
28
+ canonicalKeyingJsonString(request.state, "authored group policy state"))
29
+ throw new Error("Group policy state acknowledgement mismatch");
30
+ }
31
+ const verified = await verifyPrincipalPolicyCurrentSuccessor({
32
+ previous,
33
+ signerPublicKeys: owned.signerPublicKeys,
34
+ externalAuthority: owned.externalAuthority,
35
+ current: {
36
+ currentState: state,
37
+ currentProjection: request.projection,
38
+ currentGrants: request.grants,
39
+ currentPayload: {
40
+ ...request.encryptedPayload,
41
+ principalId: state.principalId,
42
+ principalType: state.principalType,
43
+ stateHash: state.stateHash,
44
+ },
45
+ currentMemberEnvelopes: {
46
+ envelopes: request.memberEnvelopes,
47
+ principalId: state.principalId,
48
+ principalType: state.principalType,
49
+ stateHash: state.stateHash,
50
+ epoch: state.keyEpoch,
51
+ },
52
+ },
53
+ });
54
+ if (!verified.ok)
55
+ throw verified.error;
56
+ assertPrincipalPolicyCurrentStateMatchesHead(verified.value.state, expectedHead);
57
+ verifyPrincipalPolicyCheckpoint({
58
+ chain: verified.value.retainedHistory,
59
+ currentState: verified.value.state,
60
+ localCheckpoint: owned.localPolicyCheckpoint,
61
+ });
62
+ assertProjectionVerificationCurrent(stillCurrent);
63
+ return verified.value;
64
+ }
65
+ //# sourceMappingURL=currentPolicyMutationAcknowledgement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currentPolicyMutationAcknowledgement.js","sourceRoot":"","sources":["currentPolicyMutationAcknowledgement.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type PrincipalPolicyCheckpoint,\n type PrincipalPolicyExternalAuthority,\n type PrincipalPolicySignerPublicKey,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicyCurrent,\n verifyPrincipalPolicyCheckpoint,\n verifyPrincipalPolicyCurrentSuccessor,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalStateResponse } from \"@tearleads/validators/response\";\nimport { canonicalKeyingJsonString } from \"../../data/keyingCanonicalJson\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { assertPrincipalPolicyCurrentStateMatchesHead } from \"./groupPolicyMutationHead\";\n\nexport interface CurrentPolicyMutationInput {\n readonly currentPolicy?: never;\n readonly verifiedCurrentPolicy: VerifiedPrincipalPolicyCurrent;\n readonly expectedHead: ReferencedPrincipalHead;\n readonly request: PutPrincipalPolicyRequest;\n readonly signerPublicKeys: readonly PrincipalPolicySignerPublicKey[];\n readonly externalAuthority?: PrincipalPolicyExternalAuthority | undefined;\n readonly localPolicyCheckpoint?: PrincipalPolicyCheckpoint | null;\n readonly stillCurrent: () => boolean;\n}\n\n/** Verify a single authored successor; this neither admits it nor persists a pin. */\nexport async function verifyCurrentPolicyMutation(\n input: CurrentPolicyMutationInput,\n acknowledgedState?: PrincipalStateResponse,\n): Promise<VerifiedPrincipalPolicyCurrent> {\n const previous = input.verifiedCurrentPolicy;\n const stillCurrent = input.stillCurrent;\n const owned = structuredClone({\n expectedHead: input.expectedHead,\n request: input.request,\n signerPublicKeys: input.signerPublicKeys,\n externalAuthority: input.externalAuthority,\n localPolicyCheckpoint: input.localPolicyCheckpoint,\n acknowledgedState,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const { request, expectedHead } = owned;\n const state = owned.acknowledgedState ?? {\n ...request.state,\n stateHash: expectedHead.stateHash,\n createdAt: request.state.signedAt,\n };\n if (owned.acknowledgedState) {\n const { createdAt: _createdAt, stateHash, ...responseState } = state;\n if (\n stateHash !== expectedHead.stateHash ||\n canonicalKeyingJsonString(responseState, \"stored group policy state\") !==\n canonicalKeyingJsonString(request.state, \"authored group policy state\")\n )\n throw new Error(\"Group policy state acknowledgement mismatch\");\n }\n const verified = await verifyPrincipalPolicyCurrentSuccessor({\n previous,\n signerPublicKeys: owned.signerPublicKeys,\n externalAuthority: owned.externalAuthority,\n current: {\n currentState: state,\n currentProjection: request.projection,\n currentGrants: request.grants,\n currentPayload: {\n ...request.encryptedPayload,\n principalId: state.principalId,\n principalType: state.principalType,\n stateHash: state.stateHash,\n },\n currentMemberEnvelopes: {\n envelopes: request.memberEnvelopes,\n principalId: state.principalId,\n principalType: state.principalType,\n stateHash: state.stateHash,\n epoch: state.keyEpoch,\n },\n },\n });\n if (!verified.ok) throw verified.error;\n assertPrincipalPolicyCurrentStateMatchesHead(\n verified.value.state,\n expectedHead,\n );\n verifyPrincipalPolicyCheckpoint({\n chain: verified.value.retainedHistory,\n currentState: verified.value.state,\n localCheckpoint: owned.localPolicyCheckpoint,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n return verified.value;\n}\n"]}