@tearleads/client-sdk 0.1.24 → 0.1.25

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 (85) hide show
  1. package/data/persistence/container-contents/containerContentsPersistenceTypes.d.ts +2 -0
  2. package/data/persistence/container-contents/containerContentsPersistenceTypes.js.map +1 -1
  3. package/data/persistence/container-contents/containerDeletionPersistence.js +3 -0
  4. package/data/persistence/container-contents/containerDeletionPersistence.js.map +1 -1
  5. package/data/persistence/container-contents/documentPurgePlacement.js +15 -0
  6. package/data/persistence/container-contents/documentPurgePlacement.js.map +1 -0
  7. package/data/persistence/documents/internal/documentDeletionPersistence.js +7 -0
  8. package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
  9. package/data/persistence/documents/types.d.ts +2 -1
  10. package/data/persistence/documents/types.js.map +1 -1
  11. package/data/persistence/principalCurrentAcknowledgementPersistence.d.ts +13 -2
  12. package/data/persistence/principalCurrentAcknowledgementPersistence.js +36 -20
  13. package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -1
  14. package/index.d.ts +2 -2
  15. package/index.js +1 -1
  16. package/index.js.map +1 -1
  17. package/internal/api-client/ApiClient.d.ts +6 -2
  18. package/internal/api-client/ApiClient.js +4 -5
  19. package/internal/api-client/ApiClient.js.map +1 -1
  20. package/internal/api-client/apiRequestRuntime.d.ts +1 -2
  21. package/internal/api-client/apiRequestRuntime.js +12 -15
  22. package/internal/api-client/apiRequestRuntime.js.map +1 -1
  23. package/internal/api-client/routes/containers/mutations.js +2 -2
  24. package/internal/api-client/routes/containers/mutations.js.map +1 -1
  25. package/internal/api-client/sessionRefresh.js +14 -6
  26. package/internal/api-client/sessionRefresh.js.map +1 -1
  27. package/internal/api-client/sessionRenewal.js +54 -0
  28. package/internal/api-client/sessionRenewal.js.map +1 -0
  29. package/internal/validators/operation/containerMutations.d.ts +3 -0
  30. package/internal/validators/operation/containerMutations.js +1 -0
  31. package/internal/validators/operation/containerMutations.js.map +1 -1
  32. package/package.json +1 -1
  33. package/workflows/container-contents/container-state/delete.js +2 -0
  34. package/workflows/container-contents/container-state/delete.js.map +1 -1
  35. package/workflows/container-contents/container-state/localPurgeScope.js +49 -0
  36. package/workflows/container-contents/container-state/localPurgeScope.js.map +1 -0
  37. package/workflows/container-contents/container-state/purgeTree.js +42 -7
  38. package/workflows/container-contents/container-state/purgeTree.js.map +1 -1
  39. package/workflows/container-contents/container-state/purgeTreeCollection.js +11 -0
  40. package/workflows/container-contents/container-state/purgeTreeCollection.js.map +1 -1
  41. package/workflows/container-contents/container-state/purgeTreeContainerDeletion.js +4 -1
  42. package/workflows/container-contents/container-state/purgeTreeContainerDeletion.js.map +1 -1
  43. package/workflows/container-contents/container-state/purgeTreeScope.js +158 -0
  44. package/workflows/container-contents/container-state/purgeTreeScope.js.map +1 -0
  45. package/workflows/container-contents/container-state/readLocalPurgeScope.js +18 -0
  46. package/workflows/container-contents/container-state/readLocalPurgeScope.js.map +1 -0
  47. package/workflows/container-contents/container-state/remote.js +1 -0
  48. package/workflows/container-contents/container-state/remote.js.map +1 -1
  49. package/workflows/container-contents/container-state/types.js.map +1 -1
  50. package/workflows/container-contents/documentLinks.d.ts +4 -0
  51. package/workflows/container-contents/documentLinks.js +2 -0
  52. package/workflows/container-contents/documentLinks.js.map +1 -1
  53. package/workflows/container-contents/documentPurge.d.ts +6 -1
  54. package/workflows/container-contents/documentPurge.js +8 -1
  55. package/workflows/container-contents/documentPurge.js.map +1 -1
  56. package/workflows/documents/linkSet.d.ts +1 -0
  57. package/workflows/documents/linkSet.js +2 -0
  58. package/workflows/documents/linkSet.js.map +1 -1
  59. package/workflows/documents/linkSetRemote.d.ts +2 -0
  60. package/workflows/documents/linkSetRemote.js +3 -0
  61. package/workflows/documents/linkSetRemote.js.map +1 -1
  62. package/workflows/documents/purge.d.ts +3 -0
  63. package/workflows/documents/purge.js +7 -0
  64. package/workflows/documents/purge.js.map +1 -1
  65. package/workflows/documents/subtreePurgeScope.js +11 -0
  66. package/workflows/documents/subtreePurgeScope.js.map +1 -0
  67. package/workflows/organizations/acknowledgedPrincipalPredecessor.d.ts +39 -0
  68. package/workflows/organizations/acknowledgedPrincipalPredecessor.js +87 -0
  69. package/workflows/organizations/acknowledgedPrincipalPredecessor.js.map +1 -0
  70. package/workflows/organizations/currentOrganizationMutationRetention.js +13 -2
  71. package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -1
  72. package/workflows/organizations/index.d.ts +1 -0
  73. package/workflows/organizations/index.js +1 -0
  74. package/workflows/organizations/index.js.map +1 -1
  75. package/workflows/organizations/initialPrincipalCurrentPublication.js +3 -2
  76. package/workflows/organizations/initialPrincipalCurrentPublication.js.map +1 -1
  77. package/workflows/organizations/reconcileAcknowledgedPrincipalCurrent.js +63 -0
  78. package/workflows/organizations/reconcileAcknowledgedPrincipalCurrent.js.map +1 -0
  79. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.d.ts +3 -0
  80. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +33 -55
  81. package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -1
  82. package/workflows/organizations/runtimeCurrentGroupMutation.js +13 -2
  83. package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -1
  84. package/workflows/organizations/runtimeCurrentOrganizationMutation.js +2 -2
  85. package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"purge.js","sourceRoot":"","sources":["purge.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessEventBodyHash,\n type DocumentPurgeAccessEventBody,\n KeyingVerificationError,\n signAccessEvent,\n type UnsignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { DocumentPurgeRequest } from \"@tearleads/validators/request\";\nimport {\n DOCUMENT_NOT_FOUND_ERROR_CODE,\n type DocumentPurgeProofResponse,\n type DocumentPurgeResponse,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n containerPathRefs,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"../../data/documents/shared/projection\";\nimport {\n assertDocumentManifestBundleConsistent,\n readManifestContainerId,\n} from \"../../data/documents/shared/readers\";\nimport type {\n DocumentCreateAuthor,\n DocumentSyncApi,\n} from \"../../data/documents/shared/types\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../data/keyingCanonicalJson\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport {\n verifyDocumentPurgeProof,\n verifyDocumentPurgeProofBaseline,\n verifyDocumentWriterProjection,\n} from \"../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { documentContainerProjections } from \"../../data/keyingProjectionVerification/documentContainerProjections\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\n\ninterface DocumentPurgeApi {\n getDocumentPurgeProof(\n documentId: string,\n options?: {\n readonly documentCheckpointManifestHash?: string;\n },\n requestOptions?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeProofResponse | null>;\n getDocumentWriterProjectionResult: NonNullable<\n DocumentSyncApi[\"getDocumentWriterProjectionResult\"]\n >;\n purgeDocument(\n documentId: string,\n request: DocumentPurgeRequest,\n options?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeResponse | null>;\n}\n\nconst REMOTE_DOCUMENT_ALREADY_PURGED = Symbol(\"remoteDocumentAlreadyPurged\");\n\nasync function loadAuthenticatedDocumentPurgeProof(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly documentId: string;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeProofResponse | null> {\n if (!input.apiClient.getDocumentPurgeProof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing a purge-proof endpoint\",\n );\n }\n const initialProof = await input.apiClient.getDocumentPurgeProof(\n input.documentId,\n undefined,\n {\n expectedPaymentRequiredOrganizationId: input.expectedOrganizationId,\n },\n );\n if (!initialProof) {\n // ApiClient returns null for transport, HTTP and response-shape failures.\n // Even after a deletion hint, absence cannot prove signed-data tampering.\n // Keep local data and defer deletion until an actual proof verifies.\n return null;\n }\n await verifyDocumentPurgeProofBaseline({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof: initialProof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // The current API returns complete history to recorded readers. Otherwise\n // its terminal snapshot needs an exact local pin; a floor refetch cannot\n // grant missing observation authority.\n return initialProof;\n}\n\nasync function resolveDocumentPurgeWriterProjection(input: {\n readonly apiClient: DocumentPurgeApi;\n readonly documentId: string;\n}): Promise<\n | DocumentWriterProjectionResponse\n | typeof REMOTE_DOCUMENT_ALREADY_PURGED\n | null\n> {\n const result = await input.apiClient.getDocumentWriterProjectionResult(\n input.documentId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n if (result.status === 404 && result.code === DOCUMENT_NOT_FOUND_ERROR_CODE) {\n return REMOTE_DOCUMENT_ALREADY_PURGED;\n }\n result.report();\n return null;\n}\n\nexport async function buildDocumentPurgeRequest(input: {\n readonly author: DocumentCreateAuthor;\n readonly eventId?: string | undefined;\n readonly signedAt?: string | undefined;\n readonly writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentPurgeRequest> {\n const identity = await assertDocumentManifestBundleConsistent({\n bundle: input.writerProjection.documentManifest,\n label: \"Document purge predecessor\",\n });\n if (identity.documentId !== input.writerProjection.documentId) {\n throw new Error(\"Document purge projection identity mismatch\");\n }\n if (identity.organizationId !== input.author.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Document purge author organization mismatch\",\n );\n }\n const linkedContainerIds = readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n );\n if (linkedContainerIds.length !== 1) {\n throw new Error(\"Document purge requires exactly one linked container\");\n }\n const [containerId] = linkedContainerIds;\n const authorizingProjection = documentContainerProjections(\n input.writerProjection,\n ).find((projection) => {\n const leaf = projection.path.at(-1);\n return leaf && readManifestContainerId(leaf) === containerId;\n });\n const containerManifestHash =\n authorizingProjection?.path.at(-1)?.manifestHash;\n if (!authorizingProjection || !containerId || !containerManifestHash) {\n throw new Error(\"Document purge authorization path is unavailable\");\n }\n const authorizingContainerManifestHashes = authorizingProjection.path.map(\n (bundle) => bundle.manifestHash,\n );\n const body: DocumentPurgeAccessEventBody = {\n authorizingContainerManifestHashes,\n containerId,\n containerManifestHash,\n documentManifestHash: input.writerProjection.documentManifest.manifestHash,\n eventType: \"document.purge\",\n };\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId ?? crypto.randomUUID(),\n eventType: \"document.purge\",\n objectKind: \"document\",\n objectId: input.writerProjection.documentId,\n organizationId: input.author.organizationId,\n previousManifestHash: input.writerProjection.documentManifest.manifestHash,\n dependencyManifestHashes: authorizingContainerManifestHashes,\n bodyHash: await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document purge body\"),\n ),\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt ?? new Date().toISOString(),\n };\n const event = await signAccessEvent(\n unsignedEvent,\n input.author.signerPrivateKey,\n );\n\n return {\n authorizingContainerPathRefs: containerPathRefs(authorizingProjection.path),\n body: readCanonicalRecord(body, \"Document purge body\"),\n event: readCanonicalRecord(event, \"Document purge event\"),\n };\n}\n\nexport function createVerifiedRemoteDocumentDeletionHandler(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly onVerifiedDeletion: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n readonly documentId: string;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): (deleted: { readonly documentId: string }) => Promise<void> {\n return async ({ documentId }) => {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedDeletion({\n commitPurgeProof: verified.commitCheckpoints,\n documentId,\n });\n };\n}\n\nexport async function purgeRemoteDocument(input: {\n readonly apiClient: DocumentPurgeApi;\n readonly author: DocumentCreateAuthor;\n readonly documentId: string;\n readonly execSql: ExecSql;\n readonly onVerifiedPurge: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeResponse | null> {\n const writerProjection = await resolveDocumentPurgeWriterProjection({\n apiClient: input.apiClient,\n documentId: input.documentId,\n });\n if (!writerProjection) {\n return null;\n }\n if (writerProjection === REMOTE_DOCUMENT_ALREADY_PURGED) {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId: input.documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.author.organizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Purged remote document is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return { ...proof, reclaimedBlobStorageKeys: [] };\n }\n await verifyDocumentWriterProjection({\n execSql: input.execSql,\n projection: writerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const request = await buildDocumentPurgeRequest({\n author: input.author,\n writerProjection,\n });\n const response = await input.apiClient.purgeDocument(\n input.documentId,\n request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n );\n if (!response) {\n return null;\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof: response,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return response;\n}\n"]}
