@tearleads/client-sdk 0.1.22 → 0.1.23

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 (54) hide show
  1. package/client/organizations/organizationGroupHistory.js +4 -7
  2. package/client/organizations/organizationGroupHistory.js.map +1 -1
  3. package/client/organizations/organizationReadModels.js +2 -86
  4. package/client/organizations/organizationReadModels.js.map +1 -1
  5. package/client/organizations/principalMutations.js +53 -133
  6. package/client/organizations/principalMutations.js.map +1 -1
  7. package/client/principalMutationDispatch.js +2 -2
  8. package/client/principalMutationDispatch.js.map +1 -1
  9. package/data/keyingProjectionVerification/principalPolicyVerification.js +5 -5
  10. package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
  11. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js +21 -7
  12. package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js.map +1 -1
  13. package/data/keyingProjectionVerification/types.d.ts +1 -8
  14. package/data/keyingProjectionVerification/types.js +0 -9
  15. package/data/keyingProjectionVerification/types.js.map +1 -1
  16. package/data/keyingProjectionVerification.d.ts +1 -1
  17. package/data/keyingProjectionVerification.js.map +1 -1
  18. package/data/persistence/principalHistoryPrefixPersistence.d.ts +5 -1
  19. package/data/persistence/principalHistoryPrefixPersistence.js +22 -5
  20. package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
  21. package/data/principals/principalMutationJournalShape.d.ts +1 -1
  22. package/data/principals/principalMutationJournalShape.js +2 -2
  23. package/data/principals/principalMutationJournalShape.js.map +1 -1
  24. package/index.js.map +1 -1
  25. package/package.json +1 -1
  26. package/workflows/container-contents/container-state/groupGrantVerification.js +23 -74
  27. package/workflows/container-contents/container-state/groupGrantVerification.js.map +1 -1
  28. package/workflows/container-contents/container-state/groupShareEpoch.js +6 -23
  29. package/workflows/container-contents/container-state/groupShareEpoch.js.map +1 -1
  30. package/workflows/container-contents/container-state/remote.js +5 -3
  31. package/workflows/container-contents/container-state/remote.js.map +1 -1
  32. package/workflows/container-contents/container-state/types.js.map +1 -1
  33. package/workflows/container-contents/documentLinks.d.ts +1 -1
  34. package/workflows/container-contents/documentLinks.js.map +1 -1
  35. package/workflows/container-contents/documentPurge.d.ts +1 -1
  36. package/workflows/container-contents/documentPurge.js.map +1 -1
  37. package/workflows/container-contents/metadataRemoteSync.d.ts +1 -1
  38. package/workflows/container-contents/metadataRemoteSync.js.map +1 -1
  39. package/workflows/container-contents/remoteHydration/types.d.ts +2 -2
  40. package/workflows/container-contents/remoteHydration/types.js.map +1 -1
  41. package/workflows/container-contents/remoteHydration/verifiedDestination.js +6 -7
  42. package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +1 -1
  43. package/workflows/containers/child/runtimeCurrentGroupShare.js +1 -1
  44. package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -1
  45. package/workflows/organizations/groupMetadataRuntime.js +11 -8
  46. package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
  47. package/workflows/organizations/organizationGroupNames.js +8 -55
  48. package/workflows/organizations/organizationGroupNames.js.map +1 -1
  49. package/workflows/organizations/principalOperationReceipt.js +1 -1
  50. package/workflows/organizations/principalOperationReceipt.js.map +1 -1
  51. package/workflows/organizations/runtimeGroupMetadataAuthority.js +16 -0
  52. package/workflows/organizations/runtimeGroupMetadataAuthority.js.map +1 -0
  53. package/workflows/principals/runtimePolicyWarmer.js +29 -27
  54. package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
@@ -1,60 +1,13 @@
1
- import { saveOrganizationGroupDisplayNames } from "../../data/persistence/organizations/organizationGroupNamePersistence.js";
2
- import { retainVerifiedPrincipalPolicyBundle } from "../../data/persistence/verifiedPrincipalPolicyRetentionPersistence.js";
1
+ import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
3
2
  import { hydrateCurrentOrganizationGroupNames } from "./currentOrganizationGroupNames.js";
4
- import { verifyDirectoryGroup, } from "./groupNameUniqueness.js";
5
- import { loadGroupNameDirectoryAuthority } from "./organizationGroupNamePolicies.js";
6
3
  /** Verify names against the signed directory before projecting decrypted labels. */
