@tearleads/client-sdk 0.1.63 → 0.1.64
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.
- package/data/documents/blob/shared/projection.js +1 -1
- package/data/documents/blob/shared/projection.js.map +1 -1
- package/data/documents/shared/projectionContentKeys.js +1 -1
- package/data/documents/shared/projectionContentKeys.js.map +1 -1
- package/data/documents/shared/syncResponseAuthorization.js +1 -1
- package/data/documents/shared/syncResponseAuthorization.js.map +1 -1
- package/data/keyingProjectionVerification/{accessManifestCheckpointEnforcement.js → checkpoints/accessManifestCheckpointEnforcement.js} +2 -2
- package/data/keyingProjectionVerification/checkpoints/accessManifestCheckpointEnforcement.js.map +1 -0
- package/data/keyingProjectionVerification/{bundleVerification.js → checkpoints/bundleVerification.js} +5 -5
- package/data/keyingProjectionVerification/checkpoints/bundleVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{checkpointContext.d.ts → checkpoints/checkpointContext.d.ts} +6 -6
- package/data/keyingProjectionVerification/{checkpointContext.js → checkpoints/checkpointContext.js} +6 -6
- package/data/keyingProjectionVerification/checkpoints/checkpointContext.js.map +1 -0
- package/data/keyingProjectionVerification/{manifestCheckpointVerification.js → checkpoints/manifestCheckpointVerification.js} +2 -2
- package/data/keyingProjectionVerification/checkpoints/manifestCheckpointVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{containerAncestorCitations.js → container/containerAncestorCitations.js} +4 -4
- package/data/keyingProjectionVerification/container/containerAncestorCitations.js.map +1 -0
- package/data/keyingProjectionVerification/{containerCreateManifest.js → container/containerCreateManifest.js} +1 -1
- package/data/keyingProjectionVerification/{containerDestinationVerification.js → container/containerDestinationVerification.js} +4 -4
- package/data/keyingProjectionVerification/container/containerDestinationVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{containerManifestVerification.js → container/containerManifestVerification.js} +7 -7
- package/data/keyingProjectionVerification/container/containerManifestVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{containerPathVerification.js → container/containerPathVerification.js} +2 -2
- package/data/keyingProjectionVerification/container/containerPathVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{containerProjectionVerification.d.ts → container/containerProjectionVerification.d.ts} +7 -7
- package/data/keyingProjectionVerification/{containerProjectionVerification.js → container/containerProjectionVerification.js} +9 -9
- package/data/keyingProjectionVerification/container/containerProjectionVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{documentDependencyPaths.d.ts → document/documentDependencyPaths.d.ts} +1 -1
- package/data/keyingProjectionVerification/{documentDependencyPaths.js → document/documentDependencyPaths.js} +3 -3
- package/data/keyingProjectionVerification/document/documentDependencyPaths.js.map +1 -0
- package/data/keyingProjectionVerification/{documentManifestPolicies.js → document/documentManifestPolicies.js} +2 -2
- package/data/keyingProjectionVerification/document/documentManifestPolicies.js.map +1 -0
- package/data/keyingProjectionVerification/{documentManifestPredecessor.js → document/documentManifestPredecessor.js} +1 -1
- package/data/keyingProjectionVerification/{documentManifestVerification.js → document/documentManifestVerification.js} +5 -5
- package/data/keyingProjectionVerification/document/documentManifestVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{documentProjectionVerification.d.ts → document/documentProjectionVerification.d.ts} +4 -4
- package/data/keyingProjectionVerification/{documentProjectionVerification.js → document/documentProjectionVerification.js} +9 -9
- package/data/keyingProjectionVerification/document/documentProjectionVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgeCheckpointCurrency.js → documentPurge/documentPurgeCheckpointCurrency.js} +12 -12
- package/data/keyingProjectionVerification/documentPurge/documentPurgeCheckpointCurrency.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgeCheckpointEnforcement.js → documentPurge/documentPurgeCheckpointEnforcement.js} +2 -2
- package/data/keyingProjectionVerification/documentPurge/documentPurgeCheckpointEnforcement.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgeDocumentChainVerification.js → documentPurge/documentPurgeDocumentChainVerification.js} +8 -8
- package/data/keyingProjectionVerification/documentPurge/documentPurgeDocumentChainVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgePolicyCheckpoints.js → documentPurge/documentPurgePolicyCheckpoints.js} +2 -2
- package/data/keyingProjectionVerification/documentPurge/documentPurgePolicyCheckpoints.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgePolicyCurrency.js → documentPurge/documentPurgePolicyCurrency.js} +4 -4
- package/data/keyingProjectionVerification/documentPurge/documentPurgePolicyCurrency.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgePrincipalEvidence.js → documentPurge/documentPurgePrincipalEvidence.js} +3 -3
- package/data/keyingProjectionVerification/documentPurge/documentPurgePrincipalEvidence.js.map +1 -0
- package/data/keyingProjectionVerification/{documentPurgeProofVerification.d.ts → documentPurge/documentPurgeProofVerification.d.ts} +5 -5
- package/data/keyingProjectionVerification/{documentPurgeProofVerification.js → documentPurge/documentPurgeProofVerification.js} +10 -10
- package/data/keyingProjectionVerification/documentPurge/documentPurgeProofVerification.js.map +1 -0
- package/data/keyingProjectionVerification/index.d.ts +4 -4
- package/data/keyingProjectionVerification/index.js +4 -4
- package/data/keyingProjectionVerification/index.js.map +1 -1
- package/data/keyingProjectionVerification/{mergeProjectionPolicyEvidence.js → principalPolicy/mergeProjectionPolicyEvidence.js} +2 -2
- package/data/keyingProjectionVerification/principalPolicy/mergeProjectionPolicyEvidence.js.map +1 -0
- package/data/keyingProjectionVerification/{organizationFounderBinding.js → principalPolicy/organizationFounderBinding.js} +3 -3
- package/data/keyingProjectionVerification/principalPolicy/organizationFounderBinding.js.map +1 -0
- package/data/keyingProjectionVerification/{principalPolicyCache.js → principalPolicy/principalPolicyCache.js} +6 -6
- package/data/keyingProjectionVerification/principalPolicy/principalPolicyCache.js.map +1 -0
- package/data/keyingProjectionVerification/{principalPolicyVerification.js → principalPolicy/principalPolicyVerification.js} +12 -12
- package/data/keyingProjectionVerification/principalPolicy/principalPolicyVerification.js.map +1 -0
- package/data/keyingProjectionVerification/{projectionAuthorizationEvidence.js → principalPolicy/projectionAuthorizationEvidence.js} +3 -3
- package/data/keyingProjectionVerification/principalPolicy/projectionAuthorizationEvidence.js.map +1 -0
- package/data/keyingProjectionVerification/{projectionPolicyEvidence.js → principalPolicy/projectionPolicyEvidence.js} +3 -3
- package/data/keyingProjectionVerification/principalPolicy/projectionPolicyEvidence.js.map +1 -0
- package/data/keyingProjectionVerification/{resolvedPrincipalPolicy.js → principalPolicy/resolvedPrincipalPolicy.js} +6 -6
- package/data/keyingProjectionVerification/principalPolicy/resolvedPrincipalPolicy.js.map +1 -0
- package/package.json +1 -1
- package/stores/container-contents/accessRestorationSweep.js +1 -1
- package/stores/container-contents/accessRestorationSweep.js.map +1 -1
- package/stores/container-contents/containerContentsStore.d.ts +1 -1
- package/stores/container-contents/containerContentsStore.js +12 -12
- package/stores/container-contents/containerContentsStore.js.map +1 -1
- package/stores/container-contents/containerState/containerStateMap.js.map +1 -0
- package/stores/container-contents/{containerStatePersistence.js → containerState/containerStatePersistence.js} +2 -2
- package/stores/container-contents/containerState/containerStatePersistence.js.map +1 -0
- package/stores/container-contents/{missingContainerState.js → containerState/missingContainerState.js} +1 -1
- package/stores/container-contents/containerState/missingContainerState.js.map +1 -0
- package/stores/container-contents/containerState/missingSyncedContainerState.js.map +1 -0
- package/stores/container-contents/{reconcilableContainer.d.ts → containerState/reconcilableContainer.d.ts} +1 -1
- package/stores/container-contents/containerState/reconcilableContainer.js.map +1 -0
- package/stores/container-contents/{documentRecovery.js → documentWork/documentRecovery.js} +6 -6
- package/stores/container-contents/documentWork/documentRecovery.js.map +1 -0
- package/stores/container-contents/{documentRotation.js → documentWork/documentRotation.js} +2 -2
- package/stores/container-contents/documentWork/documentRotation.js.map +1 -0
- package/stores/container-contents/{documentWork.js → documentWork/index.js} +1 -1
- package/stores/container-contents/documentWork/index.js.map +1 -0
- package/stores/container-contents/{backgroundHydration.js → hydration/backgroundHydration.js} +3 -3
- package/stores/container-contents/hydration/backgroundHydration.js.map +1 -0
- package/stores/container-contents/{remoteHydrationRequest.js → hydration/remoteHydrationRequest.js} +3 -3
- package/stores/container-contents/hydration/remoteHydrationRequest.js.map +1 -0
- package/stores/container-contents/{startupHydration.js → hydration/startupHydration.js} +3 -3
- package/stores/container-contents/hydration/startupHydration.js.map +1 -0
- package/stores/container-contents/index.d.ts +3 -3
- package/stores/container-contents/index.js +2 -2
- package/stores/container-contents/index.js.map +1 -1
- package/stores/container-contents/localRefresh.js +2 -2
- package/stores/container-contents/localRefresh.js.map +1 -1
- package/stores/container-contents/{containerPurgeCore.js → operations/containerPurgeCore.js} +4 -4
- package/stores/container-contents/operations/containerPurgeCore.js.map +1 -0
- package/stores/container-contents/operations/emptyTrashOperation.js.map +1 -0
- package/stores/container-contents/{groupRewrapOperation.js → operations/groupRewrapOperation.js} +2 -2
- package/stores/container-contents/operations/groupRewrapOperation.js.map +1 -0
- package/stores/container-contents/{operations.js → operations/index.js} +18 -18
- package/stores/container-contents/operations/index.js.map +1 -0
- package/stores/container-contents/operations/purgeContainerOperation.js.map +1 -0
- package/stores/container-contents/{reportShareFailure.js → operations/reportShareFailure.js} +4 -4
- package/stores/container-contents/operations/reportShareFailure.js.map +1 -0
- package/stores/container-contents/{setContainerIconOperation.js → operations/setContainerIconOperation.js} +6 -6
- package/stores/container-contents/operations/setContainerIconOperation.js.map +1 -0
- package/stores/container-contents/{shareOperations.js → operations/shareOperations.js} +6 -6
- package/stores/container-contents/operations/shareOperations.js.map +1 -0
- package/stores/container-contents/remoteEvents/remoteBackedContainerState.js.map +1 -0
- package/stores/container-contents/{remoteContainerIngestion.js → remoteEvents/remoteContainerIngestion.js} +4 -4
- package/stores/container-contents/remoteEvents/remoteContainerIngestion.js.map +1 -0
- package/stores/container-contents/{remoteEventProjectionInvalidation.js → remoteEvents/remoteEventProjectionInvalidation.js} +1 -1
- package/stores/container-contents/remoteEvents/remoteEventProjectionInvalidation.js.map +1 -0
- package/stores/container-contents/{remoteEventSync.js → remoteEvents/remoteEventSync.js} +4 -4
- package/stores/container-contents/remoteEvents/remoteEventSync.js.map +1 -0
- package/stores/container-contents/{remoteWriteGuards.js → remoteWrites/remoteWriteGuards.js} +2 -2
- package/stores/container-contents/remoteWrites/remoteWriteGuards.js.map +1 -0
- package/stores/container-contents/{remoteWriteQueue.js → remoteWrites/remoteWriteQueue.js} +1 -1
- package/stores/container-contents/remoteWrites/remoteWriteQueue.js.map +1 -0
- package/stores/container-contents/remoteWrites/writeGeneration.js.map +1 -0
- package/stores/container-contents/state.d.ts +1 -1
- package/stores/container-contents/state.js +2 -2
- package/stores/container-contents/state.js.map +1 -1
- package/stores/container-contents/{syncAgent.d.ts → syncAgent/index.d.ts} +2 -2
- package/stores/container-contents/{syncAgent.js → syncAgent/index.js} +14 -14
- package/stores/container-contents/syncAgent/index.js.map +1 -0
- package/stores/container-contents/{metadataSyncSignal.js → syncAgent/metadataSyncSignal.js} +1 -1
- package/stores/container-contents/{metadataSyncSignal.js.map → syncAgent/metadataSyncSignal.js.map} +1 -1
- package/stores/container-contents/{syncAgentTypes.d.ts → syncAgent/syncAgentTypes.d.ts} +5 -5
- package/stores/container-contents/syncAgent/syncAgentTypes.js.map +1 -0
- package/stores/container-contents/{syncLaneIteration.js → syncAgent/syncLaneIteration.js} +11 -11
- package/stores/container-contents/syncAgent/syncLaneIteration.js.map +1 -0
- package/stores/container-contents/{existingSystemContainer.js → systemContainers/existingSystemContainer.js} +4 -4
- package/stores/container-contents/systemContainers/existingSystemContainer.js.map +1 -0
- package/stores/container-contents/{organizationMetadataSystemContainer.js → systemContainers/organizationMetadataSystemContainer.js} +2 -2
- package/stores/container-contents/systemContainers/organizationMetadataSystemContainer.js.map +1 -0
- package/stores/container-contents/{systemContainerHydration.js → systemContainers/systemContainerHydration.js} +3 -3
- package/stores/container-contents/systemContainers/systemContainerHydration.js.map +1 -0
- package/stores/container-contents/{systemContainerIcon.js → systemContainers/systemContainerIcon.js} +5 -5
- package/stores/container-contents/systemContainers/systemContainerIcon.js.map +1 -0
- package/stores/container-contents/systemContainers/systemContainerLookup.js.map +1 -0
- package/stores/container-contents/{systemContainerPostCreate.js → systemContainers/systemContainerPostCreate.js} +2 -2
- package/stores/container-contents/systemContainers/systemContainerPostCreate.js.map +1 -0
- package/stores/container-contents/{systemContainerPromotion.js → systemContainers/systemContainerPromotion.js} +1 -1
- package/stores/container-contents/systemContainers/systemContainerPromotion.js.map +1 -0
- package/stores/container-contents/types.d.ts +2 -2
- package/stores/container-contents/types.js.map +1 -1
- package/stores/documents/documentStore/{attachmentSourceUpload.js → attachmentUpload/attachmentSourceUpload.js} +4 -4
- package/stores/documents/documentStore/attachmentUpload/attachmentSourceUpload.js.map +1 -0
- package/stores/documents/documentStore/{attachmentStaging.js → attachmentUpload/attachmentStaging.js} +5 -5
- package/stores/documents/documentStore/attachmentUpload/attachmentStaging.js.map +1 -0
- package/stores/documents/documentStore/{attachmentUploadAttempt.js → attachmentUpload/attachmentUploadAttempt.js} +2 -2
- package/stores/documents/documentStore/attachmentUpload/attachmentUploadAttempt.js.map +1 -0
- package/stores/documents/documentStore/{attachmentUploadLane.js → attachmentUpload/attachmentUploadLane.js} +1 -1
- package/stores/documents/documentStore/attachmentUpload/attachmentUploadLane.js.map +1 -0
- package/stores/documents/documentStore/{attachmentUploadResume.js → attachmentUpload/attachmentUploadResume.js} +4 -4
- package/stores/documents/documentStore/attachmentUpload/attachmentUploadResume.js.map +1 -0
- package/stores/documents/documentStore/{attachmentDetachState.js → attachments/attachmentDetachState.js} +1 -1
- package/stores/documents/documentStore/attachments/attachmentDetachState.js.map +1 -0
- package/stores/documents/documentStore/{attachmentHydration.js → attachments/attachmentHydration.js} +5 -5
- package/stores/documents/documentStore/attachments/attachmentHydration.js.map +1 -0
- package/stores/documents/documentStore/{attachmentHydrationCommit.js → attachments/attachmentHydrationCommit.js} +3 -3
- package/stores/documents/documentStore/attachments/attachmentHydrationCommit.js.map +1 -0
- package/stores/documents/documentStore/{attachmentIntents.js → attachments/attachmentIntents.js} +2 -2
- package/stores/documents/documentStore/attachments/attachmentIntents.js.map +1 -0
- package/stores/documents/documentStore/{attachmentMutationPersistence.js → attachments/attachmentMutationPersistence.js} +4 -4
- package/stores/documents/documentStore/attachments/attachmentMutationPersistence.js.map +1 -0
- package/stores/documents/documentStore/attachments/attachmentPersistFollowup.js.map +1 -0
- package/stores/documents/documentStore/{attachmentPersistence.js → attachments/attachmentPersistence.js} +4 -4
- package/stores/documents/documentStore/attachments/attachmentPersistence.js.map +1 -0
- package/stores/documents/documentStore/{attachmentRemoval.js → attachments/attachmentRemoval.js} +11 -11
- package/stores/documents/documentStore/attachments/attachmentRemoval.js.map +1 -0
- package/stores/documents/documentStore/attachments/attachmentSnapshot.js.map +1 -0
- package/stores/documents/documentStore/{attachmentWriteGeneration.js → attachments/attachmentWriteGeneration.js} +2 -2
- package/stores/documents/documentStore/attachments/attachmentWriteGeneration.js.map +1 -0
- package/stores/documents/documentStore/{attachments.js → attachments/index.js} +11 -11
- package/stores/documents/documentStore/attachments/index.js.map +1 -0
- package/stores/documents/documentStore/{documentHistoryCompaction.js → history/documentHistoryCompaction.js} +4 -4
- package/stores/documents/documentStore/history/documentHistoryCompaction.js.map +1 -0
- package/stores/documents/documentStore/{durableDocumentReload.js → history/durableDocumentReload.js} +6 -6
- package/stores/documents/documentStore/history/durableDocumentReload.js.map +1 -0
- package/stores/documents/documentStore/{historyRebuild.js → history/historyRebuild.js} +6 -6
- package/stores/documents/documentStore/history/historyRebuild.js.map +1 -0
- package/stores/documents/{documentStore.d.ts → documentStore/index.d.ts} +5 -5
- package/stores/documents/{documentStore.js → documentStore/index.js} +18 -18
- package/stores/documents/documentStore/index.js.map +1 -0
- package/stores/documents/documentStore/{deferredInitialUpdate.js → initialization/deferredInitialUpdate.js} +9 -9
- package/stores/documents/documentStore/initialization/deferredInitialUpdate.js.map +1 -0
- package/stores/documents/documentStore/{initialization.js → initialization/index.js} +14 -14
- package/stores/documents/documentStore/initialization/index.js.map +1 -0
- package/stores/documents/documentStore/{initializationAttachments.js → initialization/initializationAttachments.js} +1 -1
- package/stores/documents/documentStore/initialization/initializationAttachments.js.map +1 -0
- package/stores/documents/documentStore/{initializationHistory.js → initialization/initializationHistory.js} +3 -3
- package/stores/documents/documentStore/initialization/initializationHistory.js.map +1 -0
- package/stores/documents/documentStore/{initializationRecovery.js → initialization/initializationRecovery.js} +7 -7
- package/stores/documents/documentStore/initialization/initializationRecovery.js.map +1 -0
- package/stores/documents/documentStore/mutationIdentityRevalidation.js.map +1 -1
- package/stores/documents/documentStore/mutations.js +2 -2
- package/stores/documents/documentStore/mutations.js.map +1 -1
- package/stores/documents/documentStore/pendingUpdateRefusal.js +1 -1
- package/stores/documents/documentStore/pendingUpdateRefusal.js.map +1 -1
- package/stores/documents/documentStore/persistence.js +3 -3
- package/stores/documents/documentStore/persistence.js.map +1 -1
- package/stores/documents/documentStore/{rotation.js → rotation/index.js} +14 -14
- package/stores/documents/documentStore/rotation/index.js.map +1 -0
- package/stores/documents/documentStore/{rotationProvenance.js → rotation/rotationProvenance.js} +2 -2
- package/stores/documents/documentStore/rotation/rotationProvenance.js.map +1 -0
- package/stores/documents/documentStore/{rotationSettlement.js → rotation/rotationSettlement.js} +9 -9
- package/stores/documents/documentStore/rotation/rotationSettlement.js.map +1 -0
- package/stores/documents/documentStore/rows.js +2 -2
- package/stores/documents/documentStore/rows.js.map +1 -1
- package/stores/documents/documentStore/state.js +1 -1
- package/stores/documents/documentStore/state.js.map +1 -1
- package/stores/documents/documentStore/{sync.js → sync/index.js} +7 -7
- package/stores/documents/documentStore/sync/index.js.map +1 -0
- package/stores/documents/documentStore/{pullContinuationInvalidation.js → sync/pullContinuationInvalidation.js} +3 -3
- package/stores/documents/documentStore/sync/pullContinuationInvalidation.js.map +1 -0
- package/stores/documents/documentStore/{remoteRevalidationTelemetry.js → sync/remoteRevalidationTelemetry.js} +1 -1
- package/stores/documents/documentStore/sync/remoteRevalidationTelemetry.js.map +1 -0
- package/stores/documents/documentStore/sync/remoteWork.js.map +1 -0
- package/stores/documents/documentStore/sync/syncAcceptedUpdateIds.js.map +1 -0
- package/stores/documents/documentStore/{syncAttachmentSettlement.js → sync/syncAttachmentSettlement.js} +3 -3
- package/stores/documents/documentStore/sync/syncAttachmentSettlement.js.map +1 -0
- package/stores/documents/documentStore/{syncAttachments.js → sync/syncAttachments.js} +7 -7
- package/stores/documents/documentStore/sync/syncAttachments.js.map +1 -0
- package/stores/documents/documentStore/{syncDetachedAttachments.js → sync/syncDetachedAttachments.js} +7 -7
- package/stores/documents/documentStore/sync/syncDetachedAttachments.js.map +1 -0
- package/stores/documents/documentStore/{syncFinalize.js → sync/syncFinalize.js} +9 -9
- package/stores/documents/documentStore/sync/syncFinalize.js.map +1 -0
- package/stores/documents/documentStore/sync/syncGeneration.js.map +1 -0
- package/stores/documents/documentStore/{syncOutgoingCoverage.js → sync/syncOutgoingCoverage.js} +4 -4
- package/stores/documents/documentStore/sync/syncOutgoingCoverage.js.map +1 -0
- package/stores/documents/documentStore/{syncRemoteSignals.js → sync/syncRemoteSignals.js} +4 -4
- package/stores/documents/documentStore/sync/syncRemoteSignals.js.map +1 -0
- package/stores/documents/documentStore/{syncRequest.js → sync/syncRequest.js} +8 -8
- package/stores/documents/documentStore/sync/syncRequest.js.map +1 -0
- package/stores/documents/documentStore/{syncShared.js → sync/syncShared.js} +8 -8
- package/stores/documents/documentStore/sync/syncShared.js.map +1 -0
- package/stores/documents/documentStore/{syncUpdateImport.js → sync/syncUpdateImport.js} +3 -3
- package/stores/documents/documentStore/sync/syncUpdateImport.js.map +1 -0
- package/stores/documents/documentStore/{versionCoverage.js → sync/versionCoverage.js} +1 -1
- package/stores/documents/index.d.ts +1 -1
- package/stores/documents/index.js +1 -1
- package/stores/local-projection/localProjectionStore.d.ts +1 -1
- package/stores/local-projection/localProjectionStore.js +1 -1
- package/stores/local-projection/localProjectionStore.js.map +1 -1
- package/stores/local-projection/registry.d.ts +1 -1
- package/stores/local-projection/types.d.ts +1 -1
- package/workflows/blobs/hydration/decrypt.js +1 -1
- package/workflows/blobs/hydration/decrypt.js.map +1 -1
- package/workflows/container-contents/container-state/{createAdoption.js → create/createAdoption.js} +6 -6
- package/workflows/container-contents/container-state/create/createAdoption.js.map +1 -0
- package/workflows/container-contents/container-state/{createChild.js → create/createChild.js} +7 -7
- package/workflows/container-contents/container-state/create/createChild.js.map +1 -0
- package/workflows/container-contents/container-state/{createIntentDepth.js → create/createIntentDepth.js} +2 -2
- package/workflows/container-contents/container-state/create/createIntentDepth.js.map +1 -0
- package/workflows/container-contents/container-state/create/createIntentSettlement.js.map +1 -0
- package/workflows/container-contents/container-state/{createIntentSync.js → create/createIntentSync.js} +7 -7
- package/workflows/container-contents/container-state/create/createIntentSync.js.map +1 -0
- package/workflows/container-contents/container-state/{createTerminalFailure.js → create/createTerminalFailure.js} +2 -2
- package/workflows/container-contents/container-state/create/createTerminalFailure.js.map +1 -0
- package/workflows/container-contents/container-state/{createWithMetadata.js → create/createWithMetadata.js} +9 -9
- package/workflows/container-contents/container-state/create/createWithMetadata.js.map +1 -0
- package/workflows/container-contents/container-state/{createWithMetadataPlan.js → create/createWithMetadataPlan.js} +4 -4
- package/workflows/container-contents/container-state/create/createWithMetadataPlan.js.map +1 -0
- package/workflows/container-contents/container-state/{localPurgeScope.js → purge/localPurgeScope.js} +1 -1
- package/workflows/container-contents/container-state/purge/localPurgeScope.js.map +1 -0
- package/workflows/container-contents/container-state/{purgeTree.js → purge/purgeTree.js} +5 -5
- package/workflows/container-contents/container-state/purge/purgeTree.js.map +1 -0
- package/workflows/container-contents/container-state/purge/purgeTreeCollection.js.map +1 -0
- package/workflows/container-contents/container-state/{purgeTreeContainerDeletion.js → purge/purgeTreeContainerDeletion.js} +1 -1
- package/workflows/container-contents/container-state/purge/purgeTreeContainerDeletion.js.map +1 -0
- package/workflows/container-contents/container-state/{purgeTreeScope.js → purge/purgeTreeScope.js} +8 -8
- package/workflows/container-contents/container-state/purge/purgeTreeScope.js.map +1 -0
- package/workflows/container-contents/container-state/{readLocalPurgeScope.js → purge/readLocalPurgeScope.js} +3 -3
- package/workflows/container-contents/container-state/purge/readLocalPurgeScope.js.map +1 -0
- package/workflows/container-contents/container-state/remote.js +2 -2
- package/workflows/container-contents/container-state/remote.js.map +1 -1
- package/workflows/container-contents/container-state/{groupGrantVerification.js → share/groupGrantVerification.js} +8 -8
- package/workflows/container-contents/container-state/share/groupGrantVerification.js.map +1 -0
- package/workflows/container-contents/container-state/{groupShareEpoch.js → share/groupShareEpoch.js} +2 -2
- package/workflows/container-contents/container-state/share/groupShareEpoch.js.map +1 -0
- package/workflows/container-contents/container-state/{share.js → share/index.js} +8 -8
- package/workflows/container-contents/container-state/share/index.js.map +1 -0
- package/workflows/container-contents/container-state/{sharePersistence.js → share/sharePersistence.js} +3 -3
- package/workflows/container-contents/container-state/share/sharePersistence.js.map +1 -0
- package/workflows/container-contents/documentDiscovery/documentDiscoveryApply.js +1 -1
- package/workflows/container-contents/documentDiscovery/documentDiscoveryApply.js.map +1 -1
- package/workflows/container-contents/documentDiscovery/index.js +1 -1
- package/workflows/container-contents/documentDiscovery/index.js.map +1 -1
- package/workflows/container-contents/metadata/metadataSyncErrors.js +1 -1
- package/workflows/container-contents/metadata/metadataSyncErrors.js.map +1 -1
- package/workflows/container-contents/remoteHydration/destination/destinationPrefetch.js.map +1 -0
- package/workflows/container-contents/remoteHydration/destination/destinationRoleCache.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{destinationRootReload.js → destination/destinationRootReload.js} +1 -1
- package/workflows/container-contents/remoteHydration/destination/destinationRootReload.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{replacementBinding.js → destination/replacementBinding.js} +5 -5
- package/workflows/container-contents/remoteHydration/destination/replacementBinding.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{verifiedDestination.js → destination/verifiedDestination.js} +9 -9
- package/workflows/container-contents/remoteHydration/destination/verifiedDestination.js.map +1 -0
- package/workflows/container-contents/remoteHydration/index.js +4 -4
- package/workflows/container-contents/remoteHydration/index.js.map +1 -1
- package/workflows/container-contents/remoteHydration/lanes/childIndex.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{laneFetchMarkers.js → lanes/laneFetchMarkers.js} +1 -1
- package/workflows/container-contents/remoteHydration/lanes/laneFetchMarkers.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{parentLaneFetch.js → lanes/parentLaneFetch.js} +2 -2
- package/workflows/container-contents/remoteHydration/lanes/parentLaneFetch.js.map +1 -0
- package/workflows/container-contents/remoteHydration/lanes/parentLaneQueue.js.map +1 -0
- package/workflows/container-contents/remoteHydration/principalPolicyCache.js +1 -1
- package/workflows/container-contents/remoteHydration/principalPolicyCache.js.map +1 -1
- package/workflows/container-contents/remoteHydration/reconciliation.js +2 -2
- package/workflows/container-contents/remoteHydration/reconciliation.js.map +1 -1
- package/workflows/container-contents/remoteHydration/remoteContainers/containerStateFingerprint.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{insertRemoteContainer.js → remoteContainers/insertRemoteContainer.js} +6 -6
- package/workflows/container-contents/remoteHydration/remoteContainers/insertRemoteContainer.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{remoteContainerPageHydration.js → remoteContainers/remoteContainerPageHydration.js} +7 -7
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js.map +1 -0
- package/workflows/container-contents/remoteHydration/{remoteContainerState.js → remoteContainers/remoteContainerState.js} +9 -9
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerState.js.map +1 -0
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerTimestamps.js.map +1 -0
- package/workflows/container-contents/remoteHydration/tombstoneApplication.js +2 -2
- package/workflows/container-contents/remoteHydration/tombstoneApplication.js.map +1 -1
- package/workflows/containers/child/{createProjection.d.ts → create/createProjection.d.ts} +2 -2
- package/workflows/containers/child/{createProjection.js → create/createProjection.js} +2 -2
- package/workflows/containers/child/create/createProjection.js.map +1 -0
- package/workflows/containers/child/{createSubmission.d.ts → create/createSubmission.d.ts} +7 -7
- package/workflows/containers/child/{createSubmission.js → create/createSubmission.js} +2 -2
- package/workflows/containers/child/create/createSubmission.js.map +1 -0
- package/workflows/containers/child/{create.d.ts → create/index.d.ts} +5 -5
- package/workflows/containers/child/{create.js → create/index.js} +15 -15
- package/workflows/containers/child/create/index.js.map +1 -0
- package/workflows/containers/child/{move.d.ts → move/index.d.ts} +5 -5
- package/workflows/containers/child/{move.js → move/index.js} +12 -12
- package/workflows/containers/child/move/index.js.map +1 -0
- package/workflows/containers/child/{moveArtifacts.js → move/moveArtifacts.js} +3 -3
- package/workflows/containers/child/move/moveArtifacts.js.map +1 -0
- package/workflows/containers/child/{moveRotation.js → move/moveRotation.js} +3 -3
- package/workflows/containers/child/move/moveRotation.js.map +1 -0
- package/workflows/containers/child/{moveWraps.js → move/moveWraps.js} +5 -5
- package/workflows/containers/child/move/moveWraps.js.map +1 -0
- package/workflows/containers/child/mutationSubmit.js +1 -1
- package/workflows/containers/child/mutationSubmit.js.map +1 -1
- package/workflows/containers/child/{carriedDescendantRekeys.js → rekey/carriedDescendantRekeys.js} +4 -4
- package/workflows/containers/child/rekey/carriedDescendantRekeys.js.map +1 -0
- package/workflows/containers/child/{rekey.d.ts → rekey/index.d.ts} +6 -6
- package/workflows/containers/child/{rekey.js → rekey/index.js} +13 -13
- package/workflows/containers/child/rekey/index.js.map +1 -0
- package/workflows/containers/child/{keyringOverrideLineage.d.ts → rekey/keyringOverrideLineage.d.ts} +1 -1
- package/workflows/containers/child/{keyringOverrideLineage.js → rekey/keyringOverrideLineage.js} +1 -1
- package/workflows/containers/child/{rekeyProjection.d.ts → rekey/rekeyProjection.d.ts} +2 -2
- package/workflows/containers/child/{rekeyProjection.js → rekey/rekeyProjection.js} +3 -3
- package/workflows/containers/child/rekey/rekeyProjection.js.map +1 -0
- package/workflows/containers/child/{rekeyRemote.d.ts → rekey/rekeyRemote.d.ts} +6 -6
- package/workflows/containers/child/{rekeyRemote.js → rekey/rekeyRemote.js} +2 -2
- package/workflows/containers/child/rekey/rekeyRemote.js.map +1 -0
- package/workflows/containers/child/revoke.js +5 -5
- package/workflows/containers/child/revoke.js.map +1 -1
- package/workflows/containers/child/{replacementPrincipalPolicyReferences.js → rotation/replacementPrincipalPolicyReferences.js} +2 -2
- package/workflows/containers/child/rotation/replacementPrincipalPolicyReferences.js.map +1 -0
- package/workflows/containers/child/{rotationContext.js → rotation/rotationContext.js} +5 -5
- package/workflows/containers/child/rotation/rotationContext.js.map +1 -0
- package/workflows/containers/child/{rotationPrincipalPolicies.js → rotation/rotationPrincipalPolicies.js} +2 -2
- package/workflows/containers/child/rotation/rotationPrincipalPolicies.js.map +1 -0
- package/workflows/containers/child/{rotationWraps.js → rotation/rotationWraps.js} +1 -1
- package/workflows/containers/child/rotation/rotationWraps.js.map +1 -0
- package/workflows/containers/child/{currentShareGrantMutation.js → share/currentShareGrantMutation.js} +6 -6
- package/workflows/containers/child/share/currentShareGrantMutation.js.map +1 -0
- package/workflows/containers/child/{currentSharePrincipalPolicy.js → share/currentSharePrincipalPolicy.js} +10 -10
- package/workflows/containers/child/share/currentSharePrincipalPolicy.js.map +1 -0
- package/workflows/containers/child/{share.d.ts → share/index.d.ts} +8 -8
- package/workflows/containers/child/{share.js → share/index.js} +10 -10
- package/workflows/containers/child/share/index.js.map +1 -0
- package/workflows/containers/child/{runtimeCurrentGroupShare.js → share/runtimeCurrentGroupShare.js} +6 -6
- package/workflows/containers/child/share/runtimeCurrentGroupShare.js.map +1 -0
- package/workflows/containers/child/{shareAncestorRepair.js → share/shareAncestorRepair.js} +4 -4
- package/workflows/containers/child/share/shareAncestorRepair.js.map +1 -0
- package/workflows/containers/child/{shareMaterialization.d.ts → share/shareMaterialization.d.ts} +5 -5
- package/workflows/containers/child/{shareMaterialization.js → share/shareMaterialization.js} +7 -7
- package/workflows/containers/child/share/shareMaterialization.js.map +1 -0
- package/workflows/containers/child/{sharePlanCore.d.ts → share/sharePlanCore.d.ts} +7 -7
- package/workflows/containers/child/{sharePlanCore.js → share/sharePlanCore.js} +6 -6
- package/workflows/containers/child/share/sharePlanCore.js.map +1 -0
- package/workflows/containers/child/{sharePrincipalPolicy.d.ts → share/sharePrincipalPolicy.d.ts} +9 -9
- package/workflows/containers/child/{sharePrincipalPolicy.js → share/sharePrincipalPolicy.js} +13 -13
- package/workflows/containers/child/share/sharePrincipalPolicy.js.map +1 -0
- package/workflows/containers/child/share/shareProjection.js.map +1 -0
- package/workflows/containers/index.d.ts +10 -10
- package/workflows/containers/index.js +10 -10
- package/workflows/containers/index.js.map +1 -1
- package/workflows/documents/linkSet/linkSetAuthority.js +1 -1
- package/workflows/documents/linkSet/linkSetAuthority.js.map +1 -1
- package/workflows/documents/linkSet/linkSetBlobRewraps.js +1 -1
- package/workflows/documents/linkSet/linkSetBlobRewraps.js.map +1 -1
- package/workflows/documents/linkSet/linkSetProjectionSeed.js +1 -1
- package/workflows/documents/linkSet/linkSetProjectionSeed.js.map +1 -1
- package/workflows/documents/purge/index.js +1 -1
- package/workflows/documents/purge/index.js.map +1 -1
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js +2 -2
- package/workflows/documents/syncRekeys/syncAutomaticContainerRekeys.js.map +1 -1
- package/workflows/organizations/rematerialization/precedingPrincipalRematerialization.js +1 -1
- package/workflows/organizations/rematerialization/precedingPrincipalRematerialization.js.map +1 -1
- package/workflows/organizations/rematerialization/principalContainerRematerialization.js +5 -5
- package/workflows/organizations/rematerialization/principalContainerRematerialization.js.map +1 -1
- package/workflows/organizations/rematerialization/principalContainerRematerializationPlanning.js +1 -1
- package/workflows/organizations/rematerialization/principalContainerRematerializationPlanning.js.map +1 -1
- package/workflows/organizations/rematerialization/principalContainerRematerializationTargets.js +1 -1
- package/workflows/organizations/rematerialization/principalContainerRematerializationTargets.js.map +1 -1
- package/workflows/principals/policyCache/index.js +1 -1
- package/workflows/principals/policyCache/index.js.map +1 -1
- package/workflows/principals/policyRepair.js +1 -1
- package/workflows/principals/policyRepair.js.map +1 -1
- package/workflows/registration/organizationProvisioningArtifacts.d.ts +1 -1
- package/workflows/registration/provisioningBootstrapBuilders.js +1 -1
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +0 -1
- package/data/keyingProjectionVerification/bundleVerification.js.map +0 -1
- package/data/keyingProjectionVerification/checkpointContext.js.map +0 -1
- package/data/keyingProjectionVerification/containerAncestorCitations.js.map +0 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js.map +0 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js.map +0 -1
- package/data/keyingProjectionVerification/containerPathVerification.js.map +0 -1
- package/data/keyingProjectionVerification/containerProjectionVerification.js.map +0 -1
- package/data/keyingProjectionVerification/documentDependencyPaths.js.map +0 -1
- package/data/keyingProjectionVerification/documentManifestPolicies.js.map +0 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js.map +0 -1
- package/data/keyingProjectionVerification/documentProjectionVerification.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgeCheckpointCurrency.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgeCheckpointEnforcement.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgePolicyCheckpoints.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgePolicyCurrency.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgePrincipalEvidence.js.map +0 -1
- package/data/keyingProjectionVerification/documentPurgeProofVerification.js.map +0 -1
- package/data/keyingProjectionVerification/manifestCheckpointVerification.js.map +0 -1
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js.map +0 -1
- package/data/keyingProjectionVerification/organizationFounderBinding.js.map +0 -1
- package/data/keyingProjectionVerification/principalPolicyCache.js.map +0 -1
- package/data/keyingProjectionVerification/principalPolicyVerification.js.map +0 -1
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js.map +0 -1
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +0 -1
- package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js.map +0 -1
- package/stores/container-contents/backgroundHydration.js.map +0 -1
- package/stores/container-contents/containerPurgeCore.js.map +0 -1
- package/stores/container-contents/containerStateMap.js.map +0 -1
- package/stores/container-contents/containerStatePersistence.js.map +0 -1
- package/stores/container-contents/documentRecovery.js.map +0 -1
- package/stores/container-contents/documentRotation.js.map +0 -1
- package/stores/container-contents/documentWork.js.map +0 -1
- package/stores/container-contents/emptyTrashOperation.js.map +0 -1
- package/stores/container-contents/existingSystemContainer.js.map +0 -1
- package/stores/container-contents/groupRewrapOperation.js.map +0 -1
- package/stores/container-contents/missingContainerState.js.map +0 -1
- package/stores/container-contents/missingSyncedContainerState.js.map +0 -1
- package/stores/container-contents/operations.js.map +0 -1
- package/stores/container-contents/organizationMetadataSystemContainer.js.map +0 -1
- package/stores/container-contents/purgeContainerOperation.js.map +0 -1
- package/stores/container-contents/reconcilableContainer.js.map +0 -1
- package/stores/container-contents/remoteBackedContainerState.js.map +0 -1
- package/stores/container-contents/remoteContainerIngestion.js.map +0 -1
- package/stores/container-contents/remoteEventProjectionInvalidation.js.map +0 -1
- package/stores/container-contents/remoteEventSync.js.map +0 -1
- package/stores/container-contents/remoteHydrationRequest.js.map +0 -1
- package/stores/container-contents/remoteWriteGuards.js.map +0 -1
- package/stores/container-contents/remoteWriteQueue.js.map +0 -1
- package/stores/container-contents/reportShareFailure.js.map +0 -1
- package/stores/container-contents/setContainerIconOperation.js.map +0 -1
- package/stores/container-contents/shareOperations.js.map +0 -1
- package/stores/container-contents/startupHydration.js.map +0 -1
- package/stores/container-contents/syncAgent.js.map +0 -1
- package/stores/container-contents/syncAgentTypes.js.map +0 -1
- package/stores/container-contents/syncLaneIteration.js.map +0 -1
- package/stores/container-contents/systemContainerHydration.js.map +0 -1
- package/stores/container-contents/systemContainerIcon.js.map +0 -1
- package/stores/container-contents/systemContainerLookup.js.map +0 -1
- package/stores/container-contents/systemContainerPostCreate.js.map +0 -1
- package/stores/container-contents/systemContainerPromotion.js.map +0 -1
- package/stores/container-contents/writeGeneration.js.map +0 -1
- package/stores/documents/documentStore/attachmentDetachState.js.map +0 -1
- package/stores/documents/documentStore/attachmentHydration.js.map +0 -1
- package/stores/documents/documentStore/attachmentHydrationCommit.js.map +0 -1
- package/stores/documents/documentStore/attachmentIntents.js.map +0 -1
- package/stores/documents/documentStore/attachmentMutationPersistence.js.map +0 -1
- package/stores/documents/documentStore/attachmentPersistFollowup.js.map +0 -1
- package/stores/documents/documentStore/attachmentPersistence.js.map +0 -1
- package/stores/documents/documentStore/attachmentRemoval.js.map +0 -1
- package/stores/documents/documentStore/attachmentSnapshot.js.map +0 -1
- package/stores/documents/documentStore/attachmentSourceUpload.js.map +0 -1
- package/stores/documents/documentStore/attachmentStaging.js.map +0 -1
- package/stores/documents/documentStore/attachmentUploadAttempt.js.map +0 -1
- package/stores/documents/documentStore/attachmentUploadLane.js.map +0 -1
- package/stores/documents/documentStore/attachmentUploadResume.js.map +0 -1
- package/stores/documents/documentStore/attachmentWriteGeneration.js.map +0 -1
- package/stores/documents/documentStore/attachments.js.map +0 -1
- package/stores/documents/documentStore/deferredInitialUpdate.js.map +0 -1
- package/stores/documents/documentStore/documentHistoryCompaction.js.map +0 -1
- package/stores/documents/documentStore/durableDocumentReload.js.map +0 -1
- package/stores/documents/documentStore/historyRebuild.js.map +0 -1
- package/stores/documents/documentStore/initialization.js.map +0 -1
- package/stores/documents/documentStore/initializationAttachments.js.map +0 -1
- package/stores/documents/documentStore/initializationHistory.js.map +0 -1
- package/stores/documents/documentStore/initializationRecovery.js.map +0 -1
- package/stores/documents/documentStore/pullContinuationInvalidation.js.map +0 -1
- package/stores/documents/documentStore/remoteRevalidationTelemetry.js.map +0 -1
- package/stores/documents/documentStore/remoteWork.js.map +0 -1
- package/stores/documents/documentStore/rotation.js.map +0 -1
- package/stores/documents/documentStore/rotationProvenance.js.map +0 -1
- package/stores/documents/documentStore/rotationSettlement.js.map +0 -1
- package/stores/documents/documentStore/sync.js.map +0 -1
- package/stores/documents/documentStore/syncAcceptedUpdateIds.js.map +0 -1
- package/stores/documents/documentStore/syncAttachmentSettlement.js.map +0 -1
- package/stores/documents/documentStore/syncAttachments.js.map +0 -1
- package/stores/documents/documentStore/syncDetachedAttachments.js.map +0 -1
- package/stores/documents/documentStore/syncFinalize.js.map +0 -1
- package/stores/documents/documentStore/syncGeneration.js.map +0 -1
- package/stores/documents/documentStore/syncOutgoingCoverage.js.map +0 -1
- package/stores/documents/documentStore/syncRemoteSignals.js.map +0 -1
- package/stores/documents/documentStore/syncRequest.js.map +0 -1
- package/stores/documents/documentStore/syncShared.js.map +0 -1
- package/stores/documents/documentStore/syncUpdateImport.js.map +0 -1
- package/stores/documents/documentStore.js.map +0 -1
- package/workflows/container-contents/container-state/createAdoption.js.map +0 -1
- package/workflows/container-contents/container-state/createChild.js.map +0 -1
- package/workflows/container-contents/container-state/createIntentDepth.js.map +0 -1
- package/workflows/container-contents/container-state/createIntentSettlement.js.map +0 -1
- package/workflows/container-contents/container-state/createIntentSync.js.map +0 -1
- package/workflows/container-contents/container-state/createTerminalFailure.js.map +0 -1
- package/workflows/container-contents/container-state/createWithMetadata.js.map +0 -1
- package/workflows/container-contents/container-state/createWithMetadataPlan.js.map +0 -1
- package/workflows/container-contents/container-state/groupGrantVerification.js.map +0 -1
- package/workflows/container-contents/container-state/groupShareEpoch.js.map +0 -1
- package/workflows/container-contents/container-state/localPurgeScope.js.map +0 -1
- package/workflows/container-contents/container-state/purgeTree.js.map +0 -1
- package/workflows/container-contents/container-state/purgeTreeCollection.js.map +0 -1
- package/workflows/container-contents/container-state/purgeTreeContainerDeletion.js.map +0 -1
- package/workflows/container-contents/container-state/purgeTreeScope.js.map +0 -1
- package/workflows/container-contents/container-state/readLocalPurgeScope.js.map +0 -1
- package/workflows/container-contents/container-state/share.js.map +0 -1
- package/workflows/container-contents/container-state/sharePersistence.js.map +0 -1
- package/workflows/container-contents/remoteHydration/childIndex.js.map +0 -1
- package/workflows/container-contents/remoteHydration/containerStateFingerprint.js.map +0 -1
- package/workflows/container-contents/remoteHydration/destinationPrefetch.js.map +0 -1
- package/workflows/container-contents/remoteHydration/destinationRoleCache.js.map +0 -1
- package/workflows/container-contents/remoteHydration/destinationRootReload.js.map +0 -1
- package/workflows/container-contents/remoteHydration/insertRemoteContainer.js.map +0 -1
- package/workflows/container-contents/remoteHydration/laneFetchMarkers.js.map +0 -1
- package/workflows/container-contents/remoteHydration/parentLaneFetch.js.map +0 -1
- package/workflows/container-contents/remoteHydration/parentLaneQueue.js.map +0 -1
- package/workflows/container-contents/remoteHydration/remoteContainerPageHydration.js.map +0 -1
- package/workflows/container-contents/remoteHydration/remoteContainerState.js.map +0 -1
- package/workflows/container-contents/remoteHydration/remoteContainerTimestamps.js.map +0 -1
- package/workflows/container-contents/remoteHydration/replacementBinding.js.map +0 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +0 -1
- package/workflows/containers/child/carriedDescendantRekeys.js.map +0 -1
- package/workflows/containers/child/create.js.map +0 -1
- package/workflows/containers/child/createProjection.js.map +0 -1
- package/workflows/containers/child/createSubmission.js.map +0 -1
- package/workflows/containers/child/currentShareGrantMutation.js.map +0 -1
- package/workflows/containers/child/currentSharePrincipalPolicy.js.map +0 -1
- package/workflows/containers/child/move.js.map +0 -1
- package/workflows/containers/child/moveArtifacts.js.map +0 -1
- package/workflows/containers/child/moveRotation.js.map +0 -1
- package/workflows/containers/child/moveWraps.js.map +0 -1
- package/workflows/containers/child/rekey.js.map +0 -1
- package/workflows/containers/child/rekeyProjection.js.map +0 -1
- package/workflows/containers/child/rekeyRemote.js.map +0 -1
- package/workflows/containers/child/replacementPrincipalPolicyReferences.js.map +0 -1
- package/workflows/containers/child/rotationContext.js.map +0 -1
- package/workflows/containers/child/rotationPrincipalPolicies.js.map +0 -1
- package/workflows/containers/child/rotationWraps.js.map +0 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js.map +0 -1
- package/workflows/containers/child/share.js.map +0 -1
- package/workflows/containers/child/shareAncestorRepair.js.map +0 -1
- package/workflows/containers/child/shareMaterialization.js.map +0 -1
- package/workflows/containers/child/sharePlanCore.js.map +0 -1
- package/workflows/containers/child/sharePrincipalPolicy.js.map +0 -1
- package/workflows/containers/child/shareProjection.js.map +0 -1
- /package/data/keyingProjectionVerification/{containerCreateManifest.js.map → container/containerCreateManifest.js.map} +0 -0
- /package/data/keyingProjectionVerification/{documentContainerProjections.js → document/documentContainerProjections.js} +0 -0
- /package/data/keyingProjectionVerification/{documentContainerProjections.js.map → document/documentContainerProjections.js.map} +0 -0
- /package/data/keyingProjectionVerification/{documentManifestPredecessor.js.map → document/documentManifestPredecessor.js.map} +0 -0
- /package/stores/container-contents/{containerStateMap.js → containerState/containerStateMap.js} +0 -0
- /package/stores/container-contents/{missingSyncedContainerState.js → containerState/missingSyncedContainerState.js} +0 -0
- /package/stores/container-contents/{reconcilableContainer.js → containerState/reconcilableContainer.js} +0 -0
- /package/stores/container-contents/{remoteHydrationRefresh.js → hydration/remoteHydrationRefresh.js} +0 -0
- /package/stores/container-contents/{remoteHydrationRefresh.js.map → hydration/remoteHydrationRefresh.js.map} +0 -0
- /package/stores/container-contents/{emptyTrashOperation.js → operations/emptyTrashOperation.js} +0 -0
- /package/stores/container-contents/{purgeContainerOperation.js → operations/purgeContainerOperation.js} +0 -0
- /package/stores/container-contents/{remoteBackedContainerState.js → remoteEvents/remoteBackedContainerState.js} +0 -0
- /package/stores/container-contents/{writeGeneration.js → remoteWrites/writeGeneration.js} +0 -0
- /package/stores/container-contents/{syncAgentTypes.js → syncAgent/syncAgentTypes.js} +0 -0
- /package/stores/container-contents/{systemContainerLookup.js → systemContainers/systemContainerLookup.js} +0 -0
- /package/stores/documents/documentStore/{attachmentPersistFollowup.js → attachments/attachmentPersistFollowup.js} +0 -0
- /package/stores/documents/documentStore/{attachmentSnapshot.js → attachments/attachmentSnapshot.js} +0 -0
- /package/stores/documents/documentStore/{remoteWork.js → sync/remoteWork.js} +0 -0
- /package/stores/documents/documentStore/{syncAcceptedUpdateIds.js → sync/syncAcceptedUpdateIds.js} +0 -0
- /package/stores/documents/documentStore/{syncGeneration.js → sync/syncGeneration.js} +0 -0
- /package/stores/documents/documentStore/{versionCoverage.js.map → sync/versionCoverage.js.map} +0 -0
- /package/workflows/container-contents/container-state/{createIntentSettlement.js → create/createIntentSettlement.js} +0 -0
- /package/workflows/container-contents/container-state/{purgeProgress.d.ts → purge/purgeProgress.d.ts} +0 -0
- /package/workflows/container-contents/container-state/{purgeProgress.js → purge/purgeProgress.js} +0 -0
- /package/workflows/container-contents/container-state/{purgeProgress.js.map → purge/purgeProgress.js.map} +0 -0
- /package/workflows/container-contents/container-state/{purgeTreeCollection.js → purge/purgeTreeCollection.js} +0 -0
- /package/workflows/container-contents/remoteHydration/{destinationPrefetch.js → destination/destinationPrefetch.js} +0 -0
- /package/workflows/container-contents/remoteHydration/{destinationRoleCache.js → destination/destinationRoleCache.js} +0 -0
- /package/workflows/container-contents/remoteHydration/{childIndex.js → lanes/childIndex.js} +0 -0
- /package/workflows/container-contents/remoteHydration/{parentLaneQueue.js → lanes/parentLaneQueue.js} +0 -0
- /package/workflows/container-contents/remoteHydration/{containerStateFingerprint.js → remoteContainers/containerStateFingerprint.js} +0 -0
- /package/workflows/container-contents/remoteHydration/{remoteContainerTimestamps.js → remoteContainers/remoteContainerTimestamps.js} +0 -0
- /package/workflows/containers/child/{keyringOverrideLineage.js.map → rekey/keyringOverrideLineage.js.map} +0 -0
- /package/workflows/containers/child/{shareProjection.js → share/shareProjection.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BLOB_CONTENT_KEY_WRAP_SUITE, wrapContentKey, } from "../../../../internal/crypto/index.js";
|
|
2
2
|
import { bytesToBase64 } from "../../../../internal/encoding/index.js";
|
|
3
|
-
import { documentContainerProjections } from "../../../keyingProjectionVerification/documentContainerProjections.js";
|
|
3
|
+
import { documentContainerProjections } from "../../../keyingProjectionVerification/document/documentContainerProjections.js";
|
|
4
4
|
import { assertDocumentKekPathsCurrent } from "../../shared/containerKekCurrency.js";
|
|
5
5
|
import { readLinkedContainerIdsFromDocumentManifest, unwrapContainerKekPath, verifiedDocumentWrapTargets, } from "../../shared/projection.js";
|
|
6
6
|
import { unwrapContentKeyTargetForKind } from "../../shared/projectionContentKeys.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["projection.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BLOB_CONTENT_KEY_WRAP_SUITE,\n type DocumentContentKeyTarget,\n wrapContentKey,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type { BlobContentKeyTargetEnvelopeRequest } from \"@tearleads/validators/request\";\nimport type {\n BlobContentKeyBundleResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { documentContainerProjections } from \"../../../keyingProjectionVerification/documentContainerProjections\";\nimport type { ExecSql } from \"../../../sqlite/sqlSchema\";\nimport { assertDocumentKekPathsCurrent } from \"../../shared/containerKekCurrency\";\nimport {\n readLinkedContainerIdsFromDocumentManifest,\n unwrapContainerKekPath,\n verifiedDocumentWrapTargets,\n} from \"../../shared/projection\";\nimport { unwrapContentKeyTargetForKind } from \"../../shared/projectionContentKeys\";\nimport {\n assertEqualBytes,\n normalizeDocumentKekTargetResponse,\n} from \"../../shared/readers\";\nimport {\n type ProjectionVerificationOptions,\n projectionVerificationOptions,\n} from \"../../shared/types\";\nimport { sortBlobTargets } from \"./readers\";\nimport type { BlobContentKeyTarget, BlobEncryptedBytesHeader } from \"./types\";\n\nfunction blobTargetsFor(\n input: { bindingId: string; documentId: string },\n targets: readonly DocumentContentKeyTarget[],\n): BlobContentKeyTarget[] {\n return sortBlobTargets(\n targets.map((target) => ({\n bindingId: input.bindingId,\n documentId: input.documentId,\n ...target,\n })),\n );\n}\n\n/**\n * The targets a blob content key may be wrapped to: the verified current\n * heads of the document's linked containers. The server list only names which\n * containers a bundle must cover.\n */\nexport function verifiedBlobWrapTargetsFromDocumentProjection(input: {\n bindingId: string;\n documentId: string;\n writerProjection: DocumentWriterProjectionResponse;\n}): BlobContentKeyTarget[] {\n return blobTargetsFor(\n input,\n verifiedDocumentWrapTargets({\n linkedContainerIds: readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n ),\n serverTargets: normalizeDocumentKekTargetResponse(\n input.writerProjection.documentKekTargets,\n ),\n writerProjection: input.writerProjection,\n }),\n );\n}\n\n// Not collectContainerKeksForDocumentSync: the blob upload retry classifier\n// keys on the bare \"Container writer projection KEK… could not be unwrapped\"\n// message, which the sync collector would wrap with document-sync context.\nasync function collectContainerKeks(\n input: {\n execSql?: ExecSql | undefined;\n secretKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<ReadonlyMap<string, Uint8Array>> {\n const keksByEpochId = new Map<string, Uint8Array>();\n\n for (const projection of documentContainerProjections(\n input.writerProjection,\n )) {\n const projectionKeks = await unwrapContainerKekPath({\n execSql: input.execSql,\n projection,\n secretKey: input.secretKey,\n ...projectionVerificationOptions(input),\n });\n\n for (const [containerKeyEpochId, keyMaterial] of projectionKeks) {\n const existing = keksByEpochId.get(containerKeyEpochId);\n if (existing) {\n assertEqualBytes(\n existing,\n keyMaterial,\n \"Blob writer projection contains conflicting container KEKs\",\n );\n continue;\n }\n keksByEpochId.set(containerKeyEpochId, keyMaterial);\n }\n }\n\n return keksByEpochId;\n}\n\nexport async function wrapBlobContentKey(\n input: {\n blobId: string;\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n execSql?: ExecSql | undefined;\n secretKey: Uint8Array;\n targets: readonly BlobContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<BlobContentKeyTargetEnvelopeRequest[]> {\n assertDocumentKekPathsCurrent(\n input.writerProjection,\n new Set(input.targets.map((target) => target.containerId)),\n );\n const keksByEpochId = await collectContainerKeks({\n execSql: input.execSql,\n secretKey: input.secretKey,\n writerProjection: input.writerProjection,\n ...projectionVerificationOptions(input),\n });\n\n return Promise.all(\n input.targets.map(async (target) => {\n const targetKek = keksByEpochId.get(target.containerKeyEpochId);\n if (!targetKek) {\n throw new Error(\n `Blob target KEK could not be unwrapped for ${target.containerKeyEpochId}`,\n );\n }\n\n const wrapped = await wrapContentKey(input.contentKey, targetKek, {\n kind: \"Blob\",\n objectId: input.blobId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n return {\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: BLOB_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n };\n }),\n );\n}\n\nasync function unwrapBlobContentKeyTarget(input: {\n blobId: string;\n containerKek: Uint8Array;\n contentKeyEpoch: number;\n envelope: BlobContentKeyTargetEnvelopeRequest;\n}): Promise<Uint8Array> {\n return unwrapContentKeyTargetForKind({\n containerKek: input.containerKek,\n contentKeyEpoch: input.contentKeyEpoch,\n envelope: input.envelope,\n kind: \"Blob\",\n objectId: input.blobId,\n });\n}\n\nexport async function unwrapBlobContentKey(\n input: {\n /** The blob being read; its wraps must be sealed to it. */\n blobId: string;\n contentKeyBundle: BlobContentKeyBundleResponse;\n documentId: string;\n encrypted: BlobEncryptedBytesHeader;\n execSql?: ExecSql | undefined;\n expectedBindingId: string;\n secretKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<Uint8Array> {\n const keksByEpochId = await collectContainerKeks({\n execSql: input.execSql,\n secretKey: input.secretKey,\n writerProjection: input.writerProjection,\n ...projectionVerificationOptions(input),\n });\n let contentKey: Uint8Array | null = null;\n const attachmentTargets = input.contentKeyBundle.targets.filter(\n (envelope) =>\n envelope.bindingId === input.expectedBindingId &&\n envelope.documentId === input.documentId,\n );\n\n if (attachmentTargets.length === 0) {\n throw new Error(\"Blob content-key bundle is missing attachment target\");\n }\n\n for (const envelope of attachmentTargets) {\n const containerKek = keksByEpochId.get(envelope.containerKeyEpochId);\n if (!containerKek) {\n continue;\n }\n const unwrapped = await unwrapBlobContentKeyTarget({\n blobId: input.blobId,\n containerKek,\n contentKeyEpoch: input.contentKeyBundle.contentKeyEpoch,\n envelope,\n });\n if (contentKey) {\n assertEqualBytes(\n contentKey,\n unwrapped,\n \"Blob content-key targets unwrap to conflicting keys\",\n );\n continue;\n }\n contentKey = unwrapped;\n }\n\n if (!contentKey) {\n throw new Error(\"Blob content key could not be unwrapped\");\n }\n return contentKey;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"projection.js","sourceRoot":"","sources":["projection.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BLOB_CONTENT_KEY_WRAP_SUITE,\n type DocumentContentKeyTarget,\n wrapContentKey,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type { BlobContentKeyTargetEnvelopeRequest } from \"@tearleads/validators/request\";\nimport type {\n BlobContentKeyBundleResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { documentContainerProjections } from \"../../../keyingProjectionVerification/document/documentContainerProjections\";\nimport type { ExecSql } from \"../../../sqlite/sqlSchema\";\nimport { assertDocumentKekPathsCurrent } from \"../../shared/containerKekCurrency\";\nimport {\n readLinkedContainerIdsFromDocumentManifest,\n unwrapContainerKekPath,\n verifiedDocumentWrapTargets,\n} from \"../../shared/projection\";\nimport { unwrapContentKeyTargetForKind } from \"../../shared/projectionContentKeys\";\nimport {\n assertEqualBytes,\n normalizeDocumentKekTargetResponse,\n} from \"../../shared/readers\";\nimport {\n type ProjectionVerificationOptions,\n projectionVerificationOptions,\n} from \"../../shared/types\";\nimport { sortBlobTargets } from \"./readers\";\nimport type { BlobContentKeyTarget, BlobEncryptedBytesHeader } from \"./types\";\n\nfunction blobTargetsFor(\n input: { bindingId: string; documentId: string },\n targets: readonly DocumentContentKeyTarget[],\n): BlobContentKeyTarget[] {\n return sortBlobTargets(\n targets.map((target) => ({\n bindingId: input.bindingId,\n documentId: input.documentId,\n ...target,\n })),\n );\n}\n\n/**\n * The targets a blob content key may be wrapped to: the verified current\n * heads of the document's linked containers. The server list only names which\n * containers a bundle must cover.\n */\nexport function verifiedBlobWrapTargetsFromDocumentProjection(input: {\n bindingId: string;\n documentId: string;\n writerProjection: DocumentWriterProjectionResponse;\n}): BlobContentKeyTarget[] {\n return blobTargetsFor(\n input,\n verifiedDocumentWrapTargets({\n linkedContainerIds: readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n ),\n serverTargets: normalizeDocumentKekTargetResponse(\n input.writerProjection.documentKekTargets,\n ),\n writerProjection: input.writerProjection,\n }),\n );\n}\n\n// Not collectContainerKeksForDocumentSync: the blob upload retry classifier\n// keys on the bare \"Container writer projection KEK… could not be unwrapped\"\n// message, which the sync collector would wrap with document-sync context.\nasync function collectContainerKeks(\n input: {\n execSql?: ExecSql | undefined;\n secretKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<ReadonlyMap<string, Uint8Array>> {\n const keksByEpochId = new Map<string, Uint8Array>();\n\n for (const projection of documentContainerProjections(\n input.writerProjection,\n )) {\n const projectionKeks = await unwrapContainerKekPath({\n execSql: input.execSql,\n projection,\n secretKey: input.secretKey,\n ...projectionVerificationOptions(input),\n });\n\n for (const [containerKeyEpochId, keyMaterial] of projectionKeks) {\n const existing = keksByEpochId.get(containerKeyEpochId);\n if (existing) {\n assertEqualBytes(\n existing,\n keyMaterial,\n \"Blob writer projection contains conflicting container KEKs\",\n );\n continue;\n }\n keksByEpochId.set(containerKeyEpochId, keyMaterial);\n }\n }\n\n return keksByEpochId;\n}\n\nexport async function wrapBlobContentKey(\n input: {\n blobId: string;\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n execSql?: ExecSql | undefined;\n secretKey: Uint8Array;\n targets: readonly BlobContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<BlobContentKeyTargetEnvelopeRequest[]> {\n assertDocumentKekPathsCurrent(\n input.writerProjection,\n new Set(input.targets.map((target) => target.containerId)),\n );\n const keksByEpochId = await collectContainerKeks({\n execSql: input.execSql,\n secretKey: input.secretKey,\n writerProjection: input.writerProjection,\n ...projectionVerificationOptions(input),\n });\n\n return Promise.all(\n input.targets.map(async (target) => {\n const targetKek = keksByEpochId.get(target.containerKeyEpochId);\n if (!targetKek) {\n throw new Error(\n `Blob target KEK could not be unwrapped for ${target.containerKeyEpochId}`,\n );\n }\n\n const wrapped = await wrapContentKey(input.contentKey, targetKek, {\n kind: \"Blob\",\n objectId: input.blobId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n return {\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: BLOB_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n };\n }),\n );\n}\n\nasync function unwrapBlobContentKeyTarget(input: {\n blobId: string;\n containerKek: Uint8Array;\n contentKeyEpoch: number;\n envelope: BlobContentKeyTargetEnvelopeRequest;\n}): Promise<Uint8Array> {\n return unwrapContentKeyTargetForKind({\n containerKek: input.containerKek,\n contentKeyEpoch: input.contentKeyEpoch,\n envelope: input.envelope,\n kind: \"Blob\",\n objectId: input.blobId,\n });\n}\n\nexport async function unwrapBlobContentKey(\n input: {\n /** The blob being read; its wraps must be sealed to it. */\n blobId: string;\n contentKeyBundle: BlobContentKeyBundleResponse;\n documentId: string;\n encrypted: BlobEncryptedBytesHeader;\n execSql?: ExecSql | undefined;\n expectedBindingId: string;\n secretKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<Uint8Array> {\n const keksByEpochId = await collectContainerKeks({\n execSql: input.execSql,\n secretKey: input.secretKey,\n writerProjection: input.writerProjection,\n ...projectionVerificationOptions(input),\n });\n let contentKey: Uint8Array | null = null;\n const attachmentTargets = input.contentKeyBundle.targets.filter(\n (envelope) =>\n envelope.bindingId === input.expectedBindingId &&\n envelope.documentId === input.documentId,\n );\n\n if (attachmentTargets.length === 0) {\n throw new Error(\"Blob content-key bundle is missing attachment target\");\n }\n\n for (const envelope of attachmentTargets) {\n const containerKek = keksByEpochId.get(envelope.containerKeyEpochId);\n if (!containerKek) {\n continue;\n }\n const unwrapped = await unwrapBlobContentKeyTarget({\n blobId: input.blobId,\n containerKek,\n contentKeyEpoch: input.contentKeyBundle.contentKeyEpoch,\n envelope,\n });\n if (contentKey) {\n assertEqualBytes(\n contentKey,\n unwrapped,\n \"Blob content-key targets unwrap to conflicting keys\",\n );\n continue;\n }\n contentKey = unwrapped;\n }\n\n if (!contentKey) {\n throw new Error(\"Blob content key could not be unwrapped\");\n }\n return contentKey;\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ContentKeyEnvelopeError, computeDocumentContentKeyTargetHash, DOCUMENT_CONTENT_KEY_WRAP_SUITE, decodeContentKeyEnvelope, unwrapContentKey, wrapContentKey, } from "../../../internal/crypto/index.js";
|
|
2
2
|
import { bytesToBase64 } from "../../../internal/encoding/index.js";
|
|
3
|
-
import { documentContainerProjections } from "../../keyingProjectionVerification/documentContainerProjections.js";
|
|
3
|
+
import { documentContainerProjections } from "../../keyingProjectionVerification/document/documentContainerProjections.js";
|
|
4
4
|
import { throwKeyingVerificationErrorWithContext } from "../../keyingProjectionVerification/error.js";
|
|
5
5
|
import { assertContainerKekPathCurrent, assertDocumentKekPathsCurrent, } from "./containerKekCurrency.js";
|
|
6
6
|
import { unwrapContainerKekPath, unwrapContainerKekPathWithHistoryFailures, } from "./containerKekPath.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectionContentKeys.js","sourceRoot":"","sources":["projectionContentKeys.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,mCAAmC,EACnC,+BAA+B,EAC/B,wBAAwB,EACxB,gBAAgB,EAEhB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,iEAAiE,CAAC;AAC/G,OAAO,EAAE,uCAAuC,EAAE,MAAM,0CAA0C,CAAC;AAEnG,OAAO,EACL,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,sBAAsB,EACtB,yCAAyC,GAC1C,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mCAAmC,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,0CAA0C,EAC1C,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,gBAAgB,EAChB,yBAAyB,EACzB,kCAAkC,EAClC,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AAExD,SAAS,2BAA2B,CAClC,UAA6C;IAE7C,MAAM,MAAM,GAAG,2BAA2B,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,KASiC;IAEjC,6BAA6B,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,aAAa,GAAG,MAAM,sBAAsB,CAAC;QACjD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,8BAA8B,EAAE,KAAK,CAAC,8BAA8B;QACpE,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,GAAG,6BAA6B,CAAC,KAAK,CAAC;KACxC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,2BAA2B,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAChE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,EAAE;QAChE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,KAAK,CAAC,UAAU;QAC1B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;KAChD,CAAC,CAAC;IAEH,OAAO;QACL;YACE,GAAG,MAAM;YACT,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC;YAC7C,gBAAgB,EAAE;gBAChB,KAAK,EAAE,+BAA+B;gBACtC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;aAC9B;SACF;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CAAC,KAenD;IACC,4EAA4E;IAC5E,6EAA6E;IAC7E,4EAA4E;IAC5E,yEAAyE;IACzE,wEAAwE;IACxE,IAAI,CAAC;QACH,OAAO,MAAM,gBAAgB,CAC3B,wBAAwB,CAAC;YACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,QAAQ;SACjB,CAAC,EACF,KAAK,CAAC,YAAY,EAClB;YACE,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,eAAe,EAAE,KAAK,CAAC,eAAe;YACtC,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW;YACvC,mBAAmB,EAAE,KAAK,CAAC,QAAQ,CAAC,mBAAmB;SACxD,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,CAAC,mBAAmB;YAAE,MAAM,KAAK,CAAC;QAC5C,wEAAwE;QACxE,sCAAsC;QACtC,MAAM,MAAM,GACV,KAAK,YAAY,uBAAuB,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,mBAAmB,GAAG,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAKpD;IACC,OAAO,6BAA6B,CAAC;QACnC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,mBAAmB,EAAE,6CAA6C,KAAK,CAAC,QAAQ,CAAC,WAAW,aAAa,KAAK,CAAC,QAAQ,CAAC,mBAAmB,yBAAyB;QACpK,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,KAAK,CAAC,UAAU;KAC3B,CAAC,CAAC;AACL,CAAC;AAWD,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACnC;IAArB,YAAqB,YAAqB;QACxC,KAAK,CACH,YAAY,YAAY,KAAK;YAC3B,CAAC,CAAC,YAAY,CAAC,OAAO;YACtB,CAAC,CAAC,qCAAqC,CAC1C,CAAC;QALiB,iBAAY,GAAZ,YAAY,CAAS;QAMxC,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;IAChD,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,OAAO,kCAAmC,SAAQ,KAAK;IAC3D;QACE,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACrD,IAAI,CAAC,IAAI,GAAG,oCAAoC,CAAC;IACnD,CAAC;CACF;AAED,SAAS,2BAA2B,CAClC,QAA0B;IAE1B,OAAO,CACL,QAAQ,CAAC,IAAI,CACX,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,YAAY,mCAAmC,CAAC,CACvE,IAAI,QAAQ,CAAC,CAAC,CAAC,CACjB,CAAC;AACJ,CAAC;AAED,SAAS,iCAAiC,CACxC,QAA4B,EAC5B,GAAW,EACX,OAAc;IAEd,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,2BAA2B,CAC3C,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAC3C,CAAC;IACF,IAAI,SAAS;QAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACvD,KAOiC;IAEjC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;IACpD,MAAM,4BAA4B,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC9D,MAAM,4CAA4C,GAAG,IAAI,GAAG,EAAiB,CAAC;IAE9E,KAAK,MAAM,UAAU,IAAI,4BAA4B,CACnD,KAAK,CAAC,gBAAgB,CACvB,EAAE,CAAC;QACF,IAAI,cAEH,CAAC;QACF,IAAI,CAAC;YACH,cAAc,GAAG,MAAM,yCAAyC,CAAC;gBAC/D,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,kBAAkB,EAAE,aAAa;gBACjC,8BAA8B,EAAE,KAAK,CAAC,8BAA8B;gBACpE,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;gBAChD,UAAU;gBACV,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,GAAG,6BAA6B,CAAC,KAAK,CAAC;aACxC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uCAAuC,CACrC,KAAK,EACL,sEAAsE,2BAA2B,CAAC,UAAU,CAAC,EAAE,CAChH,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CACT,mBAAmB,EACnB,OAAO,EACR,IAAI,cAAc,CAAC,4BAA4B,EAAE,CAAC;YACjD,iCAAiC,CAC/B,4BAA4B,EAC5B,mBAAmB,EACnB,OAAO,CACR,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CACT,WAAW,EACX,OAAO,EACR,IAAI,cAAc,CAAC,4CAA4C,EAAE,CAAC;YACjE,iCAAiC,CAC/B,4CAA4C,EAC5C,WAAW,EACX,OAAO,CACR,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,CACT,mBAAmB,EACnB,WAAW,EACZ,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACxD,IAAI,QAAQ,EAAE,CAAC;gBACb,gBAAgB,CACd,QAAQ,EACR,WAAW,EACX,gEAAgE,CACjE,CAAC;gBACF,SAAS;YACX,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,OAAO;QACL,aAAa;QACb,4BAA4B;QAC5B,4CAA4C;KAC7C,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kCAAkC,CACtD,MAAwC;AACxC,+DAA+D;AAC/D,UAAkB,EAClB,sBAAuD,EACvD,+BAA2D,IAAI,GAAG,EAAE,EACpE,+CAGI,IAAI,GAAG,EAAE;IAEb,MAAM,mBAAmB,GAAG,MAAM,mCAAmC,CACnE,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CACjE,CAAC;IACF,IAAI,mBAAmB,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IACD,IAAI,UAAU,GAAsB,IAAI,CAAC;IACzC,MAAM,mBAAmB,GAAY,EAAE,CAAC;IAExC,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,YAAY,GAAG,sBAAsB,CAAC,GAAG,CAC7C,QAAQ,CAAC,mBAAmB,CAC7B,CAAC;QACF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,kBAAkB,GACtB,4BAA4B,CAAC,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC;gBAC9D,4CAA4C,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YACzE,IAAI,kBAAkB;gBAAE,mBAAmB,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACrE,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,8BAA8B,CAAC;YACrD,YAAY;YACZ,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,UAAU;YACV,QAAQ;SACT,CAAC,CAAC;QACH,IAAI,UAAU,EAAE,CAAC;YACf,gBAAgB,CACd,UAAU,EACV,SAAS,EACT,yDAAyD,CAC1D,CAAC;YACF,SAAS;QACX,CAAC;QACD,UAAU,GAAG,SAAS,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,kBAAkB,GAAG,2BAA2B,CAAC,mBAAmB,CAAC,CAAC;QAC5E,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,IAAI,+BAA+B,CAAC,kBAAkB,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,IAAI,kCAAkC,EAAE,CAAC;IACjD,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4CAA4C,CAChE,KAMiC;IAEjC,MAAM,aAAa,GAAG,MAAM,mCAAmC,CAAC,KAAK,CAAC,CAAC;IAEvE,OAAO,kCAAkC,CACvC,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,EACvC,KAAK,CAAC,gBAAgB,CAAC,UAAU,EACjC,aAAa,CAAC,aAAa,EAC3B,aAAa,CAAC,4BAA4B,EAC1C,aAAa,CAAC,4CAA4C,CAC3D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAI1D;IACC,6BAA6B,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtD,MAAM,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACxE,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,OAAO,GAAG,2BAA2B,CAAC;QAC1C,kBAAkB,EAAE,0CAA0C,CAC5D,KAAK,CAAC,gBAAgB,CACvB;QACD,aAAa,EAAE,kCAAkC,CAAC,kBAAkB,CAAC;QACrE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;KACzC,CAAC,CAAC;IACH,MAAM,SAAS,GAAgD,EAAE,CAAC;IAClE,MAAM,eAAe,GAAG,gBAAgB,CAAC,eAAe,GAAG,CAAC,CAAC;IAE7D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,KAAK,CAAC,sBAAsB,CAAC,GAAG,CACnD,MAAM,CAAC,mBAAmB,CAC3B,CAAC;QACF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,uDAAuD,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAC3F,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,YAAY,EAAE;YACnE,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,gBAAgB,CAAC,UAAU;YACrC,eAAe;YACf,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;SAChD,CAAC,CAAC;QACH,SAAS,CAAC,IAAI,CAAC;YACb,GAAG,MAAM;YACT,UAAU,EAAE,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC;YAC7C,gBAAgB,EAAE;gBAChB,KAAK,EAAE,+BAA+B;gBACtC,EAAE,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;aAC9B;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,eAAe;QACf,UAAU,EAAE,gBAAgB,CAAC,UAAU;QACvC,mBAAmB,EAAE,kBAAkB,CAAC,mBAAmB;QAC3D,UAAU,EAAE,kBAAkB,CAAC,qBAAqB;QACpD,OAAO,EAAE,SAAS;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import {\n ContentKeyEnvelopeError,\n type ContentKeyEnvelopeKind,\n computeDocumentContentKeyTargetHash,\n DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n decodeContentKeyEnvelope,\n unwrapContentKey,\n type VerifiedContainerAccessManifest,\n wrapContentKey,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type { DocumentContentKeyTargetEnvelope } from \"@tearleads/validators/request\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentContentKeyBundleResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCache } from \"../../keyingProjectionVerification\";\nimport { documentContainerProjections } from \"../../keyingProjectionVerification/documentContainerProjections\";\nimport { throwKeyingVerificationErrorWithContext } from \"../../keyingProjectionVerification/error\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport {\n assertContainerKekPathCurrent,\n assertDocumentKekPathsCurrent,\n} from \"./containerKekCurrency\";\nimport {\n unwrapContainerKekPath,\n unwrapContainerKekPathWithHistoryFailures,\n} from \"./containerKekPath\";\nimport { ContainerKekHistoryUnavailableError } from \"./containerKekPathHistory\";\nimport {\n deriveDocumentCreateTargets,\n describeProjectionTargetKek,\n readLinkedContainerIdsFromDocumentManifest,\n verifiedDocumentWrapTargets,\n} from \"./projectionTargets\";\nimport {\n assertEqualBytes,\n describeDocumentTargetKek,\n normalizeDocumentKekTargetResponse,\n sortDocumentTargets,\n targetEnvelopeReference,\n} from \"./readers\";\nimport type { ProjectionVerificationOptions } from \"./types\";\nimport { projectionVerificationOptions } from \"./types\";\n\nfunction getOnlyDocumentCreateTarget(\n projection: ContainerWriterProjectionResponse,\n) {\n const target = deriveDocumentCreateTargets(projection)[0];\n if (!target) {\n throw new Error(\"Document create target is unavailable\");\n }\n return target;\n}\n\nexport async function wrapDocumentContentKeyForCreate(\n input: {\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n documentId: string;\n execSql?: ExecSql | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n projection: ContainerWriterProjectionResponse;\n secretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<DocumentContentKeyTargetEnvelope[]> {\n assertContainerKekPathCurrent(input.projection.containerKeks);\n const keksByEpochId = await unwrapContainerKekPath({\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n projection: input.projection,\n secretKey: input.secretKey,\n ...projectionVerificationOptions(input),\n });\n const target = getOnlyDocumentCreateTarget(input.projection);\n const targetKek = keksByEpochId.get(target.containerKeyEpochId);\n if (!targetKek) {\n throw new Error(\"Document create target KEK could not be unwrapped\");\n }\n\n const wrapped = await wrapContentKey(input.contentKey, targetKek, {\n kind: \"Document\",\n objectId: input.documentId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n\n return [\n {\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n },\n ];\n}\n\nexport async function unwrapContentKeyTargetForKind(input: {\n containerKek: Uint8Array;\n /** The content-key epoch of the bundle the envelope was served in. */\n contentKeyEpoch: number;\n /** Wraps a decode or decrypt failure with this message. */\n decryptErrorMessage?: string | undefined;\n envelope: {\n containerId: string;\n containerKeyEpochId: string;\n wrappedKey: string;\n wrappingMetadata?: unknown;\n };\n kind: ContentKeyEnvelopeKind;\n /** The document or blob the caller is reading, never read from the bundle. */\n objectId: string;\n}): Promise<Uint8Array> {\n // Reading, not submitting: the suite still binds the envelope to its object\n // kind, but an unrecognized extra metadata key is ignored rather than making\n // an otherwise decryptable envelope permanently unreadable. The AEAD tag is\n // what authenticates the recovered key, bound to the object, content-key\n // epoch and target it was sealed for. The KEK stays out of the decoder.\n try {\n return await unwrapContentKey(\n decodeContentKeyEnvelope({\n envelope: input.envelope,\n kind: input.kind,\n origin: \"stored\",\n }),\n input.containerKek,\n {\n kind: input.kind,\n objectId: input.objectId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: input.envelope.containerId,\n containerKeyEpochId: input.envelope.containerKeyEpochId,\n },\n );\n } catch (error) {\n if (!input.decryptErrorMessage) throw error;\n // Keep the structural diagnostic; the wrapper only adds which target it\n // was, which the decoder cannot know.\n const detail =\n error instanceof ContentKeyEnvelopeError ? `: ${error.message}` : \"\";\n throw new Error(`${input.decryptErrorMessage}${detail}`, { cause: error });\n }\n}\n\nexport async function unwrapDocumentContentKeyTarget(input: {\n containerKek: Uint8Array;\n contentKeyEpoch: number;\n documentId: string;\n envelope: DocumentContentKeyTargetEnvelope;\n}): Promise<Uint8Array> {\n return unwrapContentKeyTargetForKind({\n containerKek: input.containerKek,\n contentKeyEpoch: input.contentKeyEpoch,\n decryptErrorMessage: `Document content-key target for container ${input.envelope.containerId} at epoch ${input.envelope.containerKeyEpochId} could not be unwrapped`,\n envelope: input.envelope,\n kind: \"Document\",\n objectId: input.documentId,\n });\n}\n\ninterface CollectedContainerKeks {\n readonly keksByEpochId: ReadonlyMap<string, Uint8Array>;\n readonly predecessorFailuresByEpochId: ReadonlyMap<string, Error>;\n readonly unattributedPredecessorFailuresByContainerId: ReadonlyMap<\n string,\n Error\n >;\n}\n\nexport class DocumentHistoryUnavailableError extends Error {\n constructor(readonly historyCause: unknown) {\n super(\n historyCause instanceof Error\n ? historyCause.message\n : \"Document history key is unavailable\",\n );\n this.name = \"DocumentHistoryUnavailableError\";\n }\n}\n\n/** No verified target or predecessor path can supply this content key. */\nexport class DocumentContentKeyUnavailableError extends Error {\n constructor() {\n super(\"Document content key could not be unwrapped\");\n this.name = \"DocumentContentKeyUnavailableError\";\n }\n}\n\nfunction preferredPredecessorFailure(\n failures: readonly Error[],\n): Error | undefined {\n return (\n failures.find(\n (failure) => !(failure instanceof ContainerKekHistoryUnavailableError),\n ) ?? failures[0]\n );\n}\n\nfunction recordPreferredPredecessorFailure(\n failures: Map<string, Error>,\n key: string,\n failure: Error,\n): void {\n const existing = failures.get(key);\n const preferred = preferredPredecessorFailure(\n existing ? [existing, failure] : [failure],\n );\n if (preferred) failures.set(key, preferred);\n}\n\nexport async function collectContainerKeksForDocumentSync(\n input: {\n execSql?: ExecSql | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n secretKey: Uint8Array;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<CollectedContainerKeks> {\n const keksByEpochId = new Map<string, Uint8Array>();\n const predecessorFailuresByEpochId = new Map<string, Error>();\n const unattributedPredecessorFailuresByContainerId = new Map<string, Error>();\n\n for (const projection of documentContainerProjections(\n input.writerProjection,\n )) {\n let projectionKeks: Awaited<\n ReturnType<typeof unwrapContainerKekPathWithHistoryFailures>\n >;\n try {\n projectionKeks = await unwrapContainerKekPathWithHistoryFailures({\n execSql: input.execSql,\n knownContainerKeks: keksByEpochId,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n principalPolicyCache: input.principalPolicyCache,\n projection,\n secretKey: input.secretKey,\n verifiedByHash: input.verifiedByHash,\n ...projectionVerificationOptions(input),\n });\n } catch (error) {\n throwKeyingVerificationErrorWithContext(\n error,\n `Document authorizing container KEK path could not be unwrapped for ${describeProjectionTargetKek(projection)}`,\n );\n }\n for (const [\n containerKeyEpochId,\n failure,\n ] of projectionKeks.predecessorFailuresByEpochId) {\n recordPreferredPredecessorFailure(\n predecessorFailuresByEpochId,\n containerKeyEpochId,\n failure,\n );\n }\n for (const [\n containerId,\n failure,\n ] of projectionKeks.unattributedPredecessorFailuresByContainerId) {\n recordPreferredPredecessorFailure(\n unattributedPredecessorFailuresByContainerId,\n containerId,\n failure,\n );\n }\n for (const [\n containerKeyEpochId,\n keyMaterial,\n ] of projectionKeks.keksByEpochId) {\n const existing = keksByEpochId.get(containerKeyEpochId);\n if (existing) {\n assertEqualBytes(\n existing,\n keyMaterial,\n \"Document writer projection contains conflicting container KEKs\",\n );\n continue;\n }\n keksByEpochId.set(containerKeyEpochId, keyMaterial);\n }\n }\n\n return {\n keksByEpochId,\n predecessorFailuresByEpochId,\n unattributedPredecessorFailuresByContainerId,\n };\n}\n\nexport async function unwrapDocumentContentKeyFromBundle(\n bundle: DocumentContentKeyBundleResponse,\n /** The document being read; its wraps must be sealed to it. */\n documentId: string,\n containerKeksByEpochId: ReadonlyMap<string, Uint8Array>,\n predecessorFailuresByEpochId: ReadonlyMap<string, Error> = new Map(),\n unattributedPredecessorFailuresByContainerId: ReadonlyMap<\n string,\n Error\n > = new Map(),\n): Promise<Uint8Array> {\n const canonicalTargetHash = await computeDocumentContentKeyTargetHash(\n sortDocumentTargets(bundle.targets.map(targetEnvelopeReference)),\n );\n if (canonicalTargetHash !== bundle.targetHash) {\n throw new Error(\"Document content-key bundle target hash is not canonical\");\n }\n if (bundle.documentId !== documentId) {\n throw new Error(\"Document content-key bundle names another document\");\n }\n let contentKey: Uint8Array | null = null;\n const predecessorFailures: Error[] = [];\n\n for (const envelope of bundle.targets) {\n const containerKek = containerKeksByEpochId.get(\n envelope.containerKeyEpochId,\n );\n if (!containerKek) {\n const predecessorFailure =\n predecessorFailuresByEpochId.get(envelope.containerKeyEpochId) ??\n unattributedPredecessorFailuresByContainerId.get(envelope.containerId);\n if (predecessorFailure) predecessorFailures.push(predecessorFailure);\n continue;\n }\n const unwrapped = await unwrapDocumentContentKeyTarget({\n containerKek,\n contentKeyEpoch: bundle.contentKeyEpoch,\n documentId,\n envelope,\n });\n if (contentKey) {\n assertEqualBytes(\n contentKey,\n unwrapped,\n \"Document content-key targets unwrap to conflicting keys\",\n );\n continue;\n }\n contentKey = unwrapped;\n }\n\n if (!contentKey) {\n const predecessorFailure = preferredPredecessorFailure(predecessorFailures);\n if (predecessorFailure !== undefined) {\n throw new DocumentHistoryUnavailableError(predecessorFailure);\n }\n throw new DocumentContentKeyUnavailableError();\n }\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Document content key must be 32 bytes\");\n }\n\n return contentKey;\n}\n\nexport async function unwrapDocumentContentKeyFromWriterProjection(\n input: {\n execSql?: ExecSql | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n secretKey: Uint8Array;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<Uint8Array> {\n const collectedKeks = await collectContainerKeksForDocumentSync(input);\n\n return unwrapDocumentContentKeyFromBundle(\n input.writerProjection.contentKeyBundle,\n input.writerProjection.documentId,\n collectedKeks.keksByEpochId,\n collectedKeks.predecessorFailuresByEpochId,\n collectedKeks.unattributedPredecessorFailuresByContainerId,\n );\n}\n\n/**\n * Builds the healing bundle for a stale content-key bundle: wraps a FRESH\n * content key to the projection's CURRENT KEK targets at the next\n * content-key epoch. A current reader can recover the stale bundle through\n * the container predecessor chain; the fresh key is still required so a\n * holder revoked by the container rotation cannot decrypt future updates.\n * Recovery re-encrypts a full-history snapshot under that fresh key.\n *\n * Like every content-key rotation (unlink included), this requires the KEK\n * of EVERY linked-container target: all envelopes in a bundle must wrap the\n * same key, so an inaccessible target's envelope can neither be carried\n * forward (it wraps the old key) nor fabricated. A writer authorized through\n * only a subset of a multi-container link set fails here with a named target\n * and leaves the heal to a member who spans all of them.\n */\nexport async function buildRotatedDocumentContentKeyBundle(input: {\n containerKeksByEpochId: ReadonlyMap<string, Uint8Array>;\n contentKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentContentKeyBundleResponse> {\n assertDocumentKekPathsCurrent(input.writerProjection);\n const { contentKeyBundle, documentKekTargets } = input.writerProjection;\n // The server list names the linked containers; each envelope's epoch comes\n // from the verified authorizing-path leaf for that container.\n const targets = verifiedDocumentWrapTargets({\n linkedContainerIds: readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n ),\n serverTargets: normalizeDocumentKekTargetResponse(documentKekTargets),\n writerProjection: input.writerProjection,\n });\n const envelopes: DocumentContentKeyBundleResponse[\"targets\"] = [];\n const contentKeyEpoch = contentKeyBundle.contentKeyEpoch + 1;\n\n for (const target of targets) {\n const containerKek = input.containerKeksByEpochId.get(\n target.containerKeyEpochId,\n );\n if (!containerKek) {\n throw new Error(\n `Document content-key re-wrap KEK is unavailable for ${describeDocumentTargetKek(target)}`,\n );\n }\n const wrapped = await wrapContentKey(input.contentKey, containerKek, {\n kind: \"Document\",\n objectId: contentKeyBundle.documentId,\n contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n envelopes.push({\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n });\n }\n\n return {\n contentKeyEpoch,\n documentId: contentKeyBundle.documentId,\n linkSetManifestHash: documentKekTargets.linkSetManifestHash,\n targetHash: documentKekTargets.documentKeyTargetHash,\n targets: envelopes,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"projectionContentKeys.js","sourceRoot":"","sources":["projectionContentKeys.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ContentKeyEnvelopeError,\n type ContentKeyEnvelopeKind,\n computeDocumentContentKeyTargetHash,\n DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n decodeContentKeyEnvelope,\n unwrapContentKey,\n type VerifiedContainerAccessManifest,\n wrapContentKey,\n} from \"@tearleads/crypto\";\nimport { bytesToBase64 } from \"@tearleads/encoding\";\nimport type { DocumentContentKeyTargetEnvelope } from \"@tearleads/validators/request\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentContentKeyBundleResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCache } from \"../../keyingProjectionVerification\";\nimport { documentContainerProjections } from \"../../keyingProjectionVerification/document/documentContainerProjections\";\nimport { throwKeyingVerificationErrorWithContext } from \"../../keyingProjectionVerification/error\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport {\n assertContainerKekPathCurrent,\n assertDocumentKekPathsCurrent,\n} from \"./containerKekCurrency\";\nimport {\n unwrapContainerKekPath,\n unwrapContainerKekPathWithHistoryFailures,\n} from \"./containerKekPath\";\nimport { ContainerKekHistoryUnavailableError } from \"./containerKekPathHistory\";\nimport {\n deriveDocumentCreateTargets,\n describeProjectionTargetKek,\n readLinkedContainerIdsFromDocumentManifest,\n verifiedDocumentWrapTargets,\n} from \"./projectionTargets\";\nimport {\n assertEqualBytes,\n describeDocumentTargetKek,\n normalizeDocumentKekTargetResponse,\n sortDocumentTargets,\n targetEnvelopeReference,\n} from \"./readers\";\nimport type { ProjectionVerificationOptions } from \"./types\";\nimport { projectionVerificationOptions } from \"./types\";\n\nfunction getOnlyDocumentCreateTarget(\n projection: ContainerWriterProjectionResponse,\n) {\n const target = deriveDocumentCreateTargets(projection)[0];\n if (!target) {\n throw new Error(\"Document create target is unavailable\");\n }\n return target;\n}\n\nexport async function wrapDocumentContentKeyForCreate(\n input: {\n contentKey: Uint8Array;\n contentKeyEpoch: number;\n documentId: string;\n execSql?: ExecSql | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n projection: ContainerWriterProjectionResponse;\n secretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<DocumentContentKeyTargetEnvelope[]> {\n assertContainerKekPathCurrent(input.projection.containerKeks);\n const keksByEpochId = await unwrapContainerKekPath({\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n projection: input.projection,\n secretKey: input.secretKey,\n ...projectionVerificationOptions(input),\n });\n const target = getOnlyDocumentCreateTarget(input.projection);\n const targetKek = keksByEpochId.get(target.containerKeyEpochId);\n if (!targetKek) {\n throw new Error(\"Document create target KEK could not be unwrapped\");\n }\n\n const wrapped = await wrapContentKey(input.contentKey, targetKek, {\n kind: \"Document\",\n objectId: input.documentId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n\n return [\n {\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n },\n ];\n}\n\nexport async function unwrapContentKeyTargetForKind(input: {\n containerKek: Uint8Array;\n /** The content-key epoch of the bundle the envelope was served in. */\n contentKeyEpoch: number;\n /** Wraps a decode or decrypt failure with this message. */\n decryptErrorMessage?: string | undefined;\n envelope: {\n containerId: string;\n containerKeyEpochId: string;\n wrappedKey: string;\n wrappingMetadata?: unknown;\n };\n kind: ContentKeyEnvelopeKind;\n /** The document or blob the caller is reading, never read from the bundle. */\n objectId: string;\n}): Promise<Uint8Array> {\n // Reading, not submitting: the suite still binds the envelope to its object\n // kind, but an unrecognized extra metadata key is ignored rather than making\n // an otherwise decryptable envelope permanently unreadable. The AEAD tag is\n // what authenticates the recovered key, bound to the object, content-key\n // epoch and target it was sealed for. The KEK stays out of the decoder.\n try {\n return await unwrapContentKey(\n decodeContentKeyEnvelope({\n envelope: input.envelope,\n kind: input.kind,\n origin: \"stored\",\n }),\n input.containerKek,\n {\n kind: input.kind,\n objectId: input.objectId,\n contentKeyEpoch: input.contentKeyEpoch,\n containerId: input.envelope.containerId,\n containerKeyEpochId: input.envelope.containerKeyEpochId,\n },\n );\n } catch (error) {\n if (!input.decryptErrorMessage) throw error;\n // Keep the structural diagnostic; the wrapper only adds which target it\n // was, which the decoder cannot know.\n const detail =\n error instanceof ContentKeyEnvelopeError ? `: ${error.message}` : \"\";\n throw new Error(`${input.decryptErrorMessage}${detail}`, { cause: error });\n }\n}\n\nexport async function unwrapDocumentContentKeyTarget(input: {\n containerKek: Uint8Array;\n contentKeyEpoch: number;\n documentId: string;\n envelope: DocumentContentKeyTargetEnvelope;\n}): Promise<Uint8Array> {\n return unwrapContentKeyTargetForKind({\n containerKek: input.containerKek,\n contentKeyEpoch: input.contentKeyEpoch,\n decryptErrorMessage: `Document content-key target for container ${input.envelope.containerId} at epoch ${input.envelope.containerKeyEpochId} could not be unwrapped`,\n envelope: input.envelope,\n kind: \"Document\",\n objectId: input.documentId,\n });\n}\n\ninterface CollectedContainerKeks {\n readonly keksByEpochId: ReadonlyMap<string, Uint8Array>;\n readonly predecessorFailuresByEpochId: ReadonlyMap<string, Error>;\n readonly unattributedPredecessorFailuresByContainerId: ReadonlyMap<\n string,\n Error\n >;\n}\n\nexport class DocumentHistoryUnavailableError extends Error {\n constructor(readonly historyCause: unknown) {\n super(\n historyCause instanceof Error\n ? historyCause.message\n : \"Document history key is unavailable\",\n );\n this.name = \"DocumentHistoryUnavailableError\";\n }\n}\n\n/** No verified target or predecessor path can supply this content key. */\nexport class DocumentContentKeyUnavailableError extends Error {\n constructor() {\n super(\"Document content key could not be unwrapped\");\n this.name = \"DocumentContentKeyUnavailableError\";\n }\n}\n\nfunction preferredPredecessorFailure(\n failures: readonly Error[],\n): Error | undefined {\n return (\n failures.find(\n (failure) => !(failure instanceof ContainerKekHistoryUnavailableError),\n ) ?? failures[0]\n );\n}\n\nfunction recordPreferredPredecessorFailure(\n failures: Map<string, Error>,\n key: string,\n failure: Error,\n): void {\n const existing = failures.get(key);\n const preferred = preferredPredecessorFailure(\n existing ? [existing, failure] : [failure],\n );\n if (preferred) failures.set(key, preferred);\n}\n\nexport async function collectContainerKeksForDocumentSync(\n input: {\n execSql?: ExecSql | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n secretKey: Uint8Array;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<CollectedContainerKeks> {\n const keksByEpochId = new Map<string, Uint8Array>();\n const predecessorFailuresByEpochId = new Map<string, Error>();\n const unattributedPredecessorFailuresByContainerId = new Map<string, Error>();\n\n for (const projection of documentContainerProjections(\n input.writerProjection,\n )) {\n let projectionKeks: Awaited<\n ReturnType<typeof unwrapContainerKekPathWithHistoryFailures>\n >;\n try {\n projectionKeks = await unwrapContainerKekPathWithHistoryFailures({\n execSql: input.execSql,\n knownContainerKeks: keksByEpochId,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n principalPolicyCache: input.principalPolicyCache,\n projection,\n secretKey: input.secretKey,\n verifiedByHash: input.verifiedByHash,\n ...projectionVerificationOptions(input),\n });\n } catch (error) {\n throwKeyingVerificationErrorWithContext(\n error,\n `Document authorizing container KEK path could not be unwrapped for ${describeProjectionTargetKek(projection)}`,\n );\n }\n for (const [\n containerKeyEpochId,\n failure,\n ] of projectionKeks.predecessorFailuresByEpochId) {\n recordPreferredPredecessorFailure(\n predecessorFailuresByEpochId,\n containerKeyEpochId,\n failure,\n );\n }\n for (const [\n containerId,\n failure,\n ] of projectionKeks.unattributedPredecessorFailuresByContainerId) {\n recordPreferredPredecessorFailure(\n unattributedPredecessorFailuresByContainerId,\n containerId,\n failure,\n );\n }\n for (const [\n containerKeyEpochId,\n keyMaterial,\n ] of projectionKeks.keksByEpochId) {\n const existing = keksByEpochId.get(containerKeyEpochId);\n if (existing) {\n assertEqualBytes(\n existing,\n keyMaterial,\n \"Document writer projection contains conflicting container KEKs\",\n );\n continue;\n }\n keksByEpochId.set(containerKeyEpochId, keyMaterial);\n }\n }\n\n return {\n keksByEpochId,\n predecessorFailuresByEpochId,\n unattributedPredecessorFailuresByContainerId,\n };\n}\n\nexport async function unwrapDocumentContentKeyFromBundle(\n bundle: DocumentContentKeyBundleResponse,\n /** The document being read; its wraps must be sealed to it. */\n documentId: string,\n containerKeksByEpochId: ReadonlyMap<string, Uint8Array>,\n predecessorFailuresByEpochId: ReadonlyMap<string, Error> = new Map(),\n unattributedPredecessorFailuresByContainerId: ReadonlyMap<\n string,\n Error\n > = new Map(),\n): Promise<Uint8Array> {\n const canonicalTargetHash = await computeDocumentContentKeyTargetHash(\n sortDocumentTargets(bundle.targets.map(targetEnvelopeReference)),\n );\n if (canonicalTargetHash !== bundle.targetHash) {\n throw new Error(\"Document content-key bundle target hash is not canonical\");\n }\n if (bundle.documentId !== documentId) {\n throw new Error(\"Document content-key bundle names another document\");\n }\n let contentKey: Uint8Array | null = null;\n const predecessorFailures: Error[] = [];\n\n for (const envelope of bundle.targets) {\n const containerKek = containerKeksByEpochId.get(\n envelope.containerKeyEpochId,\n );\n if (!containerKek) {\n const predecessorFailure =\n predecessorFailuresByEpochId.get(envelope.containerKeyEpochId) ??\n unattributedPredecessorFailuresByContainerId.get(envelope.containerId);\n if (predecessorFailure) predecessorFailures.push(predecessorFailure);\n continue;\n }\n const unwrapped = await unwrapDocumentContentKeyTarget({\n containerKek,\n contentKeyEpoch: bundle.contentKeyEpoch,\n documentId,\n envelope,\n });\n if (contentKey) {\n assertEqualBytes(\n contentKey,\n unwrapped,\n \"Document content-key targets unwrap to conflicting keys\",\n );\n continue;\n }\n contentKey = unwrapped;\n }\n\n if (!contentKey) {\n const predecessorFailure = preferredPredecessorFailure(predecessorFailures);\n if (predecessorFailure !== undefined) {\n throw new DocumentHistoryUnavailableError(predecessorFailure);\n }\n throw new DocumentContentKeyUnavailableError();\n }\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Document content key must be 32 bytes\");\n }\n\n return contentKey;\n}\n\nexport async function unwrapDocumentContentKeyFromWriterProjection(\n input: {\n execSql?: ExecSql | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n secretKey: Uint8Array;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n writerProjection: DocumentWriterProjectionResponse;\n } & ProjectionVerificationOptions,\n): Promise<Uint8Array> {\n const collectedKeks = await collectContainerKeksForDocumentSync(input);\n\n return unwrapDocumentContentKeyFromBundle(\n input.writerProjection.contentKeyBundle,\n input.writerProjection.documentId,\n collectedKeks.keksByEpochId,\n collectedKeks.predecessorFailuresByEpochId,\n collectedKeks.unattributedPredecessorFailuresByContainerId,\n );\n}\n\n/**\n * Builds the healing bundle for a stale content-key bundle: wraps a FRESH\n * content key to the projection's CURRENT KEK targets at the next\n * content-key epoch. A current reader can recover the stale bundle through\n * the container predecessor chain; the fresh key is still required so a\n * holder revoked by the container rotation cannot decrypt future updates.\n * Recovery re-encrypts a full-history snapshot under that fresh key.\n *\n * Like every content-key rotation (unlink included), this requires the KEK\n * of EVERY linked-container target: all envelopes in a bundle must wrap the\n * same key, so an inaccessible target's envelope can neither be carried\n * forward (it wraps the old key) nor fabricated. A writer authorized through\n * only a subset of a multi-container link set fails here with a named target\n * and leaves the heal to a member who spans all of them.\n */\nexport async function buildRotatedDocumentContentKeyBundle(input: {\n containerKeksByEpochId: ReadonlyMap<string, Uint8Array>;\n contentKey: Uint8Array;\n writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentContentKeyBundleResponse> {\n assertDocumentKekPathsCurrent(input.writerProjection);\n const { contentKeyBundle, documentKekTargets } = input.writerProjection;\n // The server list names the linked containers; each envelope's epoch comes\n // from the verified authorizing-path leaf for that container.\n const targets = verifiedDocumentWrapTargets({\n linkedContainerIds: readLinkedContainerIdsFromDocumentManifest(\n input.writerProjection,\n ),\n serverTargets: normalizeDocumentKekTargetResponse(documentKekTargets),\n writerProjection: input.writerProjection,\n });\n const envelopes: DocumentContentKeyBundleResponse[\"targets\"] = [];\n const contentKeyEpoch = contentKeyBundle.contentKeyEpoch + 1;\n\n for (const target of targets) {\n const containerKek = input.containerKeksByEpochId.get(\n target.containerKeyEpochId,\n );\n if (!containerKek) {\n throw new Error(\n `Document content-key re-wrap KEK is unavailable for ${describeDocumentTargetKek(target)}`,\n );\n }\n const wrapped = await wrapContentKey(input.contentKey, containerKek, {\n kind: \"Document\",\n objectId: contentKeyBundle.documentId,\n contentKeyEpoch,\n containerId: target.containerId,\n containerKeyEpochId: target.containerKeyEpochId,\n });\n envelopes.push({\n ...target,\n wrappedKey: bytesToBase64(wrapped.ciphertext),\n wrappingMetadata: {\n suite: DOCUMENT_CONTENT_KEY_WRAP_SUITE,\n iv: bytesToBase64(wrapped.iv),\n },\n });\n }\n\n return {\n contentKeyEpoch,\n documentId: contentKeyBundle.documentId,\n linkSetManifestHash: documentKekTargets.linkSetManifestHash,\n targetHash: documentKekTargets.documentKeyTargetHash,\n targets: envelopes,\n };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computeDocumentContentKeyTargetHash, makeVerifiedDocumentKekTargets, } from "../../../internal/crypto/index.js";
|
|
2
|
-
import { resolveEventContainerPaths } from "../../keyingProjectionVerification/documentDependencyPaths.js";
|
|
2
|
+
import { resolveEventContainerPaths } from "../../keyingProjectionVerification/document/documentDependencyPaths.js";
|
|
3
3
|
import { sortDocumentTargets } from "./readers.js";
|
|
4
4
|
export async function documentWriteAuthorizationForHeader(input) {
|
|
5
5
|
const source = input.plan.documentWriterAuthorization;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncResponseAuthorization.js","sourceRoot":"","sources":["syncResponseAuthorization.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mCAAmC,EAEnC,8BAA8B,GAC/B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,0BAA0B,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"syncResponseAuthorization.js","sourceRoot":"","sources":["syncResponseAuthorization.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeDocumentContentKeyTargetHash,\n type DocumentContentKeyTarget,\n makeVerifiedDocumentKekTargets,\n} from \"@tearleads/crypto\";\nimport type { DocumentSyncResponse } from \"@tearleads/validators/response\";\nimport { resolveEventContainerPaths } from \"../../keyingProjectionVerification/document/documentDependencyPaths\";\nimport { sortDocumentTargets } from \"./readers\";\nimport type { DocumentSyncPlan } from \"./types\";\n\nexport async function documentWriteAuthorizationForHeader(input: {\n readonly allowMissingAuthorization: boolean;\n readonly dependencyManifestHashes: readonly string[];\n readonly authorizationTargets: readonly DocumentContentKeyTarget[];\n readonly contentKeyBundle: DocumentSyncResponse[\"contentKeyBundle\"];\n readonly manifestHash: string;\n readonly plan: Pick<\n DocumentSyncPlan,\n \"documentId\" | \"organizationId\" | \"documentWriterAuthorization\"\n >;\n readonly targetHash: string;\n}) {\n const source = input.plan.documentWriterAuthorization;\n if (!source) {\n if (input.allowMissingAuthorization) {\n return null;\n }\n throw new Error(\n \"Document sync response lacks verified writer-authorization material\",\n );\n }\n const documentManifest = source.documentManifestByHash.get(\n input.manifestHash,\n );\n if (!documentManifest) {\n throw new Error(\n \"Document sync response write manifest is not in verified history\",\n );\n }\n if (input.contentKeyBundle.documentId !== input.plan.documentId) {\n throw new Error(\n \"Document sync response content-key bundle belongs to another document\",\n );\n }\n\n const targets = sortDocumentTargets(input.authorizationTargets);\n if (\n (await computeDocumentContentKeyTargetHash(targets)) !== input.targetHash\n ) {\n throw new Error(\"Document sync response write targets are not canonical\");\n }\n const linkedContainerIds = new Set(documentManifest.state.linkedContainerIds);\n if (\n targets.length !== linkedContainerIds.size ||\n targets.some((target) => !linkedContainerIds.has(target.containerId))\n ) {\n throw new Error(\n \"Document sync response write targets do not match the signed link set\",\n );\n }\n\n const { dependencyContainerPaths } = resolveEventContainerPaths({\n containerPathByManifestHash: source.containerPathByManifestHash,\n dependencyManifestHashes: input.dependencyManifestHashes,\n });\n // A writer needs one committed target, and can be unable to read another\n // linked container. Validate the targets that are cited without inventing\n // paths for uncited targets or dropping signed ancestor evidence.\n for (const target of targets) {\n const path = dependencyContainerPaths.find(\n (candidate) =>\n candidate.at(-1)?.manifestHash === target.containerManifestHash,\n );\n if (!path) continue;\n const leaf = path.at(-1);\n if (\n !leaf ||\n leaf.state.containerId !== target.containerId ||\n leaf.state.organizationId !== input.plan.organizationId ||\n leaf.state.containerKeyEpochId !== target.containerKeyEpochId\n ) {\n throw new Error(\n \"Document sync response write target lacks a verified container path\",\n );\n }\n }\n const authorizingContainerPaths = dependencyContainerPaths;\n const documentKekTargets = makeVerifiedDocumentKekTargets({\n documentId: input.contentKeyBundle.documentId,\n documentKeyTargetHash: input.targetHash,\n linkedContainerKeyEpochIds: targets.map(\n (target) => target.containerKeyEpochId,\n ),\n linkedContainerManifestHashes: targets.map(\n (target) => target.containerManifestHash,\n ),\n linkSetManifestHash: input.manifestHash,\n targets,\n });\n return {\n authorizingContainerPaths,\n documentKekTargets,\n documentManifest,\n principalPolicies: source.principalPolicies,\n };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { KeyingVerificationError, } from "
|
|
2
|
-
import { advanceKeyingCheckpointsAtomically, validateKeyingCheckpointsAtomically, } from "
|
|
1
|
+
import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { advanceKeyingCheckpointsAtomically, validateKeyingCheckpointsAtomically, } from "../../persistence/keyingCheckpointAdvancePersistence.js";
|
|
3
3
|
function objectKey(manifest) {
|
|
4
4
|
const { objectKind, organizationId, objectId } = manifest.checkpoint;
|
|
5
5
|
return JSON.stringify([objectKind, organizationId, objectId]);
|
package/data/keyingProjectionVerification/checkpoints/accessManifestCheckpointEnforcement.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accessManifestCheckpointEnforcement.js","sourceRoot":"","sources":["accessManifestCheckpointEnforcement.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type VerifiedAccessManifestCheckpointEvidence,\n type VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport type { DocumentPurgeCheckpoint } from \"../../persistence/documentPurgeCheckpointPersistence\";\nimport {\n type AccessManifestCheckpointAdvance,\n advanceKeyingCheckpointsAtomically,\n validateKeyingCheckpointsAtomically,\n} from \"../../persistence/keyingCheckpointAdvancePersistence\";\nimport type { VerifiedManifestBundle } from \"../../persistence/verifiedManifestBundlePersistence\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\n\nfunction objectKey(manifest: VerifiedAccessManifestCheckpointEvidence): string {\n const { objectKind, organizationId, objectId } = manifest.checkpoint;\n return JSON.stringify([objectKind, organizationId, objectId]);\n}\n\nfunction manifestsByObject(\n manifests: readonly VerifiedAccessManifestCheckpointEvidence[],\n): Map<string, Map<string, VerifiedAccessManifestCheckpointEvidence>> {\n const byObject = new Map<\n string,\n Map<string, VerifiedAccessManifestCheckpointEvidence>\n >();\n for (const manifest of manifests) {\n const key = objectKey(manifest);\n let byHash = byObject.get(key);\n if (!byHash) {\n byHash = new Map();\n byObject.set(key, byHash);\n }\n byHash.set(manifest.manifestHash, manifest);\n }\n return byObject;\n}\n\nfunction accessManifestCheckpointAdvances(input: {\n readonly verifiedHeads: readonly VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: readonly VerifiedAccessManifestCheckpointEvidence[];\n}): AccessManifestCheckpointAdvance[] {\n const evidenceByObject = manifestsByObject(input.verifiedManifests);\n const headsByObject = manifestsByObject(input.verifiedHeads);\n const advances: AccessManifestCheckpointAdvance[] = [];\n\n for (const [key, headsByHash] of headsByObject) {\n if (headsByHash.size !== 1) {\n throw new KeyingVerificationError(\n \"equivocation\",\n `projection declares conflicting access manifest heads for ${key}`,\n );\n }\n const head = headsByHash.values().next().value;\n if (!head) {\n continue;\n }\n const predecessors = [\n ...(evidenceByObject.get(key)?.values() ?? []),\n ].filter((manifest) => manifest.manifestHash !== head.manifestHash);\n advances.push({ head, predecessors });\n }\n\n return advances;\n}\n\nexport async function validateAccessManifestCheckpoints(input: {\n readonly execSql: ExecSql;\n readonly policies: readonly PrincipalPolicyCheckpointEvidence[];\n readonly authorizationPolicies?:\n | readonly VerifiedPrincipalPolicySelection[]\n | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly verifiedBundles?: readonly VerifiedManifestBundle[] | undefined;\n readonly verifiedHeads: readonly VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: readonly VerifiedAccessManifestCheckpointEvidence[];\n}): Promise<void> {\n await validateKeyingCheckpointsAtomically({\n access: accessManifestCheckpointAdvances(input),\n execSql: input.execSql,\n policies: input.policies,\n authorizationPolicies: input.authorizationPolicies,\n stillCurrent: input.stillCurrent,\n verifiedBundles: input.verifiedBundles,\n });\n}\n\nexport async function enforceAccessManifestCheckpoints(input: {\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;\n readonly policies: readonly PrincipalPolicyCheckpointEvidence[];\n readonly authorizationPolicies?:\n | readonly VerifiedPrincipalPolicySelection[]\n | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly verifiedBundles?: readonly VerifiedManifestBundle[] | undefined;\n readonly verifiedHeads: readonly VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: readonly VerifiedAccessManifestCheckpointEvidence[];\n}): Promise<void> {\n await advanceKeyingCheckpointsAtomically({\n access: accessManifestCheckpointAdvances(input),\n documentPurgeCheckpoint: input.documentPurgeCheckpoint,\n execSql: input.execSql,\n organizationId: input.organizationId,\n policies: input.policies,\n authorizationPolicies: input.authorizationPolicies,\n stillCurrent: input.stillCurrent,\n verifiedBundles: input.verifiedBundles,\n });\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { KeyingVerificationError, verifySignedAccessEvent, } from "
|
|
2
|
-
import { canonicalKeyingJsonString, readCanonicalJson, readCanonicalRecord, } from "
|
|
3
|
-
import { ProjectionDependencyUnavailableError } from "
|
|
4
|
-
import { readKeyingVerificationShape } from "
|
|
5
|
-
import { readAccessEvent, readRecordString, readRequiredRecordValue, } from "
|
|
1
|
+
import { KeyingVerificationError, verifySignedAccessEvent, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { canonicalKeyingJsonString, readCanonicalJson, readCanonicalRecord, } from "../../keying/canonicalJson.js";
|
|
3
|
+
import { ProjectionDependencyUnavailableError } from "../dependencyUnavailable.js";
|
|
4
|
+
import { readKeyingVerificationShape } from "../error.js";
|
|
5
|
+
import { readAccessEvent, readRecordString, readRequiredRecordValue, } from "../readers.js";
|
|
6
6
|
function canonicalBundleJson(value, label) {
|
|
7
7
|
return readKeyingVerificationShape(() => canonicalKeyingJsonString(value, label));
|
|
8
8
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundleVerification.js","sourceRoot":"","sources":["bundleVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n verifySignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { AccessManifestBundleWireResponse } from \"@tearleads/validators/response\";\nimport type { AccessEventBundleWireResponse } from \"@tearleads/validators/util\";\nimport {\n canonicalKeyingJsonString,\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../keying/canonicalJson\";\nimport { ProjectionDependencyUnavailableError } from \"../dependencyUnavailable\";\nimport { readKeyingVerificationShape } from \"../error\";\nimport {\n readAccessEvent,\n readRecordString,\n readRequiredRecordValue,\n} from \"../readers\";\nimport type { ProjectionUserKeyResolver } from \"../types\";\n\nfunction canonicalBundleJson(value: unknown, label: string): string {\n return readKeyingVerificationShape(() =>\n canonicalKeyingJsonString(value, label),\n );\n}\n\nexport function assertCanonicalEqual(input: {\n readonly actual: unknown;\n readonly expected: unknown;\n readonly label: string;\n}): void {\n if (\n canonicalBundleJson(input.actual, `${input.label} actual`) !==\n canonicalBundleJson(input.expected, `${input.label} expected`)\n ) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n `${input.label} mismatch`,\n );\n }\n}\n\nexport function addBundleByHash(\n bundlesByHash: Map<string, AccessManifestBundleWireResponse>,\n bundle: AccessManifestBundleWireResponse,\n label: string,\n): void {\n const existing = bundlesByHash.get(bundle.manifestHash);\n if (!existing) {\n bundlesByHash.set(bundle.manifestHash, bundle);\n return;\n }\n\n if (\n canonicalBundleJson(existing, `${label} existing`) !==\n canonicalBundleJson(bundle, `${label} duplicate`)\n ) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n `Writer projection has equivocal manifest bundle ${bundle.manifestHash}`,\n );\n }\n}\n\nfunction readStandaloneEventBundle(\n bundle: AccessEventBundleWireResponse,\n label: string,\n) {\n return readKeyingVerificationShape(() => {\n const eventBundle = readCanonicalRecord(bundle, `${label} event bundle`);\n const eventHash = readRecordString(\n eventBundle,\n \"eventHash\",\n `${label} event bundle`,\n );\n const event = readAccessEvent(\n readRequiredRecordValue(eventBundle, \"event\", `${label} event bundle`),\n `${label} signed event`,\n );\n const body = readCanonicalJson(\n readRequiredRecordValue(eventBundle, \"body\", `${label} event bundle`),\n `${label} event body`,\n );\n return { eventHash, event, body };\n });\n}\n\nexport async function verifyStandaloneAccessEventBundle(input: {\n readonly bundle: AccessEventBundleWireResponse;\n readonly label: string;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n}) {\n const { eventHash, event, body } = readStandaloneEventBundle(\n input.bundle,\n input.label,\n );\n const userKey = await input.resolveUserKey(event.signerUserId);\n if (!userKey) {\n throw new ProjectionDependencyUnavailableError(\n `${input.label} signer public key could not be resolved for ${event.signerUserId}`,\n );\n }\n\n const verified = await verifySignedAccessEvent({\n body,\n event,\n signerPublicKey: userKey.signingPublicKey,\n });\n if (!verified.ok) {\n throw verified.error;\n }\n if (verified.value.eventHash !== eventHash) {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n `${input.label} event hash mismatch`,\n );\n }\n\n return verified.value;\n}\n\nexport function verifyAccessEventBundle(input: {\n readonly bundle: AccessManifestBundleWireResponse;\n readonly label: string;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n}) {\n return verifyStandaloneAccessEventBundle({\n bundle: input.bundle.event,\n label: input.label,\n resolveUserKey: input.resolveUserKey,\n });\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type AccessManifestCheckpoint, type VerifiedAccessManifestCheckpointEvidence, type VerifiedContainerAccessManifest, type VerifiedPrincipalPolicySelection } from "
|
|
2
|
-
import type { AccessManifestBundleWireResponse } from "
|
|
3
|
-
import type { DocumentPurgeCheckpoint } from "
|
|
4
|
-
import type { VerifiedManifestBundle } from "
|
|
5
|
-
import type { PrincipalPolicyCheckpointEvidence } from "
|
|
6
|
-
import type { ExecSql } from "
|
|
1
|
+
import { type AccessManifestCheckpoint, type VerifiedAccessManifestCheckpointEvidence, type VerifiedContainerAccessManifest, type VerifiedPrincipalPolicySelection } from "../../../internal/crypto/index.js";
|
|
2
|
+
import type { AccessManifestBundleWireResponse } from "../../../internal/validators/response/index.js";
|
|
3
|
+
import type { DocumentPurgeCheckpoint } from "../../persistence/documentPurgeCheckpointPersistence.js";
|
|
4
|
+
import type { VerifiedManifestBundle } from "../../persistence/verifiedManifestBundlePersistence.js";
|
|
5
|
+
import type { PrincipalPolicyCheckpointEvidence } from "../../principals/principalPolicyEvidence.js";
|
|
6
|
+
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
7
7
|
export interface ProjectionCheckpointContext {
|
|
8
8
|
readonly heldContainerHeads: VerifiedContainerAccessManifest[];
|
|
9
9
|
readonly execSql: ExecSql;
|
package/data/keyingProjectionVerification/{checkpointContext.js → checkpoints/checkpointContext.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { KeyingVerificationError, } from "
|
|
2
|
-
import { rememberVerifiedContainerHeads } from "
|
|
3
|
-
import { PrincipalAuthorizationCheckpointUnavailableError } from "
|
|
1
|
+
import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { rememberVerifiedContainerHeads } from "../../containers/shared/heldContainerHeads.js";
|
|
3
|
+
import { PrincipalAuthorizationCheckpointUnavailableError } from "../../persistence/principalAuthorizationCheckpoints.js";
|
|
4
|
+
import { ProjectionDependencyUnavailableError } from "../dependencyUnavailable.js";
|
|
5
|
+
import { projectionLifetimeGuard } from "../projectionLifetimes.js";
|
|
6
|
+
import { assertProjectionVerificationCurrent } from "../types.js";
|
|
4
7
|
import { enforceAccessManifestCheckpoints, validateAccessManifestCheckpoints, } from "./accessManifestCheckpointEnforcement.js";
|
|
5
|
-
import { ProjectionDependencyUnavailableError } from "./dependencyUnavailable.js";
|
|
6
|
-
import { projectionLifetimeGuard } from "./projectionLifetimes.js";
|
|
7
|
-
import { assertProjectionVerificationCurrent } from "./types.js";
|
|
8
8
|
export function createProjectionCheckpointContext(input) {
|
|
9
9
|
if (typeof input.execSql !== "function") {
|
|
10
10
|
throw new KeyingVerificationError("missing_dependency", "Projection verification requires durable keying checkpoint storage");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpointContext.js","sourceRoot":"","sources":["checkpointContext.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedAccessManifestCheckpointEvidence,\n type VerifiedContainerAccessManifest,\n type VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport type { AccessManifestBundleWireResponse } from \"@tearleads/validators/response\";\nimport { rememberVerifiedContainerHeads } from \"../../containers/shared/heldContainerHeads\";\nimport type { DocumentPurgeCheckpoint } from \"../../persistence/documentPurgeCheckpointPersistence\";\nimport { PrincipalAuthorizationCheckpointUnavailableError } from \"../../persistence/principalAuthorizationCheckpoints\";\nimport type { VerifiedManifestBundle } from \"../../persistence/verifiedManifestBundlePersistence\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { ProjectionDependencyUnavailableError } from \"../dependencyUnavailable\";\nimport { projectionLifetimeGuard } from \"../projectionLifetimes\";\nimport { assertProjectionVerificationCurrent } from \"../types\";\nimport {\n enforceAccessManifestCheckpoints,\n validateAccessManifestCheckpoints,\n} from \"./accessManifestCheckpointEnforcement\";\n\nexport interface ProjectionCheckpointContext {\n readonly heldContainerHeads: VerifiedContainerAccessManifest[];\n readonly execSql: ExecSql;\n // Local checkpoints read during this verification, one read per object.\n readonly localCheckpoints: Map<string, AccessManifestCheckpoint | null>;\n organizationId?: string | undefined;\n readonly policies: PrincipalPolicyCheckpointEvidence[];\n readonly authorizationPolicies: VerifiedPrincipalPolicySelection[];\n // Served bundles whose manifests verified, stored at finalization.\n readonly verifiedBundles: VerifiedManifestBundle[];\n readonly verifiedHeads: VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: VerifiedAccessManifestCheckpointEvidence[];\n}\n\nexport function createProjectionCheckpointContext(input: {\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n}): ProjectionCheckpointContext {\n if (typeof input.execSql !== \"function\") {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection verification requires durable keying checkpoint storage\",\n );\n }\n\n return {\n heldContainerHeads: [],\n execSql: input.execSql,\n localCheckpoints: new Map(),\n organizationId: input.organizationId,\n policies: [],\n authorizationPolicies: [],\n verifiedBundles: [],\n verifiedHeads: [],\n verifiedManifests: [],\n };\n}\n\nexport function observeAccessManifestCheckpoints(\n context: ProjectionCheckpointContext,\n input: {\n readonly verifiedHeads: readonly VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: readonly VerifiedAccessManifestCheckpointEvidence[];\n },\n): void {\n context.verifiedHeads.push(...input.verifiedHeads);\n context.verifiedManifests.push(...input.verifiedManifests);\n}\n\n/**\n * Records each served bundle whose manifest this verification produced, so\n * the transaction finalizing the checkpoints also stores it for later\n * citation. A bundle the projection carried but verification never reached\n * is skipped.\n */\nexport function observeVerifiedProjectionBundles(\n context: ProjectionCheckpointContext,\n bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>,\n verifiedByHash: ReadonlyMap<\n string,\n { readonly checkpoint: AccessManifestCheckpoint }\n >,\n): void {\n for (const [manifestHash, bundle] of bundlesByHash) {\n const verified = verifiedByHash.get(manifestHash);\n if (verified)\n context.verifiedBundles.push({ bundle, checkpoint: verified.checkpoint });\n }\n}\n\nexport function observePrincipalPolicy(\n context: ProjectionCheckpointContext,\n policy: PrincipalPolicyCheckpointEvidence,\n organizationId?: string | undefined,\n): void {\n if (\n organizationId !== undefined &&\n context.organizationId !== undefined &&\n context.organizationId !== organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"projection checkpoint batch crosses organization ownership\",\n );\n }\n context.organizationId ??= organizationId;\n context.policies.push(policy);\n}\n\nexport async function commitProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input?: {\n readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n input = {\n ...input,\n stillCurrent: projectionLifetimeGuard(context, input?.stillCurrent),\n };\n assertProjectionVerificationCurrent(input?.stillCurrent);\n await enforceAccessManifestCheckpoints({\n documentPurgeCheckpoint: input?.documentPurgeCheckpoint,\n execSql: input?.execSql ?? context.execSql,\n organizationId: context.organizationId,\n policies: context.policies,\n authorizationPolicies: context.authorizationPolicies,\n stillCurrent: input?.stillCurrent,\n verifiedBundles: context.verifiedBundles,\n verifiedHeads: context.verifiedHeads,\n verifiedManifests: context.verifiedManifests,\n }).catch((error: unknown) => {\n if (error instanceof PrincipalAuthorizationCheckpointUnavailableError)\n throw new ProjectionDependencyUnavailableError(error.message);\n throw error;\n });\n assertProjectionVerificationCurrent(input?.stillCurrent);\n}\n\n/** Validates against the latest durable pins without persisting new heads. */\nasync function validateProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input?: {\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n input = {\n ...input,\n stillCurrent: projectionLifetimeGuard(context, input?.stillCurrent),\n };\n assertProjectionVerificationCurrent(input?.stillCurrent);\n await validateAccessManifestCheckpoints({\n execSql: input?.execSql ?? context.execSql,\n policies: context.policies,\n authorizationPolicies: context.authorizationPolicies,\n stillCurrent: input?.stillCurrent,\n verifiedBundles: context.verifiedBundles,\n verifiedHeads: context.verifiedHeads,\n verifiedManifests: context.verifiedManifests,\n }).catch((error: unknown) => {\n if (error instanceof PrincipalAuthorizationCheckpointUnavailableError)\n throw new ProjectionDependencyUnavailableError(error.message);\n throw error;\n });\n assertProjectionVerificationCurrent(input?.stillCurrent);\n}\n\nexport async function finalizeProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input: {\n readonly execSql?: ExecSql | undefined;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n if (input.persistVerificationCheckpoints === false) {\n await validateProjectionCheckpoints(context, input);\n return;\n }\n await commitProjectionCheckpoints(context, input);\n if (input.stillCurrent?.() === false) return;\n const organizationId =\n context.organizationId ??\n context.heldContainerHeads[0]?.state.organizationId;\n if (organizationId === undefined) return;\n try {\n rememberVerifiedContainerHeads({\n organizationId,\n execSql: input.execSql ?? context.execSql,\n heads: context.heldContainerHeads,\n policies: context.policies,\n });\n } catch {\n // Checkpoints are already committed. Optional re-citation evidence must\n // never change successful verification into a caller-visible refusal.\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { verifyAccessManifestLocalCheckpoint, } from "
|
|
2
|
-
import { loadAccessManifestCheckpoint } from "
|
|
1
|
+
import { verifyAccessManifestLocalCheckpoint, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { loadAccessManifestCheckpoint } from "../../persistence/keyingCheckpointPersistence.js";
|
|
3
3
|
/**
|
|
4
4
|
* The local checkpoint for one object, read once per verification: every
|
|
5
5
|
* checkpoint-enforced element of a served path reads its own checkpoint,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestCheckpointVerification.js","sourceRoot":"","sources":["manifestCheckpointVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifest,\n type AccessManifestCheckpoint,\n type VerifiedAccessManifestCheckpointEvidence,\n verifyAccessManifestLocalCheckpoint,\n} from \"@tearleads/crypto\";\nimport { loadAccessManifestCheckpoint } from \"../../persistence/keyingCheckpointPersistence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\n\n/**\n * The local checkpoint for one object, read once per verification: every\n * checkpoint-enforced element of a served path reads its own checkpoint,\n * and the atomic advance re-validates every checkpoint at commit.\n */\nasync function loadLocalAccessManifestCheckpoint(input: {\n readonly execSql: ExecSql;\n readonly localCheckpoints: Map<string, AccessManifestCheckpoint | null>;\n readonly objectId: string;\n readonly objectKind: AccessManifest[\"objectKind\"];\n readonly organizationId: string;\n}): Promise<AccessManifestCheckpoint | null> {\n const key = JSON.stringify([\n input.objectKind,\n input.organizationId,\n input.objectId,\n ]);\n const cached = input.localCheckpoints.get(key);\n if (cached !== undefined) return cached;\n const loaded = await loadAccessManifestCheckpoint(\n input.execSql,\n input.objectKind,\n input.organizationId,\n input.objectId,\n );\n input.localCheckpoints.set(key, loaded);\n return loaded;\n}\n\ninterface ManifestCheckpointVerificationInput<\n TManifest extends VerifiedAccessManifestCheckpointEvidence,\n> {\n readonly checkpointPredecessors: readonly TManifest[];\n readonly localCheckpoint: AccessManifestCheckpoint | null;\n}\n\nfunction isCheckpointPredecessor(input: {\n readonly candidate: VerifiedAccessManifestCheckpointEvidence;\n readonly current: AccessManifest;\n readonly localCheckpoint: AccessManifestCheckpoint;\n}): boolean {\n const candidate = input.candidate.checkpoint;\n return (\n candidate.objectKind === input.current.objectKind &&\n candidate.organizationId === input.current.organizationId &&\n candidate.objectId === input.current.objectId &&\n candidate.epoch > input.localCheckpoint.epoch &&\n candidate.epoch < input.current.epoch\n );\n}\n\nexport async function loadManifestCheckpointVerification<\n TManifest extends VerifiedAccessManifestCheckpointEvidence,\n>(input: {\n readonly current: AccessManifest;\n readonly execSql: ExecSql;\n readonly localCheckpoints: Map<string, AccessManifestCheckpoint | null>;\n readonly verifiedManifests: ReadonlyMap<string, TManifest>;\n}): Promise<ManifestCheckpointVerificationInput<TManifest>> {\n const localCheckpoint = await loadLocalAccessManifestCheckpoint({\n execSql: input.execSql,\n localCheckpoints: input.localCheckpoints,\n objectId: input.current.objectId,\n objectKind: input.current.objectKind,\n organizationId: input.current.organizationId,\n });\n const checkpointPredecessors = localCheckpoint\n ? [...input.verifiedManifests.values()]\n .filter((candidate) =>\n isCheckpointPredecessor({\n candidate,\n current: input.current,\n localCheckpoint,\n }),\n )\n .sort((left, right) => left.checkpoint.epoch - right.checkpoint.epoch)\n : [];\n return { checkpointPredecessors, localCheckpoint };\n}\n\nexport async function verifyCachedManifestCheckpoint(input: {\n readonly current: VerifiedAccessManifestCheckpointEvidence;\n readonly execSql: ExecSql;\n readonly localCheckpoints: Map<string, AccessManifestCheckpoint | null>;\n readonly verifiedManifests: ReadonlyMap<\n string,\n VerifiedAccessManifestCheckpointEvidence\n >;\n}): Promise<void> {\n const checkpoint = await loadManifestCheckpointVerification({\n current: input.current.manifest,\n execSql: input.execSql,\n localCheckpoints: input.localCheckpoints,\n verifiedManifests: input.verifiedManifests,\n });\n verifyAccessManifestLocalCheckpoint({\n checkpointPredecessors: checkpoint.checkpointPredecessors,\n current: {\n ...input.current.checkpoint,\n previousManifestHash: input.current.manifest.previousManifestHash,\n },\n localCheckpoint: checkpoint.localCheckpoint,\n });\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { KeyingVerificationError, } from "
|
|
2
|
-
import { readCanonicalRecord } from "
|
|
3
|
-
import { readKeyingVerificationShape } from "
|
|
4
|
-
import { readRecordNullableString } from "
|
|
1
|
+
import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { readCanonicalRecord } from "../../keying/canonicalJson.js";
|
|
3
|
+
import { readKeyingVerificationShape } from "../error.js";
|
|
4
|
+
import { readRecordNullableString } from "../readers.js";
|
|
5
5
|
function bundleContainerId(bundle, label) {
|
|
6
6
|
return readKeyingVerificationShape(() => readRecordNullableString(readCanonicalRecord(bundle.state, `${label} state`), "containerId", `${label} state`));
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"containerAncestorCitations.js","sourceRoot":"","sources":["containerAncestorCitations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type VerifiedAccessEvent,\n type VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport type { AccessManifestBundleWireResponse } from \"@tearleads/validators/response\";\nimport { readCanonicalRecord } from \"../../keying/canonicalJson\";\nimport { readKeyingVerificationShape } from \"../error\";\nimport { readRecordNullableString } from \"../readers\";\n\n/**\n * A container manifest pins the parent manifest it was created or moved\n * under, and successors inherit that pin, so the pin says nothing about the\n * ancestor heads a later grant, revoke, or rekey was actually authorized\n * under. Those heads are in the event: every container event signs the\n * manifest hashes of the path it was committed against, and the API refuses\n * an event whose citations are not the current heads at commit time. So a\n * head's authorization path is rebuilt here from its citations, root to\n * parent, and the signer is checked against those heads rather than against\n * whatever path the server pairs with the manifest.\n *\n * A head must also cite, for every ancestor, a head that is or descends from\n * the head an earlier signed statement already established, so an ancestor\n * head one signed statement established can never be rolled back or forked\n * away for a later one.\n *\n * As with principal policies, a successor new to a device need not cite the\n * authority's served current head. An honest server serves a\n * child head citing the ancestor head that was current when it was\n * committed, signed by a member since revoked at that ancestor, and refusing\n * that shape would leave every device holding the child unable to supersede\n * it. What can be refused is the opposite disagreement: a served current\n * ancestor head that does not descend from a head the child's signed event\n * proves exists is a stale or forked ancestor, whatever the server calls\n * current.\n */\n\ninterface CitedAncestorResolutionInput {\n readonly bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>;\n readonly label: string;\n readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n readonly verifyHistoryBundle: (\n bundle: AccessManifestBundleWireResponse,\n label: string,\n ) => Promise<VerifiedContainerAccessManifest>;\n}\n\nfunction bundleContainerId(\n bundle: AccessManifestBundleWireResponse,\n label: string,\n): string | null {\n return readKeyingVerificationShape(() =>\n readRecordNullableString(\n readCanonicalRecord(bundle.state, `${label} state`),\n \"containerId\",\n `${label} state`,\n ),\n );\n}\n\nfunction citedContainerId(\n input: CitedLineageInput,\n manifestHash: string,\n): string | null {\n const verified = input.verifiedByHash.get(manifestHash);\n if (verified) return verified.state.containerId;\n const bundle = input.bundlesByHash.get(manifestHash);\n return bundle ? bundleContainerId(bundle, input.label) : null;\n}\n\nfunction citedManifestHashForContainer(\n input: CitedAncestorResolutionInput,\n cited: readonly string[],\n containerId: string,\n): string {\n const hashes = cited.filter(\n (manifestHash) => citedContainerId(input, manifestHash) === containerId,\n );\n const [manifestHash] = hashes;\n if (manifestHash === undefined) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n `${input.label} does not cite a served head of its parent container ${containerId}`,\n );\n }\n if (hashes.length > 1) {\n throw new KeyingVerificationError(\n \"duplicate_entry\",\n `${input.label} cites more than one head of container ${containerId}`,\n );\n }\n return manifestHash;\n}\n\nasync function resolveCitedManifest(\n input: CitedAncestorResolutionInput,\n manifestHash: string,\n containerId: string,\n): Promise<VerifiedContainerAccessManifest> {\n const verified = input.verifiedByHash.get(manifestHash);\n if (verified) return verified;\n const bundle = input.bundlesByHash.get(manifestHash);\n if (!bundle) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n `${input.label} cites a head of container ${containerId} that the projection does not serve`,\n );\n }\n return input.verifyHistoryBundle(\n bundle,\n `${input.label} cited ancestor ${containerId}`,\n );\n}\n\n/**\n * The ancestor path, root first, that a container event cites, ending at the\n * head of `parentContainerId`. Empty for a root container.\n */\nexport async function resolveCitedAncestorPath(\n input: CitedAncestorResolutionInput & {\n readonly event: VerifiedAccessEvent;\n readonly parentContainerId: string | null;\n },\n): Promise<VerifiedContainerAccessManifest[]> {\n const cited = input.event.event.dependencyManifestHashes;\n const chain: VerifiedContainerAccessManifest[] = [];\n const seen = new Set<string>();\n let containerId = input.parentContainerId;\n while (containerId !== null) {\n if (seen.has(containerId)) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${input.label} cited ancestors form a cycle at ${containerId}`,\n );\n }\n seen.add(containerId);\n const ancestor = await resolveCitedManifest(\n input,\n citedManifestHashForContainer(input, cited, containerId),\n containerId,\n );\n chain.unshift(ancestor);\n containerId = ancestor.state.parentContainerId;\n }\n return chain;\n}\n\n/** What the lineage rules read: the served and the verified bundles. */\nexport type CitedLineageInput = Pick<\n CitedAncestorResolutionInput,\n \"bundlesByHash\" | \"label\" | \"verifiedByHash\"\n>;\n\n/**\n * The verified head of `containerId` among the cited hashes, if any. Reads\n * verified manifests only: a cited hash the pass has not verified is not a\n * head to reason about, and every caller runs after the cited ancestor path\n * resolved and verified the chain. An event cites one head per container,\n * so a second verified one is a served citation set that was tampered with,\n * not a choice to make.\n */\nexport function verifiedCitedHead(input: {\n readonly cited: readonly string[];\n readonly containerId: string;\n readonly label: string;\n readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n}): VerifiedContainerAccessManifest | undefined {\n let found: VerifiedContainerAccessManifest | undefined;\n for (const manifestHash of input.cited) {\n const verified = input.verifiedByHash.get(manifestHash);\n if (verified?.state.containerId !== input.containerId) continue;\n if (found && found.manifestHash !== verified.manifestHash) {\n throw new KeyingVerificationError(\n \"duplicate_entry\",\n `${input.label} cites more than one head of container ${input.containerId}`,\n );\n }\n found = verified;\n }\n return found;\n}\n\n/**\n * Whether `head` is `floor` or descends from it through verified\n * predecessors. Epochs alone would let a same-epoch fork signed under an\n * older head pass; lineage cannot be forged without the chain. Every\n * predecessor of a verified manifest was verified with it, so a hop that is\n * not in the verified set means the chain was not served.\n */\nfunction descendsFrom(\n verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>,\n head: VerifiedContainerAccessManifest,\n floor: VerifiedContainerAccessManifest,\n): boolean {\n let current: VerifiedContainerAccessManifest | undefined = head;\n while (current && current.state.epoch >= floor.state.epoch) {\n if (current.manifestHash === floor.manifestHash) return true;\n const previousHash: string | null = current.state.previousManifestHash;\n current =\n previousHash === null ? undefined : verifiedByHash.get(previousHash);\n }\n return false;\n}\n\n/** The cited head must be the established head or descend from it. */\nfunction assertCitedHeadDescendsFrom(\n input: CitedLineageInput,\n cited: VerifiedContainerAccessManifest,\n floor: VerifiedContainerAccessManifest,\n): void {\n if (descendsFrom(input.verifiedByHash, cited, floor)) return;\n throw new KeyingVerificationError(\n \"rollback\",\n `${input.label} cites a head of container ${cited.state.containerId} that does not descend from the head an earlier signed statement already proved current`,\n );\n}\n\n/**\n * A head must not cite a head of any ancestor that does not descend from the\n * head an earlier signed statement already established: the manifest before\n * it cited that ancestor, the previous manifest's own pin when this is its\n * parent, or a cited child of that ancestor was created or moved under it and\n * cited it. Ancestors no statement establishes are skipped.\n */\nexport function assertCitedAncestorsDoNotRegress(\n input: CitedLineageInput & {\n readonly citedAncestors: readonly VerifiedContainerAccessManifest[];\n readonly previousManifest: VerifiedContainerAccessManifest | null;\n },\n): void {\n const previous = input.previousManifest;\n const previousCited = previous?.event.event.dependencyManifestHashes ?? [];\n input.citedAncestors.forEach((ancestor, index) => {\n const containerId = ancestor.state.containerId;\n const citedChild = input.citedAncestors[index + 1] ?? previous;\n const floors = [\n verifiedCitedHead({\n cited: previousCited,\n containerId,\n label: input.label,\n verifiedByHash: input.verifiedByHash,\n }),\n ...(citedChild\n ? [\n input.verifiedByHash.get(citedChild.state.parentManifestHash ?? \"\"),\n verifiedCitedHead({\n cited: citedChild.event.event.dependencyManifestHashes,\n containerId,\n label: input.label,\n verifiedByHash: input.verifiedByHash,\n }),\n ]\n : []),\n ];\n for (const floor of floors) {\n if (floor && floor.state.containerId === containerId) {\n assertCitedHeadDescendsFrom(input, ancestor, floor);\n }\n }\n });\n}\n\n/**\n * Every served current ancestor head must be, or descend through verified\n * predecessors from, the head of that container the head's signed event\n * cites. A served head older than the cited one, or a same-epoch fork of it,\n * is a rollback the signature proves: the cited head exists. A served head\n * newer than the cited one is the ordinary lag of a descendant behind its\n * ancestors, and an ancestor the head does not cite at all joined the path\n * when an ancestor between them moved; neither is refused.\n */\nexport function assertServedAncestorsDescendFromCitations(input: {\n readonly head: VerifiedContainerAccessManifest;\n readonly label: string;\n readonly servedAncestors: readonly VerifiedContainerAccessManifest[];\n readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n}): void {\n const citations = input.head.event.event.dependencyManifestHashes;\n for (const served of input.servedAncestors) {\n const containerId = served.state.containerId;\n const cited = verifiedCitedHead({\n cited: citations,\n containerId,\n label: input.label,\n verifiedByHash: input.verifiedByHash,\n });\n if (!cited || descendsFrom(input.verifiedByHash, served, cited)) continue;\n throw new KeyingVerificationError(\n \"rollback\",\n `${input.label} cites a head of ancestor container ${containerId} that the served current head does not descend from`,\n );\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KeyingVerificationError, } from "
|
|
1
|
+
import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Walk a verified head back to its epoch-1 `container.create`. Head
|
|
4
4
|
* verification already verified every predecessor it cites (a head is only
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createProjectionCheckpointContext, finalizeProjectionCheckpoints, observeVerifiedProjectionBundles, } from "
|
|
1
|
+
import { createProjectionCheckpointContext, finalizeProjectionCheckpoints, observeVerifiedProjectionBundles, } from "../checkpoints/checkpointContext.js";
|
|
2
|
+
import { verifyProjectionAuthorizationEvidence } from "../principalPolicy/projectionAuthorizationEvidence.js";
|
|
3
|
+
import { projectionLifetimeGuard } from "../projectionLifetimes.js";
|
|
4
|
+
import { assertProjectionVerificationCurrent } from "../types.js";
|
|
2
5
|
import { verifyContainerManifestPath } from "./containerPathVerification.js";
|
|
3
6
|
import { addContainerWriterProjectionBundles } from "./containerProjectionVerification.js";
|
|
4
|
-
import { verifyProjectionAuthorizationEvidence } from "./projectionAuthorizationEvidence.js";
|
|
5
|
-
import { projectionLifetimeGuard } from "./projectionLifetimes.js";
|
|
6
|
-
import { assertProjectionVerificationCurrent } from "./types.js";
|
|
7
7
|
/** Authenticate immutable destination roles without advancing write-authority pins. */
|
|
8
8
|
export async function verifyContainerDestinationProjection(input) {
|
|
9
9
|
const bundlesByHash = new Map();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"containerDestinationVerification.js","sourceRoot":"","sources":["containerDestinationVerification.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,iCAAiC,EACjC,6BAA6B,EAC7B,gCAAgC,GACjC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,qCAAqC,EAAE,MAAM,oDAAoD,CAAC;AAC3G,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAKjE,OAAO,EAAE,mCAAmC,EAAE,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,mCAAmC,EAAE,MAAM,mCAAmC,CAAC;AAExF,uFAAuF;AACvF,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAQ1D;IAKC,MAAM,aAAa,GAAG,IAAI,GAAG,EAA4C,CAAC;IAC1E,mCAAmC,CACjC,aAAa,EACb,KAAK,CAAC,UAAU,EAChB,uBAAuB,CACxB,CAAC;IACF,MAAM,cAAc,GAAG,IAAI,GAAG,EAA2C,CAAC;IAC1E,MAAM,iBAAiB,GAAG,iCAAiC,CAAC;QAC1D,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc;KAChD,CAAC,CAAC;IACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAE,CAAC;IACvC,MAAM,qBAAqB,GAAG,MAAM,qCAAqC,CAAC;QACxE,OAAO,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;QACpC,iBAAiB;QACjB,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc;QAC/C,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,cAAc;QAC/C,oBAAoB;QACpB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;KACvE,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,2BAA2B,CAAC;QAC7C,qBAAqB;QACrB,4BAA4B,EAAE,IAAI;QAClC,uBAAuB,EAAE,YAAY;QACrC,aAAa;QACb,iBAAiB;QACjB,uBAAuB,EAAE,KAAK;QAC9B,eAAe,EAAE,KAAK;QACtB,KAAK,EAAE,uBAAuB;QAC9B,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI;QAC3B,oBAAoB;QACpB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,cAAc;KACf,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,uBAAuB,CACrC,iBAAiB,EACjB,KAAK,CAAC,YAAY,CACnB,CAAC;IACF,kEAAkE;IAClE,gCAAgC,CAC9B,iBAAiB,EACjB,aAAa,EACb,cAAc,CACf,CAAC;IACF,MAAM,6BAA6B,CAAC,iBAAiB,EAAE;QACrD,YAAY,EAAE,OAAO;QACrB,8BAA8B,EAAE,KAAK;KACtC,CAAC,CAAC;IACH,mCAAmC,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AAClC,CAAC","sourcesContent":["import type { VerifiedContainerAccessManifest } from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWireResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport {\n createProjectionCheckpointContext,\n finalizeProjectionCheckpoints,\n observeVerifiedProjectionBundles,\n} from \"../checkpoints/checkpointContext\";\nimport { verifyProjectionAuthorizationEvidence } from \"../principalPolicy/projectionAuthorizationEvidence\";\nimport { projectionLifetimeGuard } from \"../projectionLifetimes\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../types\";\nimport { assertProjectionVerificationCurrent } from \"../types\";\nimport { verifyContainerManifestPath } from \"./containerPathVerification\";\nimport { addContainerWriterProjectionBundles } from \"./containerProjectionVerification\";\n\n/** Authenticate immutable destination roles without advancing write-authority pins. */\nexport async function verifyContainerDestinationProjection(input: {\n readonly execSql: ExecSql;\n readonly projection: ContainerWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<{\n readonly path: VerifiedContainerAccessManifest[];\n /** Every manifest verified on the way, including each head's lineage. */\n readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n}> {\n const bundlesByHash = new Map<string, AccessManifestBundleWireResponse>();\n addContainerWriterProjectionBundles(\n bundlesByHash,\n input.projection,\n \"Container destination\",\n );\n const verifiedByHash = new Map<string, VerifiedContainerAccessManifest>();\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n organizationId: input.projection.organizationId,\n });\n const principalPolicyCache = new Map();\n const authorizationEvidence = await verifyProjectionAuthorizationEvidence({\n bundles: [...bundlesByHash.values()],\n checkpointContext,\n policyEvidence: input.projection.policyEvidence,\n organizationId: input.projection.organizationId,\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const path = await verifyContainerManifestPath({\n authorizationEvidence,\n requireAuthorizationEvidence: true,\n authorizationMembership: \"referenced\",\n bundlesByHash,\n checkpointContext,\n enforceLocalCheckpoints: false,\n servedAsCurrent: false,\n label: \"Container destination\",\n path: input.projection.path,\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash,\n });\n const current = projectionLifetimeGuard(\n checkpointContext,\n input.stillCurrent,\n );\n // Authenticated bytes, not authority: a later read may cite them.\n observeVerifiedProjectionBundles(\n checkpointContext,\n bundlesByHash,\n verifiedByHash,\n );\n await finalizeProjectionCheckpoints(checkpointContext, {\n stillCurrent: current,\n persistVerificationCheckpoints: false,\n });\n assertProjectionVerificationCurrent(current);\n return { path, verifiedByHash };\n}\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { KeyingVerificationError, principalPolicyMatchesReference, verifyContainerAccessManifest, } from "
|
|
2
|
-
import { readCanonicalJson, readCanonicalRecord, } from "
|
|
3
|
-
import { assertCanonicalEqual, verifyAccessEventBundle, } from "
|
|
1
|
+
import { KeyingVerificationError, principalPolicyMatchesReference, verifyContainerAccessManifest, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { readCanonicalJson, readCanonicalRecord, } from "../../keying/canonicalJson.js";
|
|
3
|
+
import { assertCanonicalEqual, verifyAccessEventBundle, } from "../checkpoints/bundleVerification.js";
|
|
4
|
+
import { loadManifestCheckpointVerification, verifyCachedManifestCheckpoint, } from "../checkpoints/manifestCheckpointVerification.js";
|
|
5
|
+
import { readKeyingVerificationShape } from "../error.js";
|
|
6
|
+
import { collectReferencedPrincipalPolicies } from "../principalPolicy/principalPolicyVerification.js";
|
|
7
|
+
import { readAccessManifest, readRecordNullableString } from "../readers.js";
|
|
4
8
|
import { assertCitedAncestorsDoNotRegress, resolveCitedAncestorPath, } from "./containerAncestorCitations.js";
|
|
5
|
-
import { readKeyingVerificationShape } from "./error.js";
|
|
6
|
-
import { loadManifestCheckpointVerification, verifyCachedManifestCheckpoint, } from "./manifestCheckpointVerification.js";
|
|
7
|
-
import { collectReferencedPrincipalPolicies } from "./principalPolicyVerification.js";
|
|
8
|
-
import { readAccessManifest, readRecordNullableString } from "./readers.js";
|
|
9
9
|
async function collectManifestAuthorizationPolicies(input) {
|
|
10
10
|
const missingPrincipalHeads = input.referencedPrincipalHeads.filter((reference) => !input.authorizationEvidence.some((policy) => principalPolicyMatchesReference({ policy, reference })));
|
|
11
11
|
if (input.requireAuthorizationEvidence && missingPrincipalHeads.length > 0) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"containerManifestVerification.js","sourceRoot":"","sources":["containerManifestVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyAuthorization } from \"@tearleads/crypto\";\nimport {\n KeyingVerificationError,\n principalPolicyMatchesReference,\n type VerifiedContainerAccessManifest,\n verifyContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport type { AccessManifestBundleWireResponse } from \"@tearleads/validators/response\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../keying/canonicalJson\";\nimport {\n assertCanonicalEqual,\n verifyAccessEventBundle,\n} from \"../checkpoints/bundleVerification\";\nimport type { ProjectionCheckpointContext } from \"../checkpoints/checkpointContext\";\nimport {\n loadManifestCheckpointVerification,\n verifyCachedManifestCheckpoint,\n} from \"../checkpoints/manifestCheckpointVerification\";\nimport { readKeyingVerificationShape } from \"../error\";\nimport { collectReferencedPrincipalPolicies } from \"../principalPolicy/principalPolicyVerification\";\nimport { readAccessManifest, readRecordNullableString } from \"../readers\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../types\";\nimport {\n assertCitedAncestorsDoNotRegress,\n type CitedLineageInput,\n resolveCitedAncestorPath,\n} from \"./containerAncestorCitations\";\n\nasync function collectManifestAuthorizationPolicies(input: {\n readonly authorizationEvidence: readonly PrincipalPolicyAuthorization[];\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly organizationId: string;\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly referencedPrincipalHeads: Parameters<\n typeof principalPolicyMatchesReference\n >[0][\"reference\"][];\n readonly requireAuthorizationEvidence: boolean;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}) {\n const missingPrincipalHeads = input.referencedPrincipalHeads.filter(\n (reference) =>\n !input.authorizationEvidence.some((policy) =>\n principalPolicyMatchesReference({ policy, reference }),\n ),\n );\n if (input.requireAuthorizationEvidence && missingPrincipalHeads.length > 0) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection omits required principal policy evidence\",\n );\n }\n if (input.requireAuthorizationEvidence)\n return [...input.authorizationEvidence];\n return [\n ...input.authorizationEvidence,\n ...(await collectReferencedPrincipalPolicies({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n references: missingPrincipalHeads,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n })),\n ];\n}\n\nexport async function verifyContainerManifestBundle(input: {\n readonly authorizationMembership?: \"current\" | \"referenced\" | undefined;\n readonly authorizationEvidence?:\n | readonly PrincipalPolicyAuthorization[]\n | undefined;\n readonly bundle: AccessManifestBundleWireResponse;\n readonly bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>;\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly enforceLocalCheckpoint: boolean;\n readonly label: string;\n readonly parentPath: readonly VerifiedContainerAccessManifest[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly requireAuthorizationEvidence?: boolean | undefined;\n readonly verifiedByHash: Map<string, VerifiedContainerAccessManifest>;\n // Manifest hashes whose verification is in progress up the call stack.\n // Previous manifests, pinned parents, and cited ancestors all recurse\n // before a bundle's own hash is checked, so served bundles that refer to\n // each other under claimed hashes would otherwise recurse without end.\n readonly verifying?: Set<string> | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<VerifiedContainerAccessManifest> {\n const parentPath =\n await resolveContainerManifestVerificationParentPath(input);\n const cached = input.verifiedByHash.get(input.bundle.manifestHash);\n if (cached) {\n assertContainerParentPathMatches({\n label: input.label,\n parentPath,\n verifiedManifest: cached,\n });\n if (input.enforceLocalCheckpoint) {\n await verifyCachedManifestCheckpoint({\n current: cached,\n execSql: input.checkpointContext.execSql,\n localCheckpoints: input.checkpointContext.localCheckpoints,\n verifiedManifests: input.verifiedByHash,\n });\n }\n return cached;\n }\n\n const verifying = input.verifying ?? new Set<string>();\n if (verifying.has(input.bundle.manifestHash)) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${input.label} refers back to a manifest whose verification it is part of`,\n );\n }\n verifying.add(input.bundle.manifestHash);\n try {\n return await verifyFreshContainerManifestBundle(\n { ...input, verifying },\n parentPath,\n );\n } finally {\n verifying.delete(input.bundle.manifestHash);\n }\n}\n\ntype CitedAncestorInput = Parameters<typeof verifyContainerManifestBundle>[0];\n\nasync function verifyFreshContainerManifestBundle(\n input: CitedAncestorInput,\n parentPath: readonly VerifiedContainerAccessManifest[],\n): Promise<VerifiedContainerAccessManifest> {\n const event = await verifyAccessEventBundle(input);\n const manifest = readAccessManifest(\n input.bundle.manifest,\n `${input.label} manifest`,\n );\n const authorization = await resolveContainerManifestAuthorization(\n input,\n event,\n parentPath,\n );\n const { citedAncestors, previousManifest, sourceAncestors } = authorization;\n const principalPolicies = await collectManifestAuthorizationPolicies({\n authorizationEvidence: input.authorizationEvidence ?? [],\n checkpointContext: input.checkpointContext,\n organizationId: event.event.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n referencedPrincipalHeads: [\n ...authorization.referencedPrincipalHeads,\n ...manifest.referencedPrincipalHeads,\n ],\n requireAuthorizationEvidence: input.requireAuthorizationEvidence ?? false,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const checkpointVerification = input.enforceLocalCheckpoint\n ? await loadManifestCheckpointVerification({\n current: manifest,\n execSql: input.checkpointContext.execSql,\n localCheckpoints: input.checkpointContext.localCheckpoints,\n verifiedManifests: input.verifiedByHash,\n })\n : null;\n\n const verified = await verifyContainerAccessManifest({\n // Served manifests were committed under their signed policy references.\n // Current membership still gates new writes in the API verifier.\n authorizationMembership: input.authorizationMembership ?? \"referenced\",\n destinationParentContainerPath: citedAncestors,\n event,\n expectedManifestHash: input.bundle.manifestHash,\n manifest,\n parentContainerPath: citedAncestors,\n principalPolicies,\n ...(checkpointVerification ?? {}),\n ...(previousManifest\n ? {\n previousContainerPath: [...sourceAncestors, previousManifest],\n previousManifest,\n }\n : { previousManifest: null }),\n });\n if (!verified.ok) {\n throw new KeyingVerificationError(\n verified.error.code,\n `${input.label} manifest verification failed: ${verified.error.message}`,\n );\n }\n\n assertCanonicalEqual({\n actual: input.bundle.state,\n expected: readCanonicalJson(verified.value.state, `${input.label} state`),\n label: `${input.label} state`,\n });\n input.verifiedByHash.set(input.bundle.manifestHash, verified.value);\n\n return verified.value;\n}\n\n/**\n * The paths a container event is authorized against: its previous manifest\n * and the ancestor heads its signed event cites, root to parent.\n */\nasync function resolveContainerManifestAuthorization(\n input: CitedAncestorInput,\n event: VerifiedContainerAccessManifest[\"event\"],\n parentPath: readonly VerifiedContainerAccessManifest[],\n) {\n const previousManifest =\n event.event.previousManifestHash === null\n ? null\n : await verifyPreviousContainerManifest({\n ...input,\n parentPath,\n previousManifestHash: event.event.previousManifestHash,\n });\n // Resolve the signed placement lineage, never the server-supplied wire state.\n // Rotations also resolve their new epoch's exact signed parent citation via\n // cited-ancestor verification below; that can differ from this previous path.\n const eventType = event.event.eventType;\n const { parentContainerId, parentManifestHash } =\n previousManifest && eventType !== \"container.move\"\n ? previousManifest.state\n : readContainerEventBodyParentReference(event, input.label);\n if (\n previousManifest === null &&\n parentManifestHash !== null &&\n !event.event.dependencyManifestHashes.includes(parentManifestHash)\n ) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n `${input.label} does not cite the parent manifest it was created under`,\n );\n }\n const lineage: CitedLineageInput = {\n bundlesByHash: input.bundlesByHash,\n label: input.label,\n verifiedByHash: input.verifiedByHash,\n };\n const citedAncestors = await resolveCitedAncestors(input, event, {\n parentContainerId,\n });\n assertCitedAncestorsDoNotRegress({\n ...lineage,\n citedAncestors,\n previousManifest,\n });\n // A move's source path leads to the previous manifest's parent, and the\n // move event cites that path too; the destination path is the one above.\n // The source path is held to the same no-regression rule.\n const sourceAncestors =\n eventType === \"container.move\" && previousManifest\n ? await resolveCitedAncestors(input, event, {\n parentContainerId: previousManifest.state.parentContainerId,\n })\n : citedAncestors;\n if (sourceAncestors !== citedAncestors) {\n assertCitedAncestorsDoNotRegress({\n ...lineage,\n citedAncestors: sourceAncestors,\n previousManifest,\n });\n }\n const ancestors = [\n ...parentPath,\n ...citedAncestors,\n ...(sourceAncestors === citedAncestors ? [] : sourceAncestors),\n ];\n return {\n citedAncestors,\n previousManifest,\n referencedPrincipalHeads: [\n ...ancestors.flatMap(\n (ancestor) => ancestor.state.referencedPrincipalHeads,\n ),\n ...(previousManifest?.state.referencedPrincipalHeads ?? []),\n ],\n sourceAncestors,\n };\n}\n\nfunction citedAncestorResolutionInput(input: CitedAncestorInput) {\n return {\n bundlesByHash: input.bundlesByHash,\n label: input.label,\n verifiedByHash: input.verifiedByHash,\n // A cited head older than the served one is history: authorize it at the\n // membership it referenced, as the previous manifest is.\n verifyHistoryBundle: (\n bundle: AccessManifestBundleWireResponse,\n label: string,\n ) =>\n verifyContainerManifestBundle({\n ...input,\n authorizationMembership: \"referenced\",\n bundle,\n enforceLocalCheckpoint: false,\n label,\n }),\n };\n}\n\nfunction resolveCitedAncestors(\n input: CitedAncestorInput,\n event: VerifiedContainerAccessManifest[\"event\"],\n reference: { readonly parentContainerId: string | null },\n): Promise<VerifiedContainerAccessManifest[]> {\n return resolveCitedAncestorPath({\n ...citedAncestorResolutionInput(input),\n event,\n parentContainerId: reference.parentContainerId,\n });\n}\n\nfunction assertContainerParentPathMatches(input: {\n readonly label: string;\n readonly parentPath: readonly VerifiedContainerAccessManifest[];\n readonly verifiedManifest: VerifiedContainerAccessManifest;\n}): void {\n const actualParentManifestHash =\n input.parentPath.at(-1)?.manifestHash ?? null;\n if (\n actualParentManifestHash !== input.verifiedManifest.state.parentManifestHash\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${input.label} parent path mismatch`,\n );\n }\n}\n\ninterface ContainerParentReference {\n parentContainerId: string | null;\n parentManifestHash: string | null;\n}\n\nfunction readParentReference(\n value: unknown,\n label: string,\n): ContainerParentReference {\n return readKeyingVerificationShape(() => {\n const record = readCanonicalRecord(value, label);\n\n return {\n parentContainerId: readRecordNullableString(\n record,\n \"parentContainerId\",\n label,\n ),\n parentManifestHash: readRecordNullableString(\n record,\n \"parentManifestHash\",\n label,\n ),\n };\n });\n}\n\nfunction readContainerManifestParentReference(\n bundle: AccessManifestBundleWireResponse,\n label: string,\n): ContainerParentReference {\n return readParentReference(bundle.state, `${label} state`);\n}\n\n/** The parent a create or move body pins, read from the signed body. */\nfunction readContainerEventBodyParentReference(\n event: VerifiedContainerAccessManifest[\"event\"],\n label: string,\n): ContainerParentReference {\n return readParentReference(event.body, `${label} event body`);\n}\n\nasync function resolveContainerManifestVerificationParentPath(input: {\n readonly authorizationEvidence?:\n | readonly PrincipalPolicyAuthorization[]\n | undefined;\n readonly bundle: AccessManifestBundleWireResponse;\n readonly bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>;\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly label: string;\n readonly parentPath: readonly VerifiedContainerAccessManifest[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly verifiedByHash: Map<string, VerifiedContainerAccessManifest>;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<readonly VerifiedContainerAccessManifest[]> {\n // Descendants keep the parent manifest hash they were created or moved under;\n // a later parent share/rekey must not require rewriting descendant manifests.\n const { parentContainerId, parentManifestHash } =\n readContainerManifestParentReference(input.bundle, input.label);\n if (parentContainerId === null || parentManifestHash === null) {\n return [];\n }\n\n const parentPathIndex = input.parentPath.findIndex(\n (manifest) =>\n manifest.state.containerId === parentContainerId &&\n manifest.manifestHash === parentManifestHash,\n );\n if (parentPathIndex >= 0) {\n return input.parentPath.slice(0, parentPathIndex + 1);\n }\n\n const parentBundle = input.bundlesByHash.get(parentManifestHash);\n if (!parentBundle) {\n return input.parentPath;\n }\n\n const parentParentPath = await resolveContainerManifestVerificationParentPath(\n {\n ...input,\n bundle: parentBundle,\n label: `${input.label} parent manifest`,\n },\n );\n const verifiedParent = await verifyContainerManifestBundle({\n ...input,\n bundle: parentBundle,\n enforceLocalCheckpoint: false,\n label: `${input.label} parent manifest`,\n parentPath: parentParentPath,\n });\n if (verifiedParent.state.containerId !== parentContainerId) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n `${input.label} parent manifest container mismatch`,\n );\n }\n\n return [...parentParentPath, verifiedParent];\n}\n\nasync function verifyPreviousContainerManifest(input: {\n readonly authorizationEvidence?:\n | readonly PrincipalPolicyAuthorization[]\n | undefined;\n readonly bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>;\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly label: string;\n readonly parentPath: readonly VerifiedContainerAccessManifest[];\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly previousManifestHash: string;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly requireAuthorizationEvidence?: boolean | undefined;\n readonly verifiedByHash: Map<string, VerifiedContainerAccessManifest>;\n readonly verifying?: Set<string> | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<VerifiedContainerAccessManifest> {\n const previousBundle = input.bundlesByHash.get(input.previousManifestHash);\n if (!previousBundle) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n `${input.label} previous manifest ${input.previousManifestHash} is missing`,\n );\n }\n const parentPath = await resolveContainerManifestVerificationParentPath({\n ...input,\n bundle: previousBundle,\n });\n\n return verifyContainerManifestBundle({\n authorizationMembership: \"referenced\",\n authorizationEvidence: input.authorizationEvidence,\n bundle: previousBundle,\n bundlesByHash: input.bundlesByHash,\n checkpointContext: input.checkpointContext,\n enforceLocalCheckpoint: false,\n label: `${input.label} previous manifest`,\n parentPath,\n principalPolicyCache: input.principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n requireAuthorizationEvidence: input.requireAuthorizationEvidence,\n verifiedByHash: input.verifiedByHash,\n verifying: input.verifying,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n}\n"]}
|