1
+ {"version":3,"file":"purge.js","sourceRoot":"","sources":["purge.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessEventBodyHash,\n type DocumentPurgeAccessEventBody,\n KeyingVerificationError,\n signAccessEvent,\n type UnsignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { DocumentPurgeRequest } from \"@tearleads/validators/request\";\nimport {\n DOCUMENT_NOT_FOUND_ERROR_CODE,\n type DocumentPurgeProofResponse,\n type DocumentPurgeResponse,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport {\n containerPathRefs,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"../../data/documents/shared/projection\";\nimport {\n assertDocumentManifestBundleConsistent,\n readManifestContainerId,\n} from \"../../data/documents/shared/readers\";\nimport type {\n DocumentCreateAuthor,\n DocumentSyncApi,\n} from \"../../data/documents/shared/types\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../data/keyingCanonicalJson\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport {\n verifyDocumentPurgeProof,\n verifyDocumentPurgeProofBaseline,\n verifyDocumentWriterProjection,\n} from \"../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { documentContainerProjections } from \"../../data/keyingProjectionVerification/documentContainerProjections\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { assertSubtreePurgePath } from \"./subtreePurgeScope\";\n\ninterface DocumentPurgeApi {\n getDocumentPurgeProof(\n documentId: string,\n options?: {\n readonly documentCheckpointManifestHash?: string;\n },\n requestOptions?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeProofResponse | null>;\n getDocumentWriterProjectionResult: NonNullable<\n DocumentSyncApi[\"getDocumentWriterProjectionResult\"]\n >;\n purgeDocument(\n documentId: string,\n request: DocumentPurgeRequest,\n options?: {\n readonly expectedPaymentRequiredOrganizationId?: string;\n },\n ): Promise<DocumentPurgeResponse | null>;\n}\n\nconst REMOTE_DOCUMENT_ALREADY_PURGED = Symbol(\"remoteDocumentAlreadyPurged\");\n\nasync function loadAuthenticatedDocumentPurgeProof(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly documentId: string;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeProofResponse | null> {\n if (!input.apiClient.getDocumentPurgeProof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing a purge-proof endpoint\",\n );\n }\n const initialProof = await input.apiClient.getDocumentPurgeProof(\n input.documentId,\n undefined,\n {\n expectedPaymentRequiredOrganizationId: input.expectedOrganizationId,\n },\n );\n if (!initialProof) {\n // ApiClient returns null for transport, HTTP and response-shape failures.\n // Even after a deletion hint, absence cannot prove signed-data tampering.\n // Keep local data and defer deletion until an actual proof verifies.\n return null;\n }\n await verifyDocumentPurgeProofBaseline({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof: initialProof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // The current API returns complete history to recorded readers. Otherwise\n // its terminal snapshot needs an exact local pin; a floor refetch cannot\n // grant missing observation authority.\n return initialProof;\n}\n\nasync function resolveDocumentPurgeWriterProjection(input: {\n readonly apiClient: DocumentPurgeApi;\n readonly documentId: string;\n}): Promise<\n | DocumentWriterProjectionResponse\n | typeof REMOTE_DOCUMENT_ALREADY_PURGED\n | null\n> {\n const result = await input.apiClient.getDocumentWriterProjectionResult(\n input.documentId,\n { reportErrors: false },\n );\n if (result.ok) {\n return result.data;\n }\n if (result.status === 404 && result.code === DOCUMENT_NOT_FOUND_ERROR_CODE) {\n return REMOTE_DOCUMENT_ALREADY_PURGED;\n }\n result.report();\n return null;\n}\n\nexport async function buildDocumentPurgeRequest(input: {\n readonly author: DocumentCreateAuthor;\n readonly expectedSubtreeRootId?: string | undefined;\n readonly eventId?: string | undefined;\n readonly signedAt?: string | undefined;\n readonly writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentPurgeRequest> {\n const identity = await assertDocumentManifestBundleConsistent({\n bundle: input.writerProjection.documentManifest,\n label: \"Document purge predecessor\",\n });\n if (identity.documentId !== input.writerProjection.documentId) {\n throw new Error(\"Document purge projection identity mismatch\");\n }\n if (identity.organizationId !== input.author.organizationId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Document purge author organization mismatch\",\n );\n }\n const linkedContainerIds = readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n );\n if (linkedContainerIds.length !== 1) {\n throw new Error(\"Document purge requires exactly one linked container\");\n }\n const [containerId] = linkedContainerIds;\n const authorizingProjection = documentContainerProjections(\n input.writerProjection,\n ).find((projection) => {\n const leaf = projection.path.at(-1);\n return leaf && readManifestContainerId(leaf) === containerId;\n });\n const containerManifestHash =\n authorizingProjection?.path.at(-1)?.manifestHash;\n if (!authorizingProjection || !containerId || !containerManifestHash) {\n throw new Error(\"Document purge authorization path is unavailable\");\n }\n assertSubtreePurgePath(\n authorizingProjection.path,\n input.expectedSubtreeRootId,\n );\n const authorizingContainerManifestHashes = authorizingProjection.path.map(\n (bundle) => bundle.manifestHash,\n );\n const body: DocumentPurgeAccessEventBody = {\n authorizingContainerManifestHashes,\n containerId,\n containerManifestHash,\n documentManifestHash: input.writerProjection.documentManifest.manifestHash,\n eventType: \"document.purge\",\n };\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId ?? crypto.randomUUID(),\n eventType: \"document.purge\",\n objectKind: \"document\",\n objectId: input.writerProjection.documentId,\n organizationId: input.author.organizationId,\n previousManifestHash: input.writerProjection.documentManifest.manifestHash,\n dependencyManifestHashes: authorizingContainerManifestHashes,\n bodyHash: await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document purge body\"),\n ),\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt ?? new Date().toISOString(),\n };\n const event = await signAccessEvent(\n unsignedEvent,\n input.author.signerPrivateKey,\n );\n\n return {\n authorizingContainerPathRefs: containerPathRefs(authorizingProjection.path),\n body: readCanonicalRecord(body, \"Document purge body\"),\n event: readCanonicalRecord(event, \"Document purge event\"),\n };\n}\n\nexport function createVerifiedRemoteDocumentDeletionHandler(input: {\n readonly apiClient: Pick<DocumentSyncApi, \"getDocumentPurgeProof\">;\n readonly execSql: ExecSql;\n readonly expectedOrganizationId: string;\n readonly onVerifiedDeletion: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n readonly documentId: string;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): (deleted: { readonly documentId: string }) => Promise<void> {\n return async ({ documentId }) => {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Remote document deletion is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: documentId,\n expectedOrganizationId: input.expectedOrganizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedDeletion({\n commitPurgeProof: verified.commitCheckpoints,\n documentId,\n });\n };\n}\n\nexport async function purgeRemoteDocument(input: {\n readonly beforeSubmit?: (() => Promise<boolean>) | undefined;\n readonly apiClient: DocumentPurgeApi;\n readonly author: DocumentCreateAuthor;\n readonly documentId: string;\n readonly expectedSubtreeRootId?: string | undefined;\n readonly execSql: ExecSql;\n readonly onVerifiedPurge: (input: {\n readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;\n }) => Promise<void> | void;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<DocumentPurgeResponse | null> {\n const writerProjection = await resolveDocumentPurgeWriterProjection({\n apiClient: input.apiClient,\n documentId: input.documentId,\n });\n if (!writerProjection) {\n return null;\n }\n if (writerProjection === REMOTE_DOCUMENT_ALREADY_PURGED) {\n const proof = await loadAuthenticatedDocumentPurgeProof({\n apiClient: input.apiClient,\n documentId: input.documentId,\n execSql: input.execSql,\n expectedOrganizationId: input.author.organizationId,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!proof) {\n throw new ProjectionDependencyUnavailableError(\n \"Purged remote document is missing its signed purge proof\",\n );\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return { ...proof, reclaimedBlobStorageKeys: [] };\n }\n await verifyDocumentWriterProjection({\n execSql: input.execSql,\n projection: writerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const request = await buildDocumentPurgeRequest({\n author: input.author,\n expectedSubtreeRootId: input.expectedSubtreeRootId,\n writerProjection,\n });\n if (input.beforeSubmit && !(await input.beforeSubmit())) return null;\n if (input.stillCurrent?.() === false) return null;\n const response = await input.apiClient.purgeDocument(\n input.documentId,\n request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n );\n if (!response) {\n return null;\n }\n const verified = await verifyDocumentPurgeProof({\n execSql: input.execSql,\n expectedDocumentId: input.documentId,\n expectedOrganizationId: input.author.organizationId,\n proof: response,\n resolveUserKey: input.resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await input.onVerifiedPurge({\n commitPurgeProof: verified.commitCheckpoints,\n });\n return response;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { readManifestContainerId } from "../../data/documents/shared/readers.js";
2
+ /** Check the exact verified path that the destructive request will cite. */
3
+ export function assertSubtreePurgePath(path, rootContainerId) {
4
+ if (rootContainerId === undefined)
5
+ return;
6
+ if (!path.some((bundle) => readManifestContainerId(bundle) === rootContainerId)) {
7
+ // A valid move out of the selected subtree is ordinary concurrent work.
8
+ throw new Error("Document placement is outside the requested purge subtree");
9
+ }
10
+ }
11
+ //# sourceMappingURL=subtreePurgeScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtreePurgeScope.js","sourceRoot":"","sources":["subtreePurgeScope.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,4EAA4E;AAC5E,MAAM,UAAU,sBAAsB,CACpC,IAAiD,EACjD,eAAmC;IAEnC,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO;IAC1C,IACE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,KAAK,eAAe,CAAC,EAC3E,CAAC;QACD,wEAAwE;QACxE,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;IACJ,CAAC;AACH,CAAC","sourcesContent":["import type { AccessManifestBundleWireResponse } from \"@tearleads/validators/response\";\nimport { readManifestContainerId } from \"../../data/documents/shared/readers\";\n\n/** Check the exact verified path that the destructive request will cite. */\nexport function assertSubtreePurgePath(\n path: readonly AccessManifestBundleWireResponse[],\n rootContainerId: string | undefined,\n): void {\n if (rootContainerId === undefined) return;\n if (\n !path.some((bundle) => readManifestContainerId(bundle) === rootContainerId)\n ) {\n // A valid move out of the selected subtree is ordinary concurrent work.\n throw new Error(\n \"Document placement is outside the requested purge subtree\",\n );\n }\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import { type PrincipalHistoryPrefix } from "../../data/persistence/principalHistoryPrefixPersistence.js";
2
+ import type { RecoverPrincipalPolicyHistoryOptions } from "../principals/principalHistoryRecoveryTypes.js";
3
+ /** Sealed predecessor evidence, owned by a mutation before its request is sent. */
4
+ export type AcknowledgedPrincipalPredecessor = Readonly<PrincipalHistoryPrefix>;
5
+ /** Authenticate the entire prefix, including its scope and current artifacts. */
6
+ export declare function restoreAcknowledgedPrincipalPrefix(options: RecoverPrincipalPolicyHistoryOptions, saved: AcknowledgedPrincipalPredecessor | null): Promise<{
7
+ scopeId: string;
8
+ saved: Readonly<{
9
+ version: number;
10
+ organizationId: string;
11
+ scopeId: string;
12
+ headJson: string;
13
+ currentJson: string;
14
+ progress: string;
15
+ }>;
16
+ artifacts: import("../../internal/api-client/index.js").PrincipalPolicyPageCurrent;
17
+ verifier: import("../../internal/crypto/index.js").PrincipalPolicyHistoryVerifier;
18
+ previous: import("../../internal/crypto/index.js").VerifiedPrincipalPolicyCurrent;
19
+ history: import("../../internal/crypto/index.js").VerifiedPrincipalPolicyHistory;
20
+ predecessorIndexRootHash: string;
21
+ }>;
22
+ /** Capture exact predecessor evidence while authoring, before HTTP can commit. */
23
+ export declare function captureAcknowledgedPrincipalPredecessor(input: RecoverPrincipalPolicyHistoryOptions): Promise<AcknowledgedPrincipalPredecessor>;
24
+ export declare function restoreAcknowledgedPrincipalPredecessor(options: RecoverPrincipalPolicyHistoryOptions, saved: AcknowledgedPrincipalPredecessor | null): Promise<{
25
+ scopeId: string;
26
+ saved: Readonly<{
27
+ version: number;
28
+ organizationId: string;
29
+ scopeId: string;
30
+ headJson: string;
31
+ currentJson: string;
32
+ progress: string;
33
+ }>;
34
+ artifacts: import("../../internal/api-client/index.js").PrincipalPolicyPageCurrent;
35
+ verifier: import("../../internal/crypto/index.js").PrincipalPolicyHistoryVerifier;
36
+ previous: import("../../internal/crypto/index.js").VerifiedPrincipalPolicyCurrent;
37
+ history: import("../../internal/crypto/index.js").VerifiedPrincipalPolicyHistory;
38
+ predecessorIndexRootHash: string;
39
+ }>;
@@ -0,0 +1,87 @@
1
+ import { KeyingVerificationError, restorePrincipalPolicyHistoryVerifier, verifyPrincipalPolicyCurrent, } from "../../internal/crypto/index.js";
2
+ import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
3
+ import { loadPrincipalHistoryPrefix, } from "../../data/persistence/principalHistoryPrefixPersistence.js";
4
+ import { principalHeadMatchesReference } from "../../data/principals/organizationAuthorityDescriptor.js";
5
+ import { principalHistoryEvidenceScopeId, principalHistoryPrefixProtection, } from "../../data/principals/principalHistoryPrefixProtection.js";
6
+ import { ownPrincipalHistoryProtection } from "../../data/principals/principalHistoryProtection.js";
7
+ import { parsePrincipalHistoryStageCurrent } from "../../data/principals/principalHistoryStageProtection.js";
8
+ import { principalPolicyReferenceFromBundle } from "../../data/principals/principalPolicyAdminSigners.js";
9
+ import { principalHistoryVerificationContext } from "../principals/principalHistoryRecoveryVerification.js";
10
+ /** Authenticate the entire prefix, including its scope and current artifacts. */
11
+ export async function restoreAcknowledgedPrincipalPrefix(options, saved) {
12
+ const scopeId = await principalHistoryEvidenceScopeId({
13
+ organizationId: options.organizationId,
14
+ head: options.expectedHead,
15
+ protection: options.protection,
16
+ });
17
+ if (!saved ||
18
+ saved.scopeId !== scopeId ||
19
+ saved.organizationId !== options.organizationId)
20
+ throw new KeyingVerificationError("missing_dependency", "Acknowledgement requires its authenticated predecessor prefix");
21
+ const restored = await restorePrincipalPolicyHistoryVerifier({
22
+ principalId: options.expectedHead.principalId,
23
+ principalType: options.expectedHead.principalType,
24
+ }, saved.progress, await principalHistoryPrefixProtection(options.protection, saved));
25
+ if (!restored.ok)
26
+ throw restored.error;
27
+ const artifacts = parsePrincipalHistoryStageCurrent({
28
+ currentJson: saved.currentJson,
29
+ afterVersion: saved.version - 1,
30
+ });
31
+ if (!artifacts)
32
+ throw new KeyingVerificationError("invalid_shape", "Acknowledged predecessor artifacts are malformed");
33
+ const history = restored.value.finish(principalPolicyReferenceFromBundle(artifacts));
34
+ if (!history.ok)
35
+ throw history.error;
36
+ const previous = await verifyPrincipalPolicyCurrent({
37
+ current: artifacts,
38
+ history: history.value,
39
+ });
40
+ if (!previous.ok)
41
+ throw previous.error;
42
+ return {
43
+ scopeId,
44
+ saved,
45
+ artifacts,
46
+ verifier: restored.value,
47
+ previous: previous.value,
48
+ history: history.value,
49
+ predecessorIndexRootHash: history.value.indexRootHash,
50
+ };
51
+ }
52
+ /** Capture exact predecessor evidence while authoring, before HTTP can commit. */
53
+ export async function captureAcknowledgedPrincipalPredecessor(input) {
54
+ const protection = ownPrincipalHistoryProtection(input.protection);
55
+ const options = {
56
+ ...input,
57
+ expectedHead: structuredClone(input.expectedHead),
58
+ protection: {
59
+ ...protection,
60
+ context: principalHistoryVerificationContext(input),
61
+ },
62
+ };
63
+ const current = () => !options.signal?.aborted && options.stillCurrent();
64
+ try {
65
+ assertProjectionVerificationCurrent(current);
66
+ const scopeId = await principalHistoryEvidenceScopeId({
67
+ organizationId: options.organizationId,
68
+ head: options.expectedHead,
69
+ protection: options.protection,
70
+ });
71
+ const restored = await restoreAcknowledgedPrincipalPrefix(options, await loadPrincipalHistoryPrefix(options.execSql, scopeId));
72
+ assertProjectionVerificationCurrent(current);
73
+ if (!principalHeadMatchesReference(restored.previous.state, options.expectedHead))
74
+ throw new Error("Principal policy changed before submission; retry the mutation");
75
+ return structuredClone(restored.saved);
76
+ }
77
+ finally {
78
+ protection.localKey.fill(0);
79
+ }
80
+ }
81
+ export async function restoreAcknowledgedPrincipalPredecessor(options, saved) {
82
+ const restored = await restoreAcknowledgedPrincipalPrefix(options, saved);
83
+ if (!principalHeadMatchesReference(restored.previous.state, options.expectedHead))
84
+ throw new KeyingVerificationError("object_mismatch", "Acknowledgement predecessor does not match the authored request");
85
+ return restored;
86
+ }
87
+ //# sourceMappingURL=acknowledgedPrincipalPredecessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acknowledgedPrincipalPredecessor.js","sourceRoot":"","sources":["acknowledgedPrincipalPredecessor.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n restorePrincipalPolicyHistoryVerifier,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n loadPrincipalHistoryPrefix,\n type PrincipalHistoryPrefix,\n} from \"../../data/persistence/principalHistoryPrefixPersistence\";\nimport { principalHeadMatchesReference } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport {\n principalHistoryEvidenceScopeId,\n principalHistoryPrefixProtection,\n} from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { ownPrincipalHistoryProtection } from \"../../data/principals/principalHistoryProtection\";\nimport { parsePrincipalHistoryStageCurrent } from \"../../data/principals/principalHistoryStageProtection\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport { principalHistoryVerificationContext } from \"../principals/principalHistoryRecoveryVerification\";\n\n/** Sealed predecessor evidence, owned by a mutation before its request is sent. */\nexport type AcknowledgedPrincipalPredecessor = Readonly<PrincipalHistoryPrefix>;\n\n/** Authenticate the entire prefix, including its scope and current artifacts. */\nexport async function restoreAcknowledgedPrincipalPrefix(\n options: RecoverPrincipalPolicyHistoryOptions,\n saved: AcknowledgedPrincipalPredecessor | null,\n) {\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: options.organizationId,\n head: options.expectedHead,\n protection: options.protection,\n });\n if (\n !saved ||\n saved.scopeId !== scopeId ||\n saved.organizationId !== options.organizationId\n )\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Acknowledgement requires its authenticated predecessor prefix\",\n );\n const restored = await restorePrincipalPolicyHistoryVerifier(\n {\n principalId: options.expectedHead.principalId,\n principalType: options.expectedHead.principalType,\n },\n saved.progress,\n await principalHistoryPrefixProtection(options.protection, saved),\n );\n if (!restored.ok) throw restored.error;\n const artifacts = parsePrincipalHistoryStageCurrent({\n currentJson: saved.currentJson,\n afterVersion: saved.version - 1,\n });\n if (!artifacts)\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Acknowledged predecessor artifacts are malformed\",\n );\n const history = restored.value.finish(\n principalPolicyReferenceFromBundle(artifacts),\n );\n if (!history.ok) throw history.error;\n const previous = await verifyPrincipalPolicyCurrent({\n current: artifacts,\n history: history.value,\n });\n if (!previous.ok) throw previous.error;\n return {\n scopeId,\n saved,\n artifacts,\n verifier: restored.value,\n previous: previous.value,\n history: history.value,\n predecessorIndexRootHash: history.value.indexRootHash,\n };\n}\n\n/** Capture exact predecessor evidence while authoring, before HTTP can commit. */\nexport async function captureAcknowledgedPrincipalPredecessor(\n input: RecoverPrincipalPolicyHistoryOptions,\n): Promise<AcknowledgedPrincipalPredecessor> {\n const protection = ownPrincipalHistoryProtection(input.protection);\n const options = {\n ...input,\n expectedHead: structuredClone(input.expectedHead),\n protection: {\n ...protection,\n context: principalHistoryVerificationContext(input),\n },\n };\n const current = () => !options.signal?.aborted && options.stillCurrent();\n try {\n assertProjectionVerificationCurrent(current);\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: options.organizationId,\n head: options.expectedHead,\n protection: options.protection,\n });\n const restored = await restoreAcknowledgedPrincipalPrefix(\n options,\n await loadPrincipalHistoryPrefix(options.execSql, scopeId),\n );\n assertProjectionVerificationCurrent(current);\n if (\n !principalHeadMatchesReference(\n restored.previous.state,\n options.expectedHead,\n )\n )\n throw new Error(\n \"Principal policy changed before submission; retry the mutation\",\n );\n return structuredClone(restored.saved);\n } finally {\n protection.localKey.fill(0);\n }\n}\n\nexport async function restoreAcknowledgedPrincipalPredecessor(\n options: RecoverPrincipalPolicyHistoryOptions,\n saved: AcknowledgedPrincipalPredecessor | null,\n) {\n const restored = await restoreAcknowledgedPrincipalPrefix(options, saved);\n if (\n !principalHeadMatchesReference(\n restored.previous.state,\n options.expectedHead,\n )\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Acknowledgement predecessor does not match the authored request\",\n );\n return restored;\n}\n"]}
@@ -1,9 +1,16 @@
1
1
  import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
2
2
  import { scopedGroupHistoryProtection } from "../../data/principals/principalHistoryScopeProtection.js";
3
3
  import { principalPolicyReferenceFromBundle } from "../../data/principals/principalPolicyAdminSigners.js";
4
+ import { captureAcknowledgedPrincipalPredecessor } from "./acknowledgedPrincipalPredecessor.js";
4
5
  import { retainAcknowledgedPrincipalCurrents, } from "./retainAcknowledgedPrincipalCurrents.js";
5
6
  /** Couple directory acknowledgements to any newly created group under the same lease. */
6
- export function createCurrentOrganizationMutationRetention(input) {
7
+ export async function createCurrentOrganizationMutationRetention(input) {
8
+ const predecessor = await captureAcknowledgedPrincipalPredecessor({
9
+ ...input.directoryRecovery,
10
+ execSql: input.runtime.infra.execSql,
11
+ organizationId: input.organizationId,
12
+ stillCurrent: input.stillCurrent,
13
+ });
7
14
  const retain = async (entries) => {
8
15
  assertProjectionVerificationCurrent(input.stillCurrent);
9
16
  await retainAcknowledgedPrincipalCurrents({
@@ -14,7 +21,9 @@ export function createCurrentOrganizationMutationRetention(input) {
14
21
  });
15
22
  };
16
23
  return {
17
- retainDirectory: (request, response) => retain([{ request, response, recovery: input.directoryRecovery }]),
24
+ retainDirectory: (request, response) => retain([
25
+ { predecessor, request, response, recovery: input.directoryRecovery },
26
+ ]),
18
27
  retainCreatedGroup: (receipt) => {
19
28
  const adminHead = {
20
29
  ...principalPolicyReferenceFromBundle(input.authority.admins.current),
@@ -23,6 +32,7 @@ export function createCurrentOrganizationMutationRetention(input) {
23
32
  return retain([
24
33
  {
25
34
  initialGroup: true,
35
+ predecessor: null,
26
36
  request: receipt.request,
27
37
  response: receipt.response,
28
38
  recovery: {
@@ -42,6 +52,7 @@ export function createCurrentOrganizationMutationRetention(input) {
42
52
  },
43
53
  },
44
54
  {
55
+ predecessor,
45
56
  request: receipt.organizationRequest,
46
57
  response: receipt.organizationResponse,
47
58
  recovery: input.directoryRecovery,
@@ -1 +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"]}
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;AAEvG,OAAO,EAAE,uCAAuC,EAAE,MAAM,oCAAoC,CAAC;AAE7F,OAAO,EAEL,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAE/C,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,0CAA0C,CAAC,KAUhE;IACC,MAAM,WAAW,GAAG,MAAM,uCAAuC,CAAC;QAChE,GAAG,KAAK,CAAC,iBAAiB;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACpC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,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,CACF,MAAM,CAAC;YACL,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,iBAAiB,EAAE;SACtE,CAAC;QACJ,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,WAAW,EAAE,IAAI;oBACjB,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,WAAW;oBACX,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 { captureAcknowledgedPrincipalPredecessor } from \"./acknowledgedPrincipalPredecessor\";\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 async 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 predecessor = await captureAcknowledgedPrincipalPredecessor({\n ...input.directoryRecovery,\n execSql: input.runtime.infra.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\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 ) =>\n retain([\n { predecessor, request, response, recovery: input.directoryRecovery },\n ]),\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 predecessor: null,\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 predecessor,\n request: receipt.organizationRequest,\n response: receipt.organizationResponse,\n recovery: input.directoryRecovery,\n },\n ]);\n },\n };\n}\n"]}
@@ -2,6 +2,7 @@ export { type OrganizationReadModelInvalidationListener, subscribeOrganizationRe
2
2
  export { PendingPrincipalMutationError } from "../../data/persistence/principalMutationJournalPersistence.js";
3
3
  export type { AuthoredPrincipalMutation, PrincipalMutationJournalScope, } from "../../data/principals/principalMutationJournal.js";
4
4
  export { UnreadablePrincipalMutationError } from "../../data/principals/principalMutationJournalRecord.js";
5
+ export { type AcknowledgedPrincipalPredecessor, captureAcknowledgedPrincipalPredecessor, } from "./acknowledgedPrincipalPredecessor.js";
5
6
  export { cancelStripeSubscription, checkNativePurchaseEligibility, claimNativeOrganizationSubscription, createStripeCheckout, createStripeCheckoutSession, loadOrganizationBilling, loadOrganizationBillingHistory, loadOrganizationBillingManagementUrl, loadStripeCheckoutOptions, type OrganizationBilling, type OrganizationBillingHistory, type OrganizationBillingHistoryEntry, type OrganizationBillingManagementUrl, type OrganizationBillingView, type OrganizationNativePurchaseEligibility, resolveOrganizationBillingView, type StripeCheckoutIntent, type StripeCheckoutOptions, startOrganizationTrial, } from "./billing.js";
6
7
  export { revokeOrganizationContainerGrant } from "./containerGrantRevocation.js";
7
8
  export { type CreateOrganizationApi, type CreateOrganizationInput, createOrganization, } from "./createOrganization.js";
@@ -1,6 +1,7 @@
1
1
  export { subscribeOrganizationReadModelInvalidation, } from "../../data/persistence/organizations/organizationReadModelInvalidation.js";
2
2
  export { PendingPrincipalMutationError } from "../../data/persistence/principalMutationJournalPersistence.js";
3
3
  export { UnreadablePrincipalMutationError } from "../../data/principals/principalMutationJournalRecord.js";
4
+ export { captureAcknowledgedPrincipalPredecessor, } from "./acknowledgedPrincipalPredecessor.js";
4
5
  export { cancelStripeSubscription, checkNativePurchaseEligibility, claimNativeOrganizationSubscription, createStripeCheckout, createStripeCheckoutSession, loadOrganizationBilling, loadOrganizationBillingHistory, loadOrganizationBillingManagementUrl, loadStripeCheckoutOptions, resolveOrganizationBillingView, startOrganizationTrial, } from "./billing.js";
5
6
  export { revokeOrganizationContainerGrant } from "./containerGrantRevocation.js";
6
7
  export { createOrganization, } from "./createOrganization.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0CAA0C,GAC3C,MAAM,wEAAwE,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,4DAA4D,CAAC;AAK3G,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AACxG,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,uBAAuB,EACvB,8BAA8B,EAC9B,oCAAoC,EACpC,yBAAyB,EAOzB,8BAA8B,EAG9B,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAGL,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,8BAA8B,EAG9B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,kCAAkC,EAClC,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,qCAAqC,EACrC,4CAA4C,EAC5C,0CAA0C,EAC1C,qCAAqC,EACrC,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,2CAA2C,EAC3C,8BAA8B,GAC/B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAEL,oCAAoC,EACpC,iCAAiC,EACjC,gCAAgC,GACjC,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,oCAAoC,EACpC,uBAAuB,EACvB,2BAA2B,EAC3B,yCAAyC,GAC1C,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mCAAmC,EAwBnC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uCAAuC,EACvC,iCAAiC,EAEjC,uCAAuC,GACxC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,+BAA+B,EAC/B,sCAAsC,EACtC,6CAA6C,EAC7C,kDAAkD,EAClD,+BAA+B,EAC/B,oCAAoC,EACpC,0CAA0C,EAC1C,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC","sourcesContent":["export {\n type OrganizationReadModelInvalidationListener,\n subscribeOrganizationReadModelInvalidation,\n} from \"../../data/persistence/organizations/organizationReadModelInvalidation\";\nexport { PendingPrincipalMutationError } from \"../../data/persistence/principalMutationJournalPersistence\";\nexport type {\n AuthoredPrincipalMutation,\n PrincipalMutationJournalScope,\n} from \"../../data/principals/principalMutationJournal\";\nexport { UnreadablePrincipalMutationError } from \"../../data/principals/principalMutationJournalRecord\";\nexport {\n cancelStripeSubscription,\n checkNativePurchaseEligibility,\n claimNativeOrganizationSubscription,\n createStripeCheckout,\n createStripeCheckoutSession,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n loadStripeCheckoutOptions,\n type OrganizationBilling,\n type OrganizationBillingHistory,\n type OrganizationBillingHistoryEntry,\n type OrganizationBillingManagementUrl,\n type OrganizationBillingView,\n type OrganizationNativePurchaseEligibility,\n resolveOrganizationBillingView,\n type StripeCheckoutIntent,\n type StripeCheckoutOptions,\n startOrganizationTrial,\n} from \"./billing\";\nexport { revokeOrganizationContainerGrant } from \"./containerGrantRevocation\";\nexport {\n type CreateOrganizationApi,\n type CreateOrganizationInput,\n createOrganization,\n} from \"./createOrganization\";\nexport {\n loadLocalOrganizationDataUsage,\n type OrganizationDataUsage,\n type ReconcileOrganizationDataUsageInput,\n reconcileOrganizationDataUsage,\n} from \"./dataUsageReadModel\";\nexport { deleteOrganizationGroup } from \"./deleteOrganizationGroup\";\nexport { GroupMembershipNameMismatchError } from \"./groupMembershipName\";\nexport {\n type LocalOrganizationSummary,\n listLocalOrganizations,\n} from \"./listLocalOrganizations\";\nexport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupPolicyHistory,\n loadLocalOrganizationPolicyHistory,\n loadLocalOrganizationPolicyReference,\n loadLocalOrganizationUserDetail,\n} from \"./localReadModelDetails\";\nexport {\n buildOrganizationProfileDocumentPatch,\n createInitializedOrganizationProfileDocument,\n DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME,\n getOrganizationProfileDocumentLocalId,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n readOrganizationProfileName,\n} from \"./organizationProfile\";\nexport {\n type ImportedOrganizationUser,\n importOrganizationUser,\n} from \"./organizationUserImport\";\nexport {\n abandonJournaledPrincipalMutation,\n discardUnreadableJournaledPrincipalMutation,\n readJournaledPrincipalMutation,\n} from \"./principalMutationJournalManagement\";\nexport {\n type PrincipalMutationJournalContext,\n PrincipalMutationOutcomeUnknownError,\n recoverJournaledPrincipalMutation,\n submitJournaledPrincipalMutation,\n} from \"./principalMutationJournalSession\";\nexport type { PrincipalMutationResponse } from \"./principalOperationReceipt\";\nexport {\n addOrganizationGroupUser,\n buildInitialGroupPolicyRequest,\n buildInitialMemberGroupPolicyRequest,\n createOrganizationGroup,\n removeOrganizationGroupUser,\n rotateOrganizationGroupForAccessSetShrink,\n} from \"./principalPolicy\";\nexport {\n buildOrganizationGroupPolicyHistory,\n type OrganizationContainerGrant,\n type OrganizationContainerGrants,\n type OrganizationDirectory,\n type OrganizationDirectoryAndGroups,\n type OrganizationDirectoryUser,\n type OrganizationGroupContainer,\n type OrganizationGroupContainers,\n type OrganizationGroupDetails,\n type OrganizationGroupMember,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationGroupPolicyHistoryEntry,\n type OrganizationGroupSummary,\n type OrganizationPolicyGrantChange,\n type OrganizationPolicyGroupChange,\n type OrganizationPolicyHistory,\n type OrganizationPolicyHistoryEntry,\n type OrganizationPrincipalMemberChange,\n type OrganizationPrincipalMemberChangeType,\n type OrganizationPrincipalPolicyHistory,\n type OrganizationPrincipalPolicyHistoryEntry,\n type OrganizationProfile,\n type OrganizationUserDetail,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n} from \"./readModel\";\nexport {\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupMembers,\n type ReconcileOrganizationDirectoryAndGroupsInput,\n reconcileOrganizationDirectoryAndGroups,\n} from \"./readModelProjection\";\nexport {\n type AcknowledgedPrincipalCurrentInput,\n type AcknowledgedPrincipalCurrentRetirement,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\nexport {\n buildRosterProfileDocumentPatch,\n createInitializedRosterProfileDocument,\n deriveOrganizationMetadataContainerSystemSlot,\n deriveOrganizationRosterProfileContainerSystemSlot,\n getRosterProfileDocumentLocalId,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n ROSTER_PROFILE_DOCUMENT_KIND,\n} from \"./rosterProfileContainer\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,0CAA0C,GAC3C,MAAM,wEAAwE,CAAC;AAChF,OAAO,EAAE,6BAA6B,EAAE,MAAM,4DAA4D,CAAC;AAK3G,OAAO,EAAE,gCAAgC,EAAE,MAAM,sDAAsD,CAAC;AACxG,OAAO,EAEL,uCAAuC,GACxC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,mCAAmC,EACnC,oBAAoB,EACpB,2BAA2B,EAC3B,uBAAuB,EACvB,8BAA8B,EAC9B,oCAAoC,EACpC,yBAAyB,EAOzB,8BAA8B,EAG9B,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAGL,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,8BAA8B,EAG9B,8BAA8B,GAC/B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oCAAoC,EACpC,oCAAoC,EACpC,uCAAuC,EACvC,kCAAkC,EAClC,oCAAoC,EACpC,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,qCAAqC,EACrC,4CAA4C,EAC5C,0CAA0C,EAC1C,qCAAqC,EACrC,kCAAkC,EAClC,2BAA2B,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,iCAAiC,EACjC,2CAA2C,EAC3C,8BAA8B,GAC/B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAEL,oCAAoC,EACpC,iCAAiC,EACjC,gCAAgC,GACjC,MAAM,mCAAmC,CAAC;AAE3C,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,oCAAoC,EACpC,uBAAuB,EACvB,2BAA2B,EAC3B,yCAAyC,GAC1C,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,mCAAmC,EAwBnC,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uCAAuC,EACvC,iCAAiC,EAEjC,uCAAuC,GACxC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,+BAA+B,EAC/B,sCAAsC,EACtC,6CAA6C,EAC7C,kDAAkD,EAClD,+BAA+B,EAC/B,oCAAoC,EACpC,0CAA0C,EAC1C,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC","sourcesContent":["export {\n type OrganizationReadModelInvalidationListener,\n subscribeOrganizationReadModelInvalidation,\n} from \"../../data/persistence/organizations/organizationReadModelInvalidation\";\nexport { PendingPrincipalMutationError } from \"../../data/persistence/principalMutationJournalPersistence\";\nexport type {\n AuthoredPrincipalMutation,\n PrincipalMutationJournalScope,\n} from \"../../data/principals/principalMutationJournal\";\nexport { UnreadablePrincipalMutationError } from \"../../data/principals/principalMutationJournalRecord\";\nexport {\n type AcknowledgedPrincipalPredecessor,\n captureAcknowledgedPrincipalPredecessor,\n} from \"./acknowledgedPrincipalPredecessor\";\nexport {\n cancelStripeSubscription,\n checkNativePurchaseEligibility,\n claimNativeOrganizationSubscription,\n createStripeCheckout,\n createStripeCheckoutSession,\n loadOrganizationBilling,\n loadOrganizationBillingHistory,\n loadOrganizationBillingManagementUrl,\n loadStripeCheckoutOptions,\n type OrganizationBilling,\n type OrganizationBillingHistory,\n type OrganizationBillingHistoryEntry,\n type OrganizationBillingManagementUrl,\n type OrganizationBillingView,\n type OrganizationNativePurchaseEligibility,\n resolveOrganizationBillingView,\n type StripeCheckoutIntent,\n type StripeCheckoutOptions,\n startOrganizationTrial,\n} from \"./billing\";\nexport { revokeOrganizationContainerGrant } from \"./containerGrantRevocation\";\nexport {\n type CreateOrganizationApi,\n type CreateOrganizationInput,\n createOrganization,\n} from \"./createOrganization\";\nexport {\n loadLocalOrganizationDataUsage,\n type OrganizationDataUsage,\n type ReconcileOrganizationDataUsageInput,\n reconcileOrganizationDataUsage,\n} from \"./dataUsageReadModel\";\nexport { deleteOrganizationGroup } from \"./deleteOrganizationGroup\";\nexport { GroupMembershipNameMismatchError } from \"./groupMembershipName\";\nexport {\n type LocalOrganizationSummary,\n listLocalOrganizations,\n} from \"./listLocalOrganizations\";\nexport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupPolicyHistory,\n loadLocalOrganizationPolicyHistory,\n loadLocalOrganizationPolicyReference,\n loadLocalOrganizationUserDetail,\n} from \"./localReadModelDetails\";\nexport {\n buildOrganizationProfileDocumentPatch,\n createInitializedOrganizationProfileDocument,\n DEFAULT_PERSONAL_ORGANIZATION_PROFILE_NAME,\n getOrganizationProfileDocumentLocalId,\n ORGANIZATION_PROFILE_DOCUMENT_KIND,\n readOrganizationProfileName,\n} from \"./organizationProfile\";\nexport {\n type ImportedOrganizationUser,\n importOrganizationUser,\n} from \"./organizationUserImport\";\nexport {\n abandonJournaledPrincipalMutation,\n discardUnreadableJournaledPrincipalMutation,\n readJournaledPrincipalMutation,\n} from \"./principalMutationJournalManagement\";\nexport {\n type PrincipalMutationJournalContext,\n PrincipalMutationOutcomeUnknownError,\n recoverJournaledPrincipalMutation,\n submitJournaledPrincipalMutation,\n} from \"./principalMutationJournalSession\";\nexport type { PrincipalMutationResponse } from \"./principalOperationReceipt\";\nexport {\n addOrganizationGroupUser,\n buildInitialGroupPolicyRequest,\n buildInitialMemberGroupPolicyRequest,\n createOrganizationGroup,\n removeOrganizationGroupUser,\n rotateOrganizationGroupForAccessSetShrink,\n} from \"./principalPolicy\";\nexport {\n buildOrganizationGroupPolicyHistory,\n type OrganizationContainerGrant,\n type OrganizationContainerGrants,\n type OrganizationDirectory,\n type OrganizationDirectoryAndGroups,\n type OrganizationDirectoryUser,\n type OrganizationGroupContainer,\n type OrganizationGroupContainers,\n type OrganizationGroupDetails,\n type OrganizationGroupMember,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationGroupPolicyHistoryEntry,\n type OrganizationGroupSummary,\n type OrganizationPolicyGrantChange,\n type OrganizationPolicyGroupChange,\n type OrganizationPolicyHistory,\n type OrganizationPolicyHistoryEntry,\n type OrganizationPrincipalMemberChange,\n type OrganizationPrincipalMemberChangeType,\n type OrganizationPrincipalPolicyHistory,\n type OrganizationPrincipalPolicyHistoryEntry,\n type OrganizationProfile,\n type OrganizationUserDetail,\n updateOrganizationProfile,\n updateOrganizationRosterEntry,\n} from \"./readModel\";\nexport {\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupMembers,\n type ReconcileOrganizationDirectoryAndGroupsInput,\n reconcileOrganizationDirectoryAndGroups,\n} from \"./readModelProjection\";\nexport {\n type AcknowledgedPrincipalCurrentInput,\n type AcknowledgedPrincipalCurrentRetirement,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\nexport {\n buildRosterProfileDocumentPatch,\n createInitializedRosterProfileDocument,\n deriveOrganizationMetadataContainerSystemSlot,\n deriveOrganizationRosterProfileContainerSystemSlot,\n getRosterProfileDocumentLocalId,\n ORGANIZATION_METADATA_CONTAINER_NAME,\n ORGANIZATION_ROSTER_PROFILE_CONTAINER_NAME,\n ROSTER_PROFILE_DOCUMENT_KIND,\n} from \"./rosterProfileContainer\";\n"]}
@@ -9,11 +9,12 @@ import { groupPolicyMutationHead } from "./groupPolicyMutationHead.js";
9
9
  import { sealPrincipalCurrentPublication } from "./principalCurrentPublicationSeal.js";
10
10
  import { assertPrincipalPolicyReceiptArtifacts } from "./principalPolicyReceiptArtifacts.js";
11
11
  /** Verify a newly authored group from genesis before its atomic directory publication. */
12
- export async function prepareInitialGroupCurrentPublication(input, request, response) {
12
+ export async function prepareInitialGroupCurrentPublication(input, request, response, predecessor) {
13
13
  const current = () => !input.signal?.aborted && input.stillCurrent();
14
14
  assertProjectionVerificationCurrent(current);
15
15
  const expectedHead = await groupPolicyMutationHead(request);
16
- if (request.state.principalType !== "group" ||
16
+ if (predecessor !== null ||
17
+ request.state.principalType !== "group" ||
17
18
  request.state.version !== 1 ||
18
19
  request.state.prevStateHash !== null ||
19
20
  !principalHeadMatchesReference(expectedHead, input.expectedHead))
@@ -1 +1 @@
1
- {"version":3,"file":"initialPrincipalCurrentPublication.js","sourceRoot":"","sources":["initialPrincipalCurrentPublication.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createPrincipalPolicyHistoryVerifier,\n KeyingVerificationError,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { AcknowledgedPrincipalCurrentPublication } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { preparePrincipalHistoryEvidencePage } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport { principalHeadMatchesReference } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { principalHistoryEvidenceScopeId } from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"../principals/policyVerification\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport {\n assertPrincipalHistoryVerificationMode,\n principalHistoryVerificationContext,\n} from \"../principals/principalHistoryRecoveryVerification\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { sealPrincipalCurrentPublication } from \"./principalCurrentPublicationSeal\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\n/** Verify a newly authored group from genesis before its atomic directory publication. */\nexport async function prepareInitialGroupCurrentPublication(\n input: RecoverPrincipalPolicyHistoryOptions,\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n): Promise<AcknowledgedPrincipalCurrentPublication> {\n const current = () => !input.signal?.aborted && input.stillCurrent();\n assertProjectionVerificationCurrent(current);\n const expectedHead = await groupPolicyMutationHead(request);\n if (\n request.state.principalType !== \"group\" ||\n request.state.version !== 1 ||\n request.state.prevStateHash !== null ||\n !principalHeadMatchesReference(expectedHead, input.expectedHead)\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Initial group publication must begin at its exact genesis\",\n );\n assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });\n const keys = await collectPrincipalPolicySignerPublicKeys({\n bundle: { currentState: response.currentState, previousStates: [] },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in keys)\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"Initial group signer could not be authenticated\",\n );\n const externalAuthority = await input.loadExternalAuthority?.(\n request.state.externalAuthority ? [request.state.externalAuthority] : [],\n );\n assertProjectionVerificationCurrent(current);\n const verifier = createPrincipalPolicyHistoryVerifier({\n principalType: \"group\",\n principalId: expectedHead.principalId,\n });\n const entry = {\n state: response.currentState,\n projection: response.currentProjection,\n grants: response.currentGrants,\n };\n assertPrincipalHistoryVerificationMode(input, [entry]);\n const appended = await verifier.append({\n entries: [entry],\n signerPublicKeys: keys.signerPublicKeys,\n ...(externalAuthority ? { externalAuthority } : {}),\n });\n if (!appended.ok) throw appended.error;\n const history = verifier.finish(expectedHead);\n if (!history.ok) throw history.error;\n const policy = await verifyPrincipalPolicyCurrent({\n current: response,\n history: history.value,\n });\n if (!policy.ok) throw policy.error;\n const options = {\n ...input,\n protection: {\n ...input.protection,\n context: principalHistoryVerificationContext(input),\n },\n };\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: input.organizationId,\n head: expectedHead,\n protection: options.protection,\n });\n const sealed = await sealPrincipalCurrentPublication(\n options,\n scopeId,\n expectedHead,\n verifier,\n response,\n );\n assertProjectionVerificationCurrent(current);\n return {\n ...sealed,\n policy: policy.value,\n predecessorStage: null,\n predecessorIndexRootHash: null,\n previousPrefixProgress: null,\n evidence: await preparePrincipalHistoryEvidencePage({\n indexRootHash: appended.value.indexRootHash,\n scopeId,\n organizationId: input.organizationId,\n entries: [entry],\n nodes: appended.value.indexNodes,\n }),\n };\n}\n"]}
1
+ {"version":3,"file":"initialPrincipalCurrentPublication.js","sourceRoot":"","sources":["initialPrincipalCurrentPublication.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createPrincipalPolicyHistoryVerifier,\n KeyingVerificationError,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { AcknowledgedPrincipalCurrentPublication } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { preparePrincipalHistoryEvidencePage } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport { principalHeadMatchesReference } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { principalHistoryEvidenceScopeId } from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"../principals/policyVerification\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport {\n assertPrincipalHistoryVerificationMode,\n principalHistoryVerificationContext,\n} from \"../principals/principalHistoryRecoveryVerification\";\nimport type { AcknowledgedPrincipalPredecessor } from \"./acknowledgedPrincipalPredecessor\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { sealPrincipalCurrentPublication } from \"./principalCurrentPublicationSeal\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\n/** Verify a newly authored group from genesis before its atomic directory publication. */\nexport async function prepareInitialGroupCurrentPublication(\n input: RecoverPrincipalPolicyHistoryOptions,\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n predecessor: AcknowledgedPrincipalPredecessor | null,\n): Promise<AcknowledgedPrincipalCurrentPublication> {\n const current = () => !input.signal?.aborted && input.stillCurrent();\n assertProjectionVerificationCurrent(current);\n const expectedHead = await groupPolicyMutationHead(request);\n if (\n predecessor !== null ||\n request.state.principalType !== \"group\" ||\n request.state.version !== 1 ||\n request.state.prevStateHash !== null ||\n !principalHeadMatchesReference(expectedHead, input.expectedHead)\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Initial group publication must begin at its exact genesis\",\n );\n assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });\n const keys = await collectPrincipalPolicySignerPublicKeys({\n bundle: { currentState: response.currentState, previousStates: [] },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in keys)\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"Initial group signer could not be authenticated\",\n );\n const externalAuthority = await input.loadExternalAuthority?.(\n request.state.externalAuthority ? [request.state.externalAuthority] : [],\n );\n assertProjectionVerificationCurrent(current);\n const verifier = createPrincipalPolicyHistoryVerifier({\n principalType: \"group\",\n principalId: expectedHead.principalId,\n });\n const entry = {\n state: response.currentState,\n projection: response.currentProjection,\n grants: response.currentGrants,\n };\n assertPrincipalHistoryVerificationMode(input, [entry]);\n const appended = await verifier.append({\n entries: [entry],\n signerPublicKeys: keys.signerPublicKeys,\n ...(externalAuthority ? { externalAuthority } : {}),\n });\n if (!appended.ok) throw appended.error;\n const history = verifier.finish(expectedHead);\n if (!history.ok) throw history.error;\n const policy = await verifyPrincipalPolicyCurrent({\n current: response,\n history: history.value,\n });\n if (!policy.ok) throw policy.error;\n const options = {\n ...input,\n protection: {\n ...input.protection,\n context: principalHistoryVerificationContext(input),\n },\n };\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: input.organizationId,\n head: expectedHead,\n protection: options.protection,\n });\n const sealed = await sealPrincipalCurrentPublication(\n options,\n scopeId,\n expectedHead,\n verifier,\n response,\n );\n assertProjectionVerificationCurrent(current);\n return {\n ...sealed,\n policy: policy.value,\n predecessorStage: null,\n predecessorIndexRootHash: null,\n previousPrefixProgress: null,\n evidence: await preparePrincipalHistoryEvidencePage({\n indexRootHash: appended.value.indexRootHash,\n scopeId,\n organizationId: input.organizationId,\n entries: [entry],\n nodes: appended.value.indexNodes,\n }),\n };\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import { KeyingVerificationError, verifyPrincipalPolicyCurrent, } from "../../internal/crypto/index.js";
2
+ import { loadPrincipalPolicyCheckpoint } from "../../data/persistence/keyingCheckpointPersistence.js";
3
+ import { loadPrincipalHistoryPrefix } from "../../data/persistence/principalHistoryPrefixPersistence.js";
4
+ import { principalHeadMatchesReference } from "../../data/principals/organizationAuthorityDescriptor.js";
5
+ import { selectRecoveredPrincipalHistory } from "../principals/principalHistoryRecoveryReferences.js";
6
+ import { principalHistoryVerificationContext } from "../principals/principalHistoryRecoveryVerification.js";
7
+ import { restoreAcknowledgedPrincipalPrefix } from "./acknowledgedPrincipalPredecessor.js";
8
+ /** Prove an already observed successor contains this receipt before preserving it. */
9
+ export async function reconcileAcknowledgedPrincipalCurrent(input, publication) {
10
+ const options = {
11
+ ...input,
12
+ protection: {
13
+ ...input.protection,
14
+ context: principalHistoryVerificationContext(input),
15
+ },
16
+ };
17
+ const checkpoint = await loadPrincipalPolicyCheckpoint(options.execSql, publication.policy.principalType, publication.policy.principalId);
18
+ const saved = await loadPrincipalHistoryPrefix(options.execSql, publication.prefix.scopeId);
19
+ const observedPrefixProgress = saved?.progress ?? null;
20
+ if (observedPrefixProgress === publication.previousPrefixProgress)
21
+ return {
22
+ ...publication,
23
+ preservePrefix: false,
24
+ observedPrefixProgress,
25
+ observedCheckpoint: checkpoint,
26
+ retainedPrefix: publication.prefix,
27
+ checkpointPolicy: publication.policy,
28
+ };
29
+ const restored = await restoreAcknowledgedPrincipalPrefix(options, saved);
30
+ if (restored.previous.version < publication.policy.version) {
31
+ if (!principalHeadMatchesReference(restored.previous.state, options.expectedHead))
32
+ throw new KeyingVerificationError("stale_predecessor", "Acknowledgement does not extend the authenticated current prefix");
33
+ return {
34
+ ...publication,
35
+ preservePrefix: false,
36
+ observedPrefixProgress,
37
+ observedCheckpoint: checkpoint,
38
+ retainedPrefix: publication.prefix,
39
+ checkpointPolicy: publication.policy,
40
+ };
41
+ }
42
+ const history = await selectRecoveredPrincipalHistory({
43
+ options: { ...options, retainedReferences: [publication.policy.state] },
44
+ scopeId: publication.prefix.scopeId,
45
+ history: restored.history,
46
+ checkpoint,
47
+ });
48
+ const policy = await verifyPrincipalPolicyCurrent({
49
+ current: restored.artifacts,
50
+ history,
51
+ });
52
+ if (!policy.ok)
53
+ throw policy.error;
54
+ return {
55
+ ...publication,
56
+ preservePrefix: true,
57
+ observedPrefixProgress,
58
+ observedCheckpoint: checkpoint,
59
+ retainedPrefix: restored.saved,
60
+ checkpointPolicy: policy.value,
61
+ };
62
+ }
63
+ //# sourceMappingURL=reconcileAcknowledgedPrincipalCurrent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcileAcknowledgedPrincipalCurrent.js","sourceRoot":"","sources":["reconcileAcknowledgedPrincipalCurrent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAKnG,OAAO,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AACtG,OAAO,EAAE,6BAA6B,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,EAAE,+BAA+B,EAAE,MAAM,kDAAkD,CAAC;AAEnG,OAAO,EAAE,mCAAmC,EAAE,MAAM,oDAAoD,CAAC;AACzG,OAAO,EAAE,kCAAkC,EAAE,MAAM,oCAAoC,CAAC;AAExF,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,qCAAqC,CACzD,KAA2C,EAC3C,WAAoD;IAEpD,MAAM,OAAO,GAAG;QACd,GAAG,KAAK;QACR,UAAU,EAAE;YACV,GAAG,KAAK,CAAC,UAAU;YACnB,OAAO,EAAE,mCAAmC,CAAC,KAAK,CAAC;SACpD;KACF,CAAC;IACF,MAAM,UAAU,GAAG,MAAM,6BAA6B,CACpD,OAAO,CAAC,OAAO,EACf,WAAW,CAAC,MAAM,CAAC,aAAa,EAChC,WAAW,CAAC,MAAM,CAAC,WAAW,CAC/B,CAAC;IACF,MAAM,KAAK,GAAG,MAAM,0BAA0B,CAC5C,OAAO,CAAC,OAAO,EACf,WAAW,CAAC,MAAM,CAAC,OAAO,CAC3B,CAAC;IACF,MAAM,sBAAsB,GAAG,KAAK,EAAE,QAAQ,IAAI,IAAI,CAAC;IACvD,IAAI,sBAAsB,KAAK,WAAW,CAAC,sBAAsB;QAC/D,OAAO;YACL,GAAG,WAAW;YACd,cAAc,EAAE,KAAK;YACrB,sBAAsB;YACtB,kBAAkB,EAAE,UAAU;YAC9B,cAAc,EAAE,WAAW,CAAC,MAAM;YAClC,gBAAgB,EAAE,WAAW,CAAC,MAAM;SACrC,CAAC;IACJ,MAAM,QAAQ,GAAG,MAAM,kCAAkC,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1E,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC3D,IACE,CAAC,6BAA6B,CAC5B,QAAQ,CAAC,QAAQ,CAAC,KAAK,EACvB,OAAO,CAAC,YAAY,CACrB;YAED,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,EACnB,kEAAkE,CACnE,CAAC;QACJ,OAAO;YACL,GAAG,WAAW;YACd,cAAc,EAAE,KAAK;YACrB,sBAAsB;YACtB,kBAAkB,EAAE,UAAU;YAC9B,cAAc,EAAE,WAAW,CAAC,MAAM;YAClC,gBAAgB,EAAE,WAAW,CAAC,MAAM;SACrC,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,+BAA+B,CAAC;QACpD,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,kBAAkB,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;QACvE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO;QACnC,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,UAAU;KACX,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC;QAChD,OAAO,EAAE,QAAQ,CAAC,SAAS;QAC3B,OAAO;KACR,CAAC,CAAC;IACH,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,MAAM,MAAM,CAAC,KAAK,CAAC;IACnC,OAAO;QACL,GAAG,WAAW;QACd,cAAc,EAAE,IAAI;QACpB,sBAAsB;QACtB,kBAAkB,EAAE,UAAU;QAC9B,cAAc,EAAE,QAAQ,CAAC,KAAK;QAC9B,gBAAgB,EAAE,MAAM,CAAC,KAAK;KAC/B,CAAC;AACJ,CAAC","sourcesContent":["import {\n KeyingVerificationError,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../data/persistence/keyingCheckpointPersistence\";\nimport type {\n AcknowledgedPrincipalCurrentPublication,\n ReconciledPrincipalCurrentPublication,\n} from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { loadPrincipalHistoryPrefix } from \"../../data/persistence/principalHistoryPrefixPersistence\";\nimport { principalHeadMatchesReference } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { selectRecoveredPrincipalHistory } from \"../principals/principalHistoryRecoveryReferences\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport { principalHistoryVerificationContext } from \"../principals/principalHistoryRecoveryVerification\";\nimport { restoreAcknowledgedPrincipalPrefix } from \"./acknowledgedPrincipalPredecessor\";\n\n/** Prove an already observed successor contains this receipt before preserving it. */\nexport async function reconcileAcknowledgedPrincipalCurrent(\n input: RecoverPrincipalPolicyHistoryOptions,\n publication: AcknowledgedPrincipalCurrentPublication,\n): Promise<ReconciledPrincipalCurrentPublication> {\n const options = {\n ...input,\n protection: {\n ...input.protection,\n context: principalHistoryVerificationContext(input),\n },\n };\n const checkpoint = await loadPrincipalPolicyCheckpoint(\n options.execSql,\n publication.policy.principalType,\n publication.policy.principalId,\n );\n const saved = await loadPrincipalHistoryPrefix(\n options.execSql,\n publication.prefix.scopeId,\n );\n const observedPrefixProgress = saved?.progress ?? null;\n if (observedPrefixProgress === publication.previousPrefixProgress)\n return {\n ...publication,\n preservePrefix: false,\n observedPrefixProgress,\n observedCheckpoint: checkpoint,\n retainedPrefix: publication.prefix,\n checkpointPolicy: publication.policy,\n };\n const restored = await restoreAcknowledgedPrincipalPrefix(options, saved);\n if (restored.previous.version < publication.policy.version) {\n if (\n !principalHeadMatchesReference(\n restored.previous.state,\n options.expectedHead,\n )\n )\n throw new KeyingVerificationError(\n \"stale_predecessor\",\n \"Acknowledgement does not extend the authenticated current prefix\",\n );\n return {\n ...publication,\n preservePrefix: false,\n observedPrefixProgress,\n observedCheckpoint: checkpoint,\n retainedPrefix: publication.prefix,\n checkpointPolicy: publication.policy,\n };\n }\n const history = await selectRecoveredPrincipalHistory({\n options: { ...options, retainedReferences: [publication.policy.state] },\n scopeId: publication.prefix.scopeId,\n history: restored.history,\n checkpoint,\n });\n const policy = await verifyPrincipalPolicyCurrent({\n current: restored.artifacts,\n history,\n });\n if (!policy.ok) throw policy.error;\n return {\n ...publication,\n preservePrefix: true,\n observedPrefixProgress,\n observedCheckpoint: checkpoint,\n retainedPrefix: restored.saved,\n checkpointPolicy: policy.value,\n };\n}\n"]}
@@ -4,8 +4,11 @@ import type { PrincipalPolicyMutationResponse } from "../../internal/validators/
4
4
  import { type AcknowledgedPrincipalCurrentRetirement } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
5
5
  import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
6
6
  import type { RecoverPrincipalPolicyHistoryOptions } from "../principals/principalHistoryRecoveryTypes.js";
7
+ import { type AcknowledgedPrincipalPredecessor } from "./acknowledgedPrincipalPredecessor.js";
7
8
  export type { AcknowledgedPrincipalCurrentRetirement } from "../../data/persistence/principalCurrentAcknowledgementPersistence.js";
8
9
  export interface AcknowledgedPrincipalCurrentInput {
10
+ /** Capture before submitting the mutation; null only for a new group. */
11
+ readonly predecessor: AcknowledgedPrincipalPredecessor | null;
9
12
  /** Only a newly authored group at version one; never skips a predecessor. */
10
13
  readonly initialGroup?: boolean | undefined;
11
14
  /** The same scoped protection and verification mode used to recover the predecessor. */