7
4
  export async function hydrateOrganizationGroupNames(input) {
8
- if (input.resolveCurrentPolicy)
9
- return hydrateCurrentOrganizationGroupNames({
10
- ...input,
11
- organizationReference: input.organizationPolicyReference,
12
- resolveCurrentPolicy: input.resolveCurrentPolicy,
13
- });
14
- const authority = await loadGroupNameDirectoryAuthority(input);
15
- if (!authority)
16
- throw new Error("Group directory authority is unavailable");
17
- const names = [];
18
- const unreadableGroupIds = new Set();
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 verifyDirectoryGroup({
24
- ...input,
25
- descriptor: authority.descriptor,
26
- externalAuthority: authority.externalAuthority,
27
- }, head);
28
- // An undecryptable name stays blank for its group alone, and is flagged so
29
- // the group is never offered for selection by name.
30
- if (verified.name === null) {
31
- unreadableGroupIds.add(group.groupId);
32
- }
33
- else {
34
- names.push({
35
- groupId: group.groupId,
36
- name: verified.name,
37
- stateHash: head.stateHash,
38
- });
39
- }
40
- await retainVerifiedPrincipalPolicyBundle({
41
- ...input,
42
- bundle: verified.bundle,
43
- policy: verified.policy,
44
- updatedAt: new Date().toISOString(),
45
- });
46
- }
47
- if (!input.stillCurrent())
48
- throw new Error("Group directory access changed");
49
- await saveOrganizationGroupDisplayNames({ ...input, names });
50
- const byId = new Map(names.map((entry) => [entry.groupId, entry.name]));
51
- return {
52
- ...input.directory,
53
- groups: input.directory.groups.map((group) => ({
54
- ...group,
55
- name: byId.get(group.groupId) ?? "",
56
- nameUnreadable: unreadableGroupIds.has(group.groupId),
57
- })),
58
- };
5
+ if (!input.resolveCurrentPolicy)
6
+ throw new ProjectionDependencyUnavailableError("Group names require private paged recovery");
7
+ return hydrateCurrentOrganizationGroupNames({
8
+ ...input,
9
+ organizationReference: input.organizationPolicyReference,
10
+ resolveCurrentPolicy: input.resolveCurrentPolicy,
11
+ });
59
12
  }
60
13
  //# sourceMappingURL=organizationGroupNames.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"organizationGroupNames.js","sourceRoot":"","sources":["organizationGroupNames.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ReferencedPrincipalHead } from \"@tearleads/crypto\";\nimport { saveOrganizationGroupDisplayNames } from \"../../data/persistence/organizations/organizationGroupNamePersistence\";\nimport { retainVerifiedPrincipalPolicyBundle } from \"../../data/persistence/verifiedPrincipalPolicyRetentionPersistence\";\nimport { hydrateCurrentOrganizationGroupNames } from \"./currentOrganizationGroupNames\";\nimport {\n type DirectoryGroupWalkInput,\n verifyDirectoryGroup,\n} from \"./groupNameUniqueness\";\nimport { loadGroupNameDirectoryAuthority } from \"./organizationGroupNamePolicies\";\nimport type { OrganizationDirectoryAndGroups } from \"./readModel\";\n\n/** Verify names against the signed directory before projecting decrypted labels. */\nexport async function hydrateOrganizationGroupNames(\n input: Omit<DirectoryGroupWalkInput, \"descriptor\" | \"externalAuthority\"> & {\n readonly directory: OrganizationDirectoryAndGroups;\n readonly organizationPolicyReference?: ReferencedPrincipalHead | null;\n readonly recoveryBatch?: object | undefined;\n readonly stillCurrent: () => boolean;\n readonly createCurrentNameReader?: Parameters<\n typeof hydrateCurrentOrganizationGroupNames\n >[0][\"createCurrentNameReader\"];\n readonly resolveCurrentPolicy?:\n | Parameters<\n typeof hydrateCurrentOrganizationGroupNames\n >[0][\"resolveCurrentPolicy\"]\n | undefined;\n },\n): Promise<OrganizationDirectoryAndGroups> {\n if (input.resolveCurrentPolicy)\n return hydrateCurrentOrganizationGroupNames({\n ...input,\n organizationReference: input.organizationPolicyReference,\n resolveCurrentPolicy: input.resolveCurrentPolicy,\n });\n const authority = await loadGroupNameDirectoryAuthority(input);\n if (!authority) throw new Error(\"Group directory authority is unavailable\");\n const names: { groupId: string; name: string; stateHash: string }[] = [];\n const unreadableGroupIds = new Set<string>();\n for (const group of input.directory.groups) {\n const head = authority.descriptor.groupHeads.find(\n (head) => head.principalId === group.groupId,\n );\n if (!head || head.stateHash !== group.currentState?.stateHash)\n throw new Error(\"Group listing does not match the signed directory\");\n const verified = await verifyDirectoryGroup(\n {\n ...input,\n descriptor: authority.descriptor,\n externalAuthority: authority.externalAuthority,\n },\n head,\n );\n // An undecryptable name stays blank for its group alone, and is flagged so\n // the group is never offered for selection by name.\n if (verified.name === null) {\n unreadableGroupIds.add(group.groupId);\n } else {\n names.push({\n groupId: group.groupId,\n name: verified.name,\n stateHash: head.stateHash,\n });\n }\n await retainVerifiedPrincipalPolicyBundle({\n ...input,\n bundle: verified.bundle,\n policy: verified.policy,\n updatedAt: new Date().toISOString(),\n });\n }\n if (!input.stillCurrent()) throw new Error(\"Group directory access changed\");\n await saveOrganizationGroupDisplayNames({ ...input, names });\n const byId = new Map(names.map((entry) => [entry.groupId, entry.name]));\n return {\n ...input.directory,\n groups: input.directory.groups.map((group) => ({\n ...group,\n name: byId.get(group.groupId) ?? \"\",\n nameUnreadable: unreadableGroupIds.has(group.groupId),\n })),\n };\n}\n"]}
1
+ {"version":3,"file":"organizationGroupNames.js","sourceRoot":"","sources":["organizationGroupNames.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,oCAAoC,EAAE,MAAM,iCAAiC,CAAC;AAIvF,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,KAaC;IAED,IAAI,CAAC,KAAK,CAAC,oBAAoB;QAC7B,MAAM,IAAI,oCAAoC,CAC5C,4CAA4C,CAC7C,CAAC;IACJ,OAAO,oCAAoC,CAAC;QAC1C,GAAG,KAAK;QACR,qBAAqB,EAAE,KAAK,CAAC,2BAA2B;QACxD,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;KACjD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ReferencedPrincipalHead } from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { hydrateCurrentOrganizationGroupNames } from \"./currentOrganizationGroupNames\";\nimport type { DirectoryGroupWalkInput } from \"./groupNameUniqueness\";\nimport type { OrganizationDirectoryAndGroups } from \"./readModel\";\n\n/** Verify names against the signed directory before projecting decrypted labels. */\nexport async function hydrateOrganizationGroupNames(\n input: Omit<DirectoryGroupWalkInput, \"descriptor\" | \"externalAuthority\"> & {\n readonly directory: OrganizationDirectoryAndGroups;\n readonly organizationPolicyReference?: ReferencedPrincipalHead | null;\n readonly recoveryBatch?: object | undefined;\n readonly stillCurrent: () => boolean;\n readonly createCurrentNameReader?: Parameters<\n typeof hydrateCurrentOrganizationGroupNames\n >[0][\"createCurrentNameReader\"];\n readonly resolveCurrentPolicy?:\n | Parameters<\n typeof hydrateCurrentOrganizationGroupNames\n >[0][\"resolveCurrentPolicy\"]\n | undefined;\n },\n): Promise<OrganizationDirectoryAndGroups> {\n if (!input.resolveCurrentPolicy)\n throw new ProjectionDependencyUnavailableError(\n \"Group names require private paged recovery\",\n );\n return hydrateCurrentOrganizationGroupNames({\n ...input,\n organizationReference: input.organizationPolicyReference,\n resolveCurrentPolicy: input.resolveCurrentPolicy,\n });\n}\n"]}
@@ -5,7 +5,7 @@ import { assertAuthoredPrincipalMutationReceipt, assertAuthoredPrincipalPolicyRe
5
5
  /** Match both the operation's route and its exact authored policy artifacts. */
6
6
  export async function assertAuthoredPrincipalOperationReceipt(mutation, response) {
7
7
  switch (mutation.kind) {
8
- case undefined:
8
+ case "compound":
9
9
  if (!isCommitOrganizationGroupPolicyResponse(response))
10
10
  break;
11
11
  return assertAuthoredPrincipalMutationReceipt(mutation.request, response);
@@ -1 +1 @@
1
- {"version":3,"file":"principalOperationReceipt.js","sourceRoot":"","sources":["principalOperationReceipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAIL,uCAAuC,EACvC,iCAAiC,EACjC,iCAAiC,EACjC,iCAAiC,GAElC,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EACL,sCAAsC,EACtC,oCAAoC,GACrC,MAAM,4BAA4B,CAAC;AAQpC,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,uCAAuC,CAC3D,QAAmC,EACnC,QAAmC;IAEnC,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,SAAS;YACZ,IAAI,CAAC,uCAAuC,CAAC,QAAQ,CAAC;gBAAE,MAAM;YAC9D,OAAO,sCAAsC,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5E,KAAK,cAAc;YACjB,IAAI,CAAC,iCAAiC,CAAC,QAAQ,CAAC;gBAAE,MAAM;YACxD,OAAO,oCAAoC,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1E,KAAK,cAAc;YACjB,IAAI,CAAC,iCAAiC,CAAC,QAAQ,CAAC;gBAAE,MAAM;YACxD,MAAM,6BAA6B,CAAC;gBAClC,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,WAAW;gBACrE,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,QAAQ,EAAE,QAAQ,CAAC,KAAK;gBACxB,SAAS,EAAE,MAAM,yBAAyB,CACxC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAC1C;aACF,CAAC,CAAC;YACH,OAAO,oCAAoC,CACzC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,EACnC,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;QACJ,KAAK,cAAc;YACjB,IACE,CAAC,iCAAiC,CAAC,QAAQ,CAAC;gBAC5C,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;gBACrC,QAAQ,CAAC,cAAc;oBACrB,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,WAAW;gBAEvD,MAAM;YACR,OAAO,oCAAoC,CACzC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,EACnC,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;IACN,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;AAC5E,CAAC","sourcesContent":["import { computePrincipalStateHash } from \"@tearleads/crypto\";\nimport {\n type CommitOrganizationGroupPolicyResponse,\n type CreateOrganizationGroupResponse,\n type DeleteOrganizationGroupResponse,\n isCommitOrganizationGroupPolicyResponse,\n isCreateOrganizationGroupResponse,\n isDeleteOrganizationGroupResponse,\n isPrincipalPolicyMutationResponse,\n type PrincipalPolicyMutationResponse,\n} from \"@tearleads/validators/response\";\nimport type { AuthoredPrincipalMutation } from \"../../data/principals/principalMutationJournal\";\nimport { acknowledgeInitialGroupPolicy } from \"./groupPolicyMutationAcknowledgement\";\nimport {\n assertAuthoredPrincipalMutationReceipt,\n assertAuthoredPrincipalPolicyReceipt,\n} from \"./principalMutationReceipt\";\n\nexport type PrincipalMutationResponse =\n | CommitOrganizationGroupPolicyResponse\n | CreateOrganizationGroupResponse\n | DeleteOrganizationGroupResponse\n | PrincipalPolicyMutationResponse;\n\n/** Match both the operation's route and its exact authored policy artifacts. */\nexport async function assertAuthoredPrincipalOperationReceipt(\n mutation: AuthoredPrincipalMutation,\n response: PrincipalMutationResponse,\n): Promise<void> {\n switch (mutation.kind) {\n case undefined:\n if (!isCommitOrganizationGroupPolicyResponse(response)) break;\n return assertAuthoredPrincipalMutationReceipt(mutation.request, response);\n case \"organization\":\n if (!isPrincipalPolicyMutationResponse(response)) break;\n return assertAuthoredPrincipalPolicyReceipt(mutation.request, response);\n case \"group-create\":\n if (!isCreateOrganizationGroupResponse(response)) break;\n await acknowledgeInitialGroupPolicy({\n organizationId: mutation.request.organizationPolicy.state.principalId,\n request: mutation.request,\n response: response.group,\n stateHash: await computePrincipalStateHash(\n mutation.request.initialGroupPolicy.state,\n ),\n });\n return assertAuthoredPrincipalPolicyReceipt(\n mutation.request.organizationPolicy,\n response.organizationPolicy,\n );\n case \"group-delete\":\n if (\n !isDeleteOrganizationGroupResponse(response) ||\n response.groupId !== mutation.groupId ||\n response.organizationId !==\n mutation.request.organizationPolicy.state.principalId\n )\n break;\n return assertAuthoredPrincipalPolicyReceipt(\n mutation.request.organizationPolicy,\n response.organizationPolicy,\n );\n }\n throw new Error(\"Principal mutation receipt operation or target differs\");\n}\n"]}
1
+ {"version":3,"file":"principalOperationReceipt.js","sourceRoot":"","sources":["principalOperationReceipt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAIL,uCAAuC,EACvC,iCAAiC,EACjC,iCAAiC,EACjC,iCAAiC,GAElC,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EACL,sCAAsC,EACtC,oCAAoC,GACrC,MAAM,4BAA4B,CAAC;AAQpC,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,uCAAuC,CAC3D,QAAmC,EACnC,QAAmC;IAEnC,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,UAAU;YACb,IAAI,CAAC,uCAAuC,CAAC,QAAQ,CAAC;gBAAE,MAAM;YAC9D,OAAO,sCAAsC,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5E,KAAK,cAAc;YACjB,IAAI,CAAC,iCAAiC,CAAC,QAAQ,CAAC;gBAAE,MAAM;YACxD,OAAO,oCAAoC,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1E,KAAK,cAAc;YACjB,IAAI,CAAC,iCAAiC,CAAC,QAAQ,CAAC;gBAAE,MAAM;YACxD,MAAM,6BAA6B,CAAC;gBAClC,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,WAAW;gBACrE,OAAO,EAAE,QAAQ,CAAC,OAAO;gBACzB,QAAQ,EAAE,QAAQ,CAAC,KAAK;gBACxB,SAAS,EAAE,MAAM,yBAAyB,CACxC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAC1C;aACF,CAAC,CAAC;YACH,OAAO,oCAAoC,CACzC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,EACnC,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;QACJ,KAAK,cAAc;YACjB,IACE,CAAC,iCAAiC,CAAC,QAAQ,CAAC;gBAC5C,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,OAAO;gBACrC,QAAQ,CAAC,cAAc;oBACrB,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,WAAW;gBAEvD,MAAM;YACR,OAAO,oCAAoC,CACzC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,EACnC,QAAQ,CAAC,kBAAkB,CAC5B,CAAC;IACN,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;AAC5E,CAAC","sourcesContent":["import { computePrincipalStateHash } from \"@tearleads/crypto\";\nimport {\n type CommitOrganizationGroupPolicyResponse,\n type CreateOrganizationGroupResponse,\n type DeleteOrganizationGroupResponse,\n isCommitOrganizationGroupPolicyResponse,\n isCreateOrganizationGroupResponse,\n isDeleteOrganizationGroupResponse,\n isPrincipalPolicyMutationResponse,\n type PrincipalPolicyMutationResponse,\n} from \"@tearleads/validators/response\";\nimport type { AuthoredPrincipalMutation } from \"../../data/principals/principalMutationJournal\";\nimport { acknowledgeInitialGroupPolicy } from \"./groupPolicyMutationAcknowledgement\";\nimport {\n assertAuthoredPrincipalMutationReceipt,\n assertAuthoredPrincipalPolicyReceipt,\n} from \"./principalMutationReceipt\";\n\nexport type PrincipalMutationResponse =\n | CommitOrganizationGroupPolicyResponse\n | CreateOrganizationGroupResponse\n | DeleteOrganizationGroupResponse\n | PrincipalPolicyMutationResponse;\n\n/** Match both the operation's route and its exact authored policy artifacts. */\nexport async function assertAuthoredPrincipalOperationReceipt(\n mutation: AuthoredPrincipalMutation,\n response: PrincipalMutationResponse,\n): Promise<void> {\n switch (mutation.kind) {\n case \"compound\":\n if (!isCommitOrganizationGroupPolicyResponse(response)) break;\n return assertAuthoredPrincipalMutationReceipt(mutation.request, response);\n case \"organization\":\n if (!isPrincipalPolicyMutationResponse(response)) break;\n return assertAuthoredPrincipalPolicyReceipt(mutation.request, response);\n case \"group-create\":\n if (!isCreateOrganizationGroupResponse(response)) break;\n await acknowledgeInitialGroupPolicy({\n organizationId: mutation.request.organizationPolicy.state.principalId,\n request: mutation.request,\n response: response.group,\n stateHash: await computePrincipalStateHash(\n mutation.request.initialGroupPolicy.state,\n ),\n });\n return assertAuthoredPrincipalPolicyReceipt(\n mutation.request.organizationPolicy,\n response.organizationPolicy,\n );\n case \"group-delete\":\n if (\n !isDeleteOrganizationGroupResponse(response) ||\n response.groupId !== mutation.groupId ||\n response.organizationId !==\n mutation.request.organizationPolicy.state.principalId\n )\n break;\n return assertAuthoredPrincipalPolicyReceipt(\n mutation.request.organizationPolicy,\n response.organizationPolicy,\n );\n }\n throw new Error(\"Principal mutation receipt operation or target differs\");\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
2
+ import { createRuntimePrincipalPolicyCurrentResolver, } from "../principals/runtimePolicyRecovery.js";
3
+ import { createCurrentGroupMetadataContainerVerifier } from "./currentGroupMetadataAuthority.js";
4
+ /** Remote metadata destinations require the same private authority as name reads. */
5
+ export async function verifyRuntimeGroupMetadataAuthority(input) {
6
+ const resolveCurrentPolicy = createRuntimePrincipalPolicyCurrentResolver(input.runtime);
7
+ if (!resolveCurrentPolicy)
8
+ throw new ProjectionDependencyUnavailableError("Group metadata requires private paged recovery");
9
+ await createCurrentGroupMetadataContainerVerifier({
10
+ execSql: input.runtime.infra.execSql,
11
+ organizationId: input.organizationId,
12
+ resolveCurrentPolicy,
13
+ stillCurrent: input.stillCurrent,
14
+ })(input.state, input.organizationReference);
15
+ }
16
+ //# sourceMappingURL=runtimeGroupMetadataAuthority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeGroupMetadataAuthority.js","sourceRoot":"","sources":["runtimeGroupMetadataAuthority.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EACL,2CAA2C,GAE5C,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,2CAA2C,EAAE,MAAM,iCAAiC,CAAC;AAE9F,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,KAMzD;IACC,MAAM,oBAAoB,GAAG,2CAA2C,CACtE,KAAK,CAAC,OAAO,CACd,CAAC;IACF,IAAI,CAAC,oBAAoB;QACvB,MAAM,IAAI,oCAAoC,CAC5C,gDAAgD,CACjD,CAAC;IACJ,MAAM,2CAA2C,CAAC;QAChD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACpC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,oBAAoB;QACpB,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC;AAC/C,CAAC","sourcesContent":["import type {\n ContainerAccessManifestState,\n ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport {\n createRuntimePrincipalPolicyCurrentResolver,\n type PrincipalPolicyRecoveryRuntime,\n} from \"../principals/runtimePolicyRecovery\";\nimport { createCurrentGroupMetadataContainerVerifier } from \"./currentGroupMetadataAuthority\";\n\n/** Remote metadata destinations require the same private authority as name reads. */\nexport async function verifyRuntimeGroupMetadataAuthority(input: {\n readonly runtime: PrincipalPolicyRecoveryRuntime;\n readonly organizationId: string;\n readonly state: ContainerAccessManifestState;\n readonly organizationReference?: ReferencedPrincipalHead | undefined;\n readonly stillCurrent: () => boolean;\n}): Promise<void> {\n const resolveCurrentPolicy = createRuntimePrincipalPolicyCurrentResolver(\n input.runtime,\n );\n if (!resolveCurrentPolicy)\n throw new ProjectionDependencyUnavailableError(\n \"Group metadata requires private paged recovery\",\n );\n await createCurrentGroupMetadataContainerVerifier({\n execSql: input.runtime.infra.execSql,\n organizationId: input.organizationId,\n resolveCurrentPolicy,\n stillCurrent: input.stillCurrent,\n })(input.state, input.organizationReference);\n}\n"]}
@@ -1,35 +1,37 @@
1
- import { cachePrincipalPolicyBundles, cacheReferencedPrincipalPolicies, } from "./policyCache.js";
1
+ import { errorMessage } from "../../data/errorMessage.js";
2
+ import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
3
+ import { rethrowKeyingVerificationError } from "../../data/keyingProjectionVerification/error.js";
4
+ import { assertProjectionVerificationCurrent, isProjectionVerificationCancelledError, } from "../../data/keyingProjectionVerification/types.js";
2
5
  import { createRuntimePrincipalPolicyResolver, } from "./runtimePolicyRecovery.js";
3
6
  import { createRuntimeProjectionPolicyResolver } from "./runtimeProjectionPolicyRecovery.js";
7
+ /** Prefetch is best-effort; exact resolution still rejects unavailable evidence. */
4
8
  export function createRuntimePrincipalPolicyWarmer(runtime, options = {}) {
5
- const policyInput = ({ organizationId, references, stillCurrent, }) => {
6
- const input = {
7
- execSql: runtime.infra.execSql,
8
- getCurrentPrincipalPolicy: (principalType, principalId) => runtime.apiClient.getCurrentPrincipalPolicy(principalType, principalId),
9
- log: runtime.util.log,
10
- organizationId,
11
- reportSecurityIncident: runtime.util.reportSecurityIncident,
12
- references,
13
- resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,
14
- stillCurrent,
15
- };
16
- return input;
9
+ const resolve = createRuntimePrincipalPolicyResolver(runtime, options);
10
+ const resolveReference = async (input) => {
11
+ if (!resolve)
12
+ throw new ProjectionDependencyUnavailableError("Principal policies require private paged recovery");
13
+ return resolve(input);
17
14
  };
18
- const warmer = async (input) => cacheReferencedPrincipalPolicies(policyInput(input));
19
- const cacheBundles = (input) => cachePrincipalPolicyBundles({
20
- bundles: input.bundles,
21
- execSql: runtime.infra.execSql,
22
- getCurrentPrincipalPolicy: (principalType, principalId) => runtime.apiClient.getCurrentPrincipalPolicy(principalType, principalId),
23
- log: runtime.util.log,
24
- organizationId: input.organizationId,
25
- reportSecurityIncident: runtime.util.reportSecurityIncident,
26
- resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,
27
- stillCurrent: input.stillCurrent,
28
- });
29
- return Object.assign(warmer, {
30
- cacheBundles,
31
- resolveReference: createRuntimePrincipalPolicyResolver(runtime, options),
15
+ return Object.assign((input) => prefetchReferences(runtime, resolveReference, input), {
16
+ resolveReference,
32
17
  resolveProjectionHistory: createRuntimeProjectionPolicyResolver(runtime),
33
18
  });
34
19
  }
20
+ async function prefetchReferences(runtime, resolve, input) {
21
+ const recoveryBatch = {};
22
+ for (const reference of input.references) {
23
+ try {
24
+ assertProjectionVerificationCurrent(input.stillCurrent);
25
+ const resolved = await resolve({ ...input, reference, recoveryBatch });
26
+ assertProjectionVerificationCurrent(resolved.stillCurrent);
27
+ }
28
+ catch (error) {
29
+ if (isProjectionVerificationCancelledError(error))
30
+ return;
31
+ // Recovery already reports signature/authority failures. Keep them fatal.
32
+ rethrowKeyingVerificationError(error);
33
+ runtime.util.log?.(`Principal policy prefetch: ${reference.principalId}: ${errorMessage(error)}`);
34
+ }
35
+ }
36
+ }
35
37
  //# sourceMappingURL=runtimePolicyWarmer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtimePolicyWarmer.js","sourceRoot":"","sources":["runtimePolicyWarmer.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,2BAA2B,EAC3B,gCAAgC,GACjC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,oCAAoC,GAErC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,qCAAqC,EAAE,MAAM,mCAAmC,CAAC;AAiB1F,MAAM,UAAU,kCAAkC,CAChD,OAAmC,EACnC,UAAqD,EAAE;IAEvD,MAAM,WAAW,GAAG,CAAC,EACnB,cAAc,EACd,UAAU,EACV,YAAY,GACmC,EAAE,EAAE;QACnD,MAAM,KAAK,GAA2D;YACpE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;YAC9B,yBAAyB,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,EAAE,CACxD,OAAO,CAAC,SAAS,CAAC,yBAAyB,CAAC,aAAa,EAAE,WAAW,CAAC;YACzE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;YACrB,cAAc;YACd,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB;YAC3D,UAAU;YACV,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;YAC9D,YAAY;SACb,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAClB,KAAqD,EACrD,EAAE,CAAC,gCAAgC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,CAAC,KAAwC,EAAE,EAAE,CAChE,2BAA2B,CAAC;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO;QAC9B,yBAAyB,EAAE,CAAC,aAAa,EAAE,WAAW,EAAE,EAAE,CACxD,OAAO,CAAC,SAAS,CAAC,yBAAyB,CAAC,aAAa,EAAE,WAAW,CAAC;QACzE,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QACrB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,sBAAsB,EAAE,OAAO,CAAC,IAAI,CAAC,sBAAsB;QAC3D,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;QAC9D,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACL,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;QAC3B,YAAY;QACZ,gBAAgB,EAAE,oCAAoC,CAAC,OAAO,EAAE,OAAO,CAAC;QACxE,wBAAwB,EAAE,qCAAqC,CAAC,OAAO,CAAC;KACzE,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport type {\n PrincipalPolicyBundleCacheRequest,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport {\n cachePrincipalPolicyBundles,\n cacheReferencedPrincipalPolicies,\n} from \"./policyCache\";\nimport {\n createRuntimePrincipalPolicyResolver,\n type PrincipalPolicyRecoveryRuntime,\n} from \"./runtimePolicyRecovery\";\nimport { createRuntimeProjectionPolicyResolver } from \"./runtimeProjectionPolicyRecovery\";\n\ninterface PrincipalPolicyWarmRuntime extends PrincipalPolicyRecoveryRuntime {\n readonly apiClient: PrincipalPolicyRecoveryRuntime[\"apiClient\"] & {\n getCurrentPrincipalPolicy(\n principalType: \"group\" | \"organization\",\n principalId: string,\n ): Promise<PrincipalPolicyBundleResponse | null>;\n };\n readonly infra: { readonly execSql: ExecSql };\n readonly util: {\n readonly log: (message: string) => void;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n };\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}\n\nexport function createRuntimePrincipalPolicyWarmer(\n runtime: PrincipalPolicyWarmRuntime,\n options: { readonly preferLocalCurrent?: boolean } = {},\n): ReferencedPrincipalPolicyWarmer {\n const policyInput = ({\n organizationId,\n references,\n stillCurrent,\n }: Parameters<ReferencedPrincipalPolicyWarmer>[0]) => {\n const input: Parameters<typeof cacheReferencedPrincipalPolicies>[0] = {\n execSql: runtime.infra.execSql,\n getCurrentPrincipalPolicy: (principalType, principalId) =>\n runtime.apiClient.getCurrentPrincipalPolicy(principalType, principalId),\n log: runtime.util.log,\n organizationId,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n references,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n stillCurrent,\n };\n return input;\n };\n const warmer = async (\n input: Parameters<ReferencedPrincipalPolicyWarmer>[0],\n ) => cacheReferencedPrincipalPolicies(policyInput(input));\n const cacheBundles = (input: PrincipalPolicyBundleCacheRequest) =>\n cachePrincipalPolicyBundles({\n bundles: input.bundles,\n execSql: runtime.infra.execSql,\n getCurrentPrincipalPolicy: (principalType, principalId) =>\n runtime.apiClient.getCurrentPrincipalPolicy(principalType, principalId),\n log: runtime.util.log,\n organizationId: input.organizationId,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n return Object.assign(warmer, {\n cacheBundles,\n resolveReference: createRuntimePrincipalPolicyResolver(runtime, options),\n resolveProjectionHistory: createRuntimeProjectionPolicyResolver(runtime),\n });\n}\n"]}
1
+ {"version":3,"file":"runtimePolicyWarmer.js","sourceRoot":"","sources":["runtimePolicyWarmer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EACL,mCAAmC,EACnC,sCAAsC,GAEvC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,oCAAoC,GAErC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,qCAAqC,EAAE,MAAM,mCAAmC,CAAC;AAW1F,oFAAoF;AACpF,MAAM,UAAU,kCAAkC,CAChD,OAAmC,EACnC,UAAqD,EAAE;IAEvD,MAAM,OAAO,GAAG,oCAAoC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACvE,MAAM,gBAAgB,GAAmB,KAAK,EAAE,KAAK,EAAE,EAAE;QACvD,IAAI,CAAC,OAAO;YACV,MAAM,IAAI,oCAAoC,CAC5C,mDAAmD,CACpD,CAAC;QACJ,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAClB,CAAC,KAAqD,EAAE,EAAE,CACxD,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,CAAC,EACtD;QACE,gBAAgB;QAChB,wBAAwB,EAAE,qCAAqC,CAAC,OAAO,CAAC;KACzE,CACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB,CAC/B,OAAmC,EACnC,OAAuB,EACvB,KAAqD;IAErD,MAAM,aAAa,GAAG,EAAE,CAAC;IACzB,KAAK,MAAM,SAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC;YACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACxD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;YACvE,mCAAmC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,sCAAsC,CAAC,KAAK,CAAC;gBAAE,OAAO;YAC1D,0EAA0E;YAC1E,8BAA8B,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAChB,8BAA8B,SAAS,CAAC,WAAW,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,CAC9E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { errorMessage } from \"../../data/errorMessage\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { rethrowKeyingVerificationError } from \"../../data/keyingProjectionVerification/error\";\nimport {\n assertProjectionVerificationCurrent,\n isProjectionVerificationCancelledError,\n type ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification/types\";\nimport {\n createRuntimePrincipalPolicyResolver,\n type PrincipalPolicyRecoveryRuntime,\n} from \"./runtimePolicyRecovery\";\nimport { createRuntimeProjectionPolicyResolver } from \"./runtimeProjectionPolicyRecovery\";\n\ntype PolicyResolver = NonNullable<\n ReferencedPrincipalPolicyWarmer[\"resolveReference\"]\n>;\ninterface PrincipalPolicyWarmRuntime extends PrincipalPolicyRecoveryRuntime {\n readonly util: PrincipalPolicyRecoveryRuntime[\"util\"] & {\n readonly log?: ((message: string) => void) | undefined;\n };\n}\n\n/** Prefetch is best-effort; exact resolution still rejects unavailable evidence. */\nexport function createRuntimePrincipalPolicyWarmer(\n runtime: PrincipalPolicyWarmRuntime,\n options: { readonly preferLocalCurrent?: boolean } = {},\n): ReferencedPrincipalPolicyWarmer {\n const resolve = createRuntimePrincipalPolicyResolver(runtime, options);\n const resolveReference: PolicyResolver = async (input) => {\n if (!resolve)\n throw new ProjectionDependencyUnavailableError(\n \"Principal policies require private paged recovery\",\n );\n return resolve(input);\n };\n return Object.assign(\n (input: Parameters<ReferencedPrincipalPolicyWarmer>[0]) =>\n prefetchReferences(runtime, resolveReference, input),\n {\n resolveReference,\n resolveProjectionHistory: createRuntimeProjectionPolicyResolver(runtime),\n },\n );\n}\n\nasync function prefetchReferences(\n runtime: PrincipalPolicyWarmRuntime,\n resolve: PolicyResolver,\n input: Parameters<ReferencedPrincipalPolicyWarmer>[0],\n): Promise<void> {\n const recoveryBatch = {};\n for (const reference of input.references) {\n try {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const resolved = await resolve({ ...input, reference, recoveryBatch });\n assertProjectionVerificationCurrent(resolved.stillCurrent);\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return;\n // Recovery already reports signature/authority failures. Keep them fatal.\n rethrowKeyingVerificationError(error);\n runtime.util.log?.(\n `Principal policy prefetch: ${reference.principalId}: ${errorMessage(error)}`,\n );\n }\n }\n}\n"]}