@tearleads/client-sdk 0.1.58 → 0.1.60
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/Tearleads.d.ts +17 -17
- package/Tearleads.js +15 -15
- package/Tearleads.js.map +1 -1
- package/client/{blobs.d.ts → blobs/index.d.ts} +1 -1
- package/client/{blobs.js → blobs/index.js} +3 -3
- package/client/blobs/index.js.map +1 -0
- package/client/{containerDocumentDiscovery.js → containerContents/documentDiscovery.js} +11 -11
- package/client/containerContents/documentDiscovery.js.map +1 -0
- package/client/{containerContents.d.ts → containerContents/index.d.ts} +13 -13
- package/client/{containerContents.js → containerContents/index.js} +18 -18
- package/client/containerContents/index.js.map +1 -0
- package/client/{containerContentsTypes.d.ts → containerContents/types.d.ts} +14 -14
- package/client/containerContents/types.js +2 -0
- package/client/containerContents/types.js.map +1 -0
- package/client/{deviceFirst.d.ts → deviceFirst/index.d.ts} +7 -7
- package/client/{deviceFirst.js → deviceFirst/index.js} +11 -11
- package/client/deviceFirst/index.js.map +1 -0
- package/client/{reconciledDocumentContentPull.js → deviceFirst/reconciledDocumentContentPull.js} +1 -1
- package/client/deviceFirst/reconciledDocumentContentPull.js.map +1 -0
- package/client/{documents.d.ts → documents/index.d.ts} +5 -5
- package/client/{documents.js → documents/index.js} +5 -5
- package/client/documents/index.js.map +1 -0
- package/client/{identity.d.ts → identity/index.d.ts} +2 -2
- package/client/{identity.js → identity/index.js} +5 -5
- package/client/identity/index.js.map +1 -0
- package/client/{identityKeyPackage.d.ts → identity/keyPackage.d.ts} +1 -1
- package/client/{identityKeyPackage.js → identity/keyPackage.js} +4 -4
- package/client/identity/keyPackage.js.map +1 -0
- package/client/{userIdentities.d.ts → identity/userIdentities.d.ts} +2 -2
- package/client/{userIdentities.js → identity/userIdentities.js} +4 -4
- package/client/identity/userIdentities.js.map +1 -0
- package/client/index.d.ts +18 -18
- package/client/index.js +9 -9
- package/client/index.js.map +1 -1
- package/client/organizations/currentPrincipalMutations.js.map +1 -1
- package/client/organizations/index.d.ts +2 -2
- package/client/organizations/index.js.map +1 -1
- package/client/organizations/organizationAccessRestoration.js.map +1 -1
- package/client/organizations/organizationDataUsage.d.ts +1 -1
- package/client/organizations/organizationDataUsage.js.map +1 -1
- package/client/organizations/organizationGroupNameHydration.js.map +1 -1
- package/client/organizations/organizationGroupPresentation.d.ts +1 -1
- package/client/organizations/organizationGroupPresentation.js.map +1 -1
- package/client/organizations/organizationMetadataProfileSync.js +1 -1
- package/client/organizations/organizationMetadataProfileSync.js.map +1 -1
- package/client/organizations/organizationReadModels.d.ts +1 -1
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/client/organizations/organizationWorkflowRuntime.js.map +1 -1
- package/client/organizations/organizationsTypes.d.ts +1 -1
- package/client/organizations/organizationsTypes.js.map +1 -1
- package/client/organizations/principalContainerMutations.js.map +1 -1
- package/client/organizations/principalMutationRecovery.d.ts +1 -1
- package/client/organizations/principalMutationRecovery.js.map +1 -1
- package/client/organizations/principalMutationScope.js.map +1 -1
- package/client/organizations/principalMutations.d.ts +2 -2
- package/client/organizations/principalMutations.js.map +1 -1
- package/client/root/index.d.ts +1 -1
- package/client/root/index.js.map +1 -1
- package/client/{database.d.ts → runtime/database.d.ts} +1 -1
- package/client/{database.js → runtime/database.js} +1 -1
- package/client/runtime/database.js.map +1 -0
- package/client/{principalHistoryProtection.d.ts → runtime/principalHistoryProtection.d.ts} +1 -1
- package/client/{principalHistoryProtection.js → runtime/principalHistoryProtection.js} +2 -2
- package/client/runtime/principalHistoryProtection.js.map +1 -0
- package/client/{principalMutationApi.d.ts → runtime/principalMutationApi.d.ts} +4 -4
- package/client/{principalMutationApi.js → runtime/principalMutationApi.js} +2 -2
- package/client/runtime/principalMutationApi.js.map +1 -0
- package/client/{principalMutationDispatch.js → runtime/principalMutationDispatch.js} +2 -2
- package/client/runtime/principalMutationDispatch.js.map +1 -0
- package/client/runtime/rootContainerAdoption.js.map +1 -0
- package/client/{workflowRuntime.d.ts → runtime/workflowRuntime.d.ts} +12 -12
- package/client/{workflowRuntime.js → runtime/workflowRuntime.js} +5 -5
- package/client/runtime/workflowRuntime.js.map +1 -0
- package/client/{securityIncidents.d.ts → securityIncidents/index.d.ts} +3 -3
- package/client/{securityIncidents.js → securityIncidents/index.js} +5 -5
- package/client/securityIncidents/index.js.map +1 -0
- package/client/session/index.js +1 -1
- package/client/session/index.js.map +1 -1
- package/client/session/sessionIdentityTrust.d.ts +1 -1
- package/client/session/sessionLoginRefusal.js.map +1 -1
- package/client/session/sessionOrganizationCreation.js.map +1 -1
- package/client/session/sessionPurgeRecovery.js.map +1 -1
- package/client/session/sessionRootAuthority.js.map +1 -1
- package/client/session/sessionTypes.d.ts +3 -3
- package/client/session/sessionTypes.js.map +1 -1
- package/data/blobs/createBlobStore.d.ts +1 -1
- package/data/blobs/createBlobStore.js.map +1 -1
- package/data/blobs/encryptedBlobByteSource.js +1 -1
- package/data/blobs/encryptedBlobByteSource.js.map +1 -1
- package/data/blobs/encryptedBlobEnvelope.d.ts +1 -1
- package/data/blobs/encryptedBlobEnvelope.js +2 -2
- package/data/blobs/encryptedBlobEnvelope.js.map +1 -1
- package/data/blobs/encryptedBlobStore.d.ts +1 -1
- package/data/blobs/encryptedBlobStore.js +1 -1
- package/data/blobs/encryptedBlobStore.js.map +1 -1
- package/data/blobs/memoryBlobStore.d.ts +1 -1
- package/data/blobs/memoryBlobStore.js +1 -1
- package/data/blobs/memoryBlobStore.js.map +1 -1
- package/data/blobs/opfsBlobStore.d.ts +1 -1
- package/data/blobs/opfsBlobStore.js +1 -1
- package/data/blobs/opfsBlobStore.js.map +1 -1
- package/data/containers/containerMetadataDocument.js +1 -1
- package/data/containers/containerMetadataDocument.js.map +1 -1
- package/data/containers/shared/events.js +1 -1
- package/data/containers/shared/events.js.map +1 -1
- package/data/containers/shared/heldContainerHeads.js +1 -1
- package/data/containers/shared/heldContainerHeads.js.map +1 -1
- package/data/containers/shared/mutationAcknowledgement.js +1 -1
- package/data/containers/shared/mutationAcknowledgement.js.map +1 -1
- package/data/containers/shared/principalPolicies.js +1 -1
- package/data/containers/shared/principalPolicies.js.map +1 -1
- package/data/containers/shared/readers.js +2 -2
- package/data/containers/shared/readers.js.map +1 -1
- package/data/documents/attachmentContentIdentity.js +1 -1
- package/data/documents/attachmentContentIdentity.js.map +1 -1
- package/data/documents/blob/shared/blobEnvelopeStream.js.map +1 -1
- package/data/documents/blob/shared/blobSourceSnapshot.d.ts +1 -1
- package/data/documents/blob/shared/blobSourceSnapshot.js.map +1 -1
- package/data/documents/blob/shared/chunkedBlobCrypto.js.map +1 -1
- package/data/documents/blob/shared/encryptedUploadParts.js.map +1 -1
- package/data/documents/blob/shared/events.js +1 -1
- package/data/documents/blob/shared/events.js.map +1 -1
- package/data/documents/blob/shared/types.d.ts +2 -2
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/documents/shared/containerKekPathHistory.js +1 -1
- package/data/documents/shared/containerKekPathHistory.js.map +1 -1
- package/data/documents/shared/containerKekPathVerification.d.ts +1 -1
- package/data/documents/shared/containerKekPathVerification.js +1 -1
- package/data/documents/shared/events.js +1 -1
- package/data/documents/shared/events.js.map +1 -1
- package/data/documents/shared/manifestBundleReaders.js +2 -2
- package/data/documents/shared/manifestBundleReaders.js.map +1 -1
- package/data/documents/shared/projection.d.ts +1 -1
- package/data/documents/shared/projection.js +2 -2
- package/data/documents/shared/projection.js.map +1 -1
- package/data/documents/shared/projectionContentKeys.d.ts +1 -1
- package/data/documents/shared/readers.js +3 -3
- package/data/documents/shared/readers.js.map +1 -1
- package/data/documents/shared/stableDocumentId.js +1 -1
- package/data/documents/shared/stableDocumentId.js.map +1 -1
- package/data/documents/shared/types.d.ts +1 -1
- package/data/documents/shared/types.js +1 -1
- package/data/{keyingCanonicalJson.js → keying/canonicalJson.js} +3 -3
- package/data/keying/canonicalJson.js.map +1 -0
- package/data/keyingProjectionVerification/bundleVerification.js +1 -1
- package/data/keyingProjectionVerification/bundleVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerAncestorCitations.js +1 -1
- package/data/keyingProjectionVerification/containerAncestorCitations.js.map +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js +1 -1
- package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +1 -1
- package/data/keyingProjectionVerification/error.js +1 -1
- package/data/keyingProjectionVerification/error.js.map +1 -1
- package/data/keyingProjectionVerification/index.d.ts +9 -0
- package/data/{keyingProjectionVerification.js → keyingProjectionVerification/index.js} +8 -8
- package/data/keyingProjectionVerification/index.js.map +1 -0
- package/data/keyingProjectionVerification/principalPolicyCache.js +1 -1
- package/data/keyingProjectionVerification/principalPolicyCache.js.map +1 -1
- package/data/keyingProjectionVerification/principalPolicyVerification.js +1 -1
- package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
- package/data/keyingProjectionVerification/readers.d.ts +1 -1
- package/data/keyingProjectionVerification/readers.js +3 -3
- package/data/keyingProjectionVerification/readers.js.map +1 -1
- package/data/keyingProjectionVerification/userKeyResolver.d.ts +1 -1
- package/data/keyingProjectionVerification/userKeyResolver.js.map +1 -1
- package/data/persistence/containers/containerPersistence.js +1 -1
- package/data/persistence/containers/containerPersistence.js.map +1 -1
- package/data/persistence/documents/documentDiscoveryCandidate.js +1 -1
- package/data/persistence/documents/documentDiscoveryCandidate.js.map +1 -1
- package/data/persistence/documents/documentDiscoveryEvidencePersistence.js +1 -1
- package/data/persistence/documents/documentDiscoveryEvidencePersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentProjectionRows.js +1 -1
- package/data/persistence/documents/internal/documentProjectionRows.js.map +1 -1
- package/data/persistence/documents/internal/documentRows.js +1 -1
- package/data/persistence/documents/internal/documentRows.js.map +1 -1
- package/data/persistence/principalPolicyBundleIntegrity.js +1 -1
- package/data/persistence/principalPolicyBundleIntegrity.js.map +1 -1
- package/data/persistence/principalPolicyReferenceCheckpoint.js +1 -1
- package/data/persistence/principalPolicyReferenceCheckpoint.js.map +1 -1
- package/data/persistence/principalPolicyReferenceIndexPersistence.js +1 -1
- package/data/persistence/principalPolicyReferenceIndexPersistence.js.map +1 -1
- package/data/persistence/principalPolicyReferencePersistence.js +1 -1
- package/data/persistence/principalPolicyReferencePersistence.js.map +1 -1
- package/data/persistence/securityIncidentPersistence.js.map +1 -1
- package/data/persistence/verifiedPrincipalPolicyBundle.js +1 -1
- package/data/persistence/verifiedPrincipalPolicyBundle.js.map +1 -1
- package/data/persistence/verifiedPrincipalPolicyCurrent.js +1 -1
- package/data/persistence/verifiedPrincipalPolicyCurrent.js.map +1 -1
- package/data/principals/principalMutationJournal.js +1 -1
- package/data/principals/principalMutationJournal.js.map +1 -1
- package/data/{securityIncidents.d.ts → shared/securityIncidents.d.ts} +1 -1
- package/data/sqlite/documentRecordPersistence.js +1 -1
- package/data/sqlite/documentRecordPersistence.js.map +1 -1
- package/data/sync/crdtPeerSeed.d.ts +18 -0
- package/data/sync/originatedDocuments.d.ts +1 -1
- package/data/sync/originatedDocuments.js.map +1 -1
- package/data/sync/syncCoordinator.d.ts +1 -1
- package/data/sync/syncCoordinator.js.map +1 -1
- package/package.json +1 -1
- package/stores/container-contents/backgroundHydration.js +1 -1
- package/stores/container-contents/backgroundHydration.js.map +1 -1
- package/stores/container-contents/containerContentsStore.d.ts +1 -1
- package/stores/container-contents/containerContentsStore.js.map +1 -1
- package/stores/container-contents/localRefresh.js +1 -1
- package/stores/container-contents/localRefresh.js.map +1 -1
- package/stores/container-contents/remoteContainerIngestion.js +1 -1
- package/stores/container-contents/remoteContainerIngestion.js.map +1 -1
- package/stores/container-contents/remoteWriteQueue.js +1 -1
- package/stores/container-contents/remoteWriteQueue.js.map +1 -1
- package/stores/container-contents/systemContainerHydration.js +1 -1
- package/stores/container-contents/systemContainerHydration.js.map +1 -1
- package/stores/container-contents/utils.js +1 -1
- package/stores/container-contents/utils.js.map +1 -1
- package/stores/documents/documentStore/attachmentIntents.js +1 -1
- package/stores/documents/documentStore/attachmentIntents.js.map +1 -1
- package/stores/documents/documentStore/attachmentSourceUpload.js.map +1 -1
- package/stores/documents/documentStore/attachmentStaging.js +1 -1
- package/stores/documents/documentStore/attachmentStaging.js.map +1 -1
- package/stores/documents/documentStore/attachmentUploadLane.js.map +1 -1
- package/stores/documents/documentStore/persistence.js +2 -2
- package/stores/documents/documentStore/persistence.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/storedDocument.js +1 -1
- package/stores/documents/documentStore/storedDocument.js.map +1 -1
- package/stores/documents/documentStore/syncAttachments.js.map +1 -1
- package/stores/documents/documentStore.d.ts +1 -1
- package/stores/documents/documentStore.js.map +1 -1
- package/stores/documents/registry.d.ts +1 -1
- package/stores/documents/registry.js.map +1 -1
- package/stores/documents/types.d.ts +1 -1
- package/stores/documents/types.js.map +1 -1
- package/stores/local-projection/registry.d.ts +1 -1
- package/stores/local-projection/registry.js.map +1 -1
- package/sync/reconciliation/serviceTypes.d.ts +1 -1
- package/sync/reconciliation/serviceTypes.js.map +1 -1
- package/sync/reconciliation/triggers.d.ts +1 -1
- package/sync/reconciliation/triggers.js.map +1 -1
- package/workflows/blobs/attachmentBindingVerification.js +2 -2
- package/workflows/blobs/attachmentBindingVerification.js.map +1 -1
- package/workflows/blobs/blobChunkDecryption.js.map +1 -1
- package/workflows/blobs/decrypt.d.ts +1 -1
- package/workflows/blobs/decrypt.js +2 -2
- package/workflows/blobs/decrypt.js.map +1 -1
- package/workflows/blobs/detach.js +2 -2
- package/workflows/blobs/detach.js.map +1 -1
- package/workflows/blobs/hydrate.d.ts +3 -3
- package/workflows/blobs/hydrate.js +1 -1
- package/workflows/blobs/hydrate.js.map +1 -1
- package/workflows/blobs/hydrationResults.js.map +1 -1
- package/workflows/blobs/index.d.ts +2 -2
- package/workflows/blobs/index.js +1 -1
- package/workflows/blobs/index.js.map +1 -1
- package/workflows/blobs/multipartFirstParts.js.map +1 -1
- package/workflows/blobs/retainedAttachmentVerification.js +1 -1
- package/workflows/blobs/upload.js +3 -3
- package/workflows/blobs/upload.js.map +1 -1
- package/workflows/container-contents/container-state/createAdoption.js +1 -1
- package/workflows/container-contents/container-state/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/createChild.js +1 -1
- package/workflows/container-contents/container-state/createChild.js.map +1 -1
- package/workflows/container-contents/container-state/createIntentSync.js +1 -1
- package/workflows/container-contents/container-state/createIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/groupGrantVerification.js +1 -1
- package/workflows/container-contents/container-state/moveIntentSync.js +1 -1
- package/workflows/container-contents/container-state/moveIntentSync.js.map +1 -1
- package/workflows/container-contents/container-state/purgeTreeScope.js +1 -1
- package/workflows/container-contents/container-state/purgeTreeScope.js.map +1 -1
- package/workflows/container-contents/container-state/share.js +1 -1
- package/workflows/container-contents/documentDiscoveryInputs.js +1 -1
- package/workflows/container-contents/documentDiscoveryInputs.js.map +1 -1
- package/workflows/container-contents/documentInfo.d.ts +1 -1
- package/workflows/container-contents/documentInfo.js.map +1 -1
- package/workflows/container-contents/documentLinks.d.ts +1 -1
- package/workflows/container-contents/documentLinks.js +1 -1
- package/workflows/container-contents/documentLinks.js.map +1 -1
- package/workflows/container-contents/documentMoveIntentSync.js +1 -1
- package/workflows/container-contents/documentMoveIntentSync.js.map +1 -1
- package/workflows/container-contents/documentPurge.d.ts +1 -1
- package/workflows/container-contents/documentPurge.js +1 -1
- package/workflows/container-contents/documentPurge.js.map +1 -1
- package/workflows/container-contents/documentQueries/rows.js +1 -1
- package/workflows/container-contents/documentQueries/rows.js.map +1 -1
- package/workflows/container-contents/metadata.d.ts +1 -1
- package/workflows/container-contents/metadataMutationPreparation.js +1 -1
- package/workflows/container-contents/metadataMutationPreparation.js.map +1 -1
- package/workflows/container-contents/metadataRemoteSync.d.ts +1 -1
- package/workflows/container-contents/metadataSyncErrors.js.map +1 -1
- package/workflows/container-contents/projectionKeys.d.ts +1 -1
- package/workflows/container-contents/syncLane.d.ts +1 -1
- package/workflows/container-contents/syncLane.js.map +1 -1
- package/workflows/containers/child/carriedDescendantRekeys.js +1 -1
- package/workflows/containers/child/create.d.ts +1 -1
- package/workflows/containers/child/create.js +2 -2
- package/workflows/containers/child/create.js.map +1 -1
- package/workflows/containers/child/createProjection.js +1 -1
- package/workflows/containers/child/createProjection.js.map +1 -1
- package/workflows/containers/child/createSubmission.d.ts +2 -2
- package/workflows/containers/child/createSubmission.js.map +1 -1
- package/workflows/containers/child/move.d.ts +2 -2
- package/workflows/containers/child/move.js +2 -2
- package/workflows/containers/child/move.js.map +1 -1
- package/workflows/containers/child/moveWraps.js +1 -1
- package/workflows/containers/child/mutationRequestCore.js +1 -1
- package/workflows/containers/child/mutationRequestCore.js.map +1 -1
- package/workflows/containers/child/mutationSubmit.js.map +1 -1
- package/workflows/containers/child/recite.js.map +1 -1
- package/workflows/containers/child/recitePlan.js +1 -1
- package/workflows/containers/child/recitePlan.js.map +1 -1
- package/workflows/containers/child/rekey.d.ts +1 -1
- package/workflows/containers/child/rekey.js +2 -2
- package/workflows/containers/child/rekey.js.map +1 -1
- package/workflows/containers/child/rekeyProjection.js +1 -1
- package/workflows/containers/child/rekeyProjection.js.map +1 -1
- package/workflows/containers/child/rekeyRemote.d.ts +2 -2
- package/workflows/containers/child/rekeyRemote.js.map +1 -1
- package/workflows/containers/child/revoke.d.ts +2 -2
- package/workflows/containers/child/revoke.js +2 -2
- package/workflows/containers/child/revoke.js.map +1 -1
- package/workflows/containers/child/rotationPrincipalPolicies.js +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js +1 -1
- package/workflows/containers/child/share.d.ts +2 -2
- package/workflows/containers/child/share.js +1 -1
- package/workflows/containers/child/share.js.map +1 -1
- package/workflows/containers/child/shareAncestorRepair.js.map +1 -1
- package/workflows/containers/child/shareMaterialization.d.ts +1 -1
- package/workflows/containers/child/sharePlanCore.d.ts +1 -1
- package/workflows/containers/child/sharePlanCore.js +1 -1
- package/workflows/containers/root/create.js +1 -1
- package/workflows/containers/root/create.js.map +1 -1
- package/workflows/containers/root/initialGroupPolicy.js +1 -1
- package/workflows/containers/root/initialGroupPolicy.js.map +1 -1
- package/workflows/documents/create.d.ts +1 -1
- package/workflows/documents/create.js +1 -1
- package/workflows/documents/documentMutationPreparation.js +1 -1
- package/workflows/documents/documentMutationPreparation.js.map +1 -1
- package/workflows/documents/historyContent.js +1 -1
- package/workflows/documents/historyContent.js.map +1 -1
- package/workflows/documents/linkSet.js +1 -1
- package/workflows/documents/linkSet.js.map +1 -1
- package/workflows/documents/linkSetAuthority.js +1 -1
- package/workflows/documents/linkSetBlobRewraps.js +2 -2
- package/workflows/documents/linkSetBlobRewraps.js.map +1 -1
- package/workflows/documents/linkSetRemote.d.ts +1 -1
- package/workflows/documents/linkSetRemote.js +1 -1
- package/workflows/documents/orphanBlobReclaims.js +1 -1
- package/workflows/documents/orphanBlobReclaims.js.map +1 -1
- package/workflows/documents/projectionKeys.d.ts +1 -1
- package/workflows/documents/purge.d.ts +1 -1
- package/workflows/documents/purge.js +2 -2
- package/workflows/documents/purge.js.map +1 -1
- package/workflows/documents/readOnlySync.d.ts +1 -1
- package/workflows/documents/readOnlySync.js +1 -1
- package/workflows/documents/readOnlySync.js.map +1 -1
- package/workflows/documents/sync.js +1 -1
- package/workflows/documents/syncContainerRekeyPreparation.js +1 -1
- package/workflows/documents/syncLane.d.ts +1 -1
- package/workflows/documents/syncLane.js.map +1 -1
- package/workflows/documents/syncPlanIdentity.js +1 -1
- package/workflows/documents/syncPlanIdentity.js.map +1 -1
- package/workflows/documents/syncRepairAccess.js +1 -1
- package/workflows/documents/syncSubmittedResult.js +1 -1
- package/workflows/organizations/authoredPrincipalPolicyWarmer.js +1 -1
- package/workflows/organizations/authoredPrincipalPolicyWarmer.js.map +1 -1
- package/workflows/organizations/containerGrantRevocation.d.ts +2 -2
- package/workflows/organizations/containerGrantRevocation.js.map +1 -1
- package/workflows/organizations/createCurrentOrganizationGroup.js.map +1 -1
- package/workflows/organizations/currentOrganizationGroupNames.js.map +1 -1
- package/workflows/organizations/currentPolicyMutationAcknowledgement.js +1 -1
- package/workflows/organizations/currentPolicyMutationAcknowledgement.js.map +1 -1
- package/workflows/organizations/groupCreation.d.ts +1 -1
- package/workflows/organizations/groupCreation.js.map +1 -1
- package/workflows/organizations/groupMetadataAccess.d.ts +1 -1
- package/workflows/organizations/groupMetadataContainerAuthority.js.map +1 -1
- package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
- package/workflows/organizations/groupNameUniqueness.js.map +1 -1
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js +1 -1
- package/workflows/organizations/groupPolicyMutationAcknowledgement.js.map +1 -1
- package/workflows/organizations/groupPolicyRequests.js.map +1 -1
- package/workflows/organizations/loadPolicyHistoryDetails.js.map +1 -1
- package/workflows/organizations/organizationGroupDirectory.js.map +1 -1
- package/workflows/organizations/organizationProfile.js +1 -1
- package/workflows/organizations/organizationProfile.js.map +1 -1
- package/workflows/organizations/policyHistoryCache.js.map +1 -1
- package/workflows/organizations/principalContainerRematerialization.js +1 -1
- package/workflows/organizations/principalContainerRematerializationPlanning.js.map +1 -1
- package/workflows/organizations/principalMutationJournalManagement.js +1 -1
- package/workflows/organizations/principalMutationJournalManagement.js.map +1 -1
- package/workflows/organizations/principalMutationReceipt.js +1 -1
- package/workflows/organizations/principalMutationReceipt.js.map +1 -1
- package/workflows/organizations/principalPolicy.d.ts +1 -1
- package/workflows/organizations/principalPolicy.js.map +1 -1
- package/workflows/organizations/principalPolicyReceiptArtifacts.js +1 -1
- package/workflows/organizations/principalPolicyReceiptArtifacts.js.map +1 -1
- package/workflows/organizations/rosterProfileContainer.js +1 -1
- package/workflows/organizations/rosterProfileContainer.js.map +1 -1
- package/workflows/principals/policyCache.d.ts +1 -1
- package/workflows/principals/policyCache.js +2 -2
- package/workflows/principals/policyCache.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimePolicyWarmer.js +1 -1
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
- package/workflows/registration/persistRegistrationBootstrap.js +1 -1
- package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
- package/workflows/runtimeInput.d.ts +3 -3
- package/workflows/runtimeInput.js.map +1 -1
- package/workflows/sync/index.d.ts +2 -1
- package/workflows/sync/index.js +2 -1
- package/workflows/sync/index.js.map +1 -1
- package/client/blobs.js.map +0 -1
- package/client/containerContents.js.map +0 -1
- package/client/containerContentsTypes.js +0 -2
- package/client/containerContentsTypes.js.map +0 -1
- package/client/containerDocumentDiscovery.js.map +0 -1
- package/client/database.js.map +0 -1
- package/client/deviceFirst.js.map +0 -1
- package/client/documents.js.map +0 -1
- package/client/identity.js.map +0 -1
- package/client/identityKeyPackage.js.map +0 -1
- package/client/principalHistoryProtection.js.map +0 -1
- package/client/principalMutationApi.js.map +0 -1
- package/client/principalMutationDispatch.js.map +0 -1
- package/client/reconciledDocumentContentPull.js.map +0 -1
- package/client/rootContainerAdoption.js.map +0 -1
- package/client/securityIncidents.js.map +0 -1
- package/client/userIdentities.js.map +0 -1
- package/client/workflowRuntime.js.map +0 -1
- package/data/keyingCanonicalJson.js.map +0 -1
- package/data/keyingProjectionVerification.d.ts +0 -9
- package/data/keyingProjectionVerification.js.map +0 -1
- /package/client/{fileSaver.d.ts → host/fileSaver.d.ts} +0 -0
- /package/client/{fileSaver.js → host/fileSaver.js} +0 -0
- /package/client/{fileSaver.js.map → host/fileSaver.js.map} +0 -0
- /package/client/{logger.d.ts → host/logger.d.ts} +0 -0
- /package/client/{logger.js → host/logger.js} +0 -0
- /package/client/{logger.js.map → host/logger.js.map} +0 -0
- /package/client/{apiVersion.d.ts → runtime/apiVersion.d.ts} +0 -0
- /package/client/{apiVersion.js → runtime/apiVersion.js} +0 -0
- /package/client/{apiVersion.js.map → runtime/apiVersion.js.map} +0 -0
- /package/client/{events.d.ts → runtime/events.d.ts} +0 -0
- /package/client/{events.js → runtime/events.js} +0 -0
- /package/client/{events.js.map → runtime/events.js.map} +0 -0
- /package/client/{listenerSet.js → runtime/listenerSet.js} +0 -0
- /package/client/{listenerSet.js.map → runtime/listenerSet.js.map} +0 -0
- /package/client/{network.d.ts → runtime/network.d.ts} +0 -0
- /package/client/{network.js → runtime/network.js} +0 -0
- /package/client/{network.js.map → runtime/network.js.map} +0 -0
- /package/client/{principalMutationDeadline.js → runtime/principalMutationDeadline.js} +0 -0
- /package/client/{principalMutationDeadline.js.map → runtime/principalMutationDeadline.js.map} +0 -0
- /package/client/{rootContainerAdoption.js → runtime/rootContainerAdoption.js} +0 -0
- /package/client/{syncBillingGate.d.ts → runtime/syncBillingGate.d.ts} +0 -0
- /package/client/{syncBillingGate.js → runtime/syncBillingGate.js} +0 -0
- /package/client/{syncBillingGate.js.map → runtime/syncBillingGate.js.map} +0 -0
- /package/data/{blobContracts.d.ts → blobs/blobContracts.d.ts} +0 -0
- /package/data/{blobContracts.js → blobs/blobContracts.js} +0 -0
- /package/data/{blobContracts.js.map → blobs/blobContracts.js.map} +0 -0
- /package/data/{accessLevel.js → keying/accessLevel.js} +0 -0
- /package/data/{accessLevel.js.map → keying/accessLevel.js.map} +0 -0
- /package/data/{stableUuid.js → keying/stableUuid.js} +0 -0
- /package/data/{stableUuid.js.map → keying/stableUuid.js.map} +0 -0
- /package/data/{principalPolicyStates.js → principals/principalPolicyStates.js} +0 -0
- /package/data/{principalPolicyStates.js.map → principals/principalPolicyStates.js.map} +0 -0
- /package/data/{domainScope.d.ts → shared/domainScope.d.ts} +0 -0
- /package/data/{domainScope.js → shared/domainScope.js} +0 -0
- /package/data/{domainScope.js.map → shared/domainScope.js.map} +0 -0
- /package/data/{errorMessage.js → shared/errorMessage.js} +0 -0
- /package/data/{errorMessage.js.map → shared/errorMessage.js.map} +0 -0
- /package/data/{recordReaders.d.ts → shared/recordReaders.d.ts} +0 -0
- /package/data/{recordReaders.js → shared/recordReaders.js} +0 -0
- /package/data/{recordReaders.js.map → shared/recordReaders.js.map} +0 -0
- /package/data/{securityIncidents.js → shared/securityIncidents.js} +0 -0
- /package/data/{securityIncidents.js.map → shared/securityIncidents.js.map} +0 -0
- /package/data/{crdtPeerSeed.js → sync/crdtPeerSeed.js} +0 -0
- /package/data/{crdtPeerSeed.js.map → sync/crdtPeerSeed.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["events.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,+BAA+B,EAC/B,0BAA0B,EAC1B,mCAAmC,EACnC,sBAAsB,EACtB,eAAe,EACf,eAAe,GAGhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["events.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessEvent,\n type AttachmentBindAccessEventBody,\n type AttachmentDetachAccessEventBody,\n CONTENT_RECORD_ENCRYPTION_SUITE,\n computeAccessEventBodyHash,\n computeContentRecordNonceDomainHash,\n computeWriteHeaderHash,\n signAccessEvent,\n signWriteHeader,\n type UnsignedAccessEvent,\n type WriteHeader,\n} from \"@tearleads/crypto\";\nimport type { ContainerManifestRef } from \"@tearleads/validators/request\";\nimport { readCanonicalJson } from \"../../../keying/canonicalJson\";\nimport { uniqueSortedStrings } from \"../../shared/readers\";\nimport type { DocumentCreateAuthor } from \"../../shared/types\";\nimport type { BlobEncryptionPlan, DocumentManifestIdentity } from \"./types\";\n\nasync function signBlobAttachmentBodyEvent<\n Body extends AttachmentBindAccessEventBody | AttachmentDetachAccessEventBody,\n>(\n body: Body,\n input: {\n author: DocumentCreateAuthor;\n blobId: string;\n eventId: string;\n manifestIdentity: DocumentManifestIdentity;\n signedAt: string;\n authorizingContainerPathRefs: readonly (readonly ContainerManifestRef[])[];\n },\n): Promise<{ body: Body; event: AccessEvent }> {\n const bodyLabel =\n body.eventType === \"attachment.bind\"\n ? \"Blob attachment bind body\"\n : \"Blob attachment detach body\";\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId,\n eventType: body.eventType,\n objectKind: \"blob\",\n objectId: input.blobId,\n organizationId: input.manifestIdentity.organizationId,\n previousManifestHash: null,\n dependencyManifestHashes: uniqueSortedStrings([\n input.manifestIdentity.manifestHash,\n ...input.authorizingContainerPathRefs.flatMap((path) =>\n path.map((ref) => ref.manifestHash),\n ),\n ]),\n bodyHash: await computeAccessEventBodyHash(\n readCanonicalJson(body, bodyLabel),\n ),\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt,\n };\n\n return {\n body,\n event: await signAccessEvent(unsignedEvent, input.author.signerPrivateKey),\n };\n}\n\nexport async function signBlobAttachmentEvent(input: {\n author: DocumentCreateAuthor;\n bindingId: string;\n blobId: string;\n documentId: string;\n eventId: string;\n expectedBindingId: string | null;\n manifestIdentity: DocumentManifestIdentity;\n signedAt: string;\n slotId: string;\n authorizingContainerPathRefs: readonly (readonly ContainerManifestRef[])[];\n}): Promise<{ body: AttachmentBindAccessEventBody; event: AccessEvent }> {\n return signBlobAttachmentBodyEvent(\n {\n eventType: \"attachment.bind\",\n bindingId: input.bindingId,\n blobId: input.blobId,\n documentId: input.documentId,\n slotId: input.slotId,\n expectedBindingId: input.expectedBindingId,\n documentManifestHash: input.manifestIdentity.manifestHash,\n },\n input,\n );\n}\n\nexport async function signBlobAttachmentDetachEvent(input: {\n author: DocumentCreateAuthor;\n bindingId: string;\n blobId: string;\n documentId: string;\n eventId: string;\n manifestIdentity: DocumentManifestIdentity;\n signedAt: string;\n slotId: string;\n authorizingContainerPathRefs: readonly (readonly ContainerManifestRef[])[];\n}): Promise<{ body: AttachmentDetachAccessEventBody; event: AccessEvent }> {\n return signBlobAttachmentBodyEvent(\n {\n eventType: \"attachment.detach\",\n bindingId: input.bindingId,\n blobId: input.blobId,\n documentId: input.documentId,\n slotId: input.slotId,\n documentManifestHash: input.manifestIdentity.manifestHash,\n },\n input,\n );\n}\n\nexport async function signBlobAttachmentWriteHeader(input: {\n authorizingContainerPathRefs: readonly (readonly ContainerManifestRef[])[];\n author: DocumentCreateAuthor;\n blobAccessManifestHash: string;\n blobId: string;\n contentKeyEpoch: number;\n encrypted: BlobEncryptionPlan;\n manifestIdentity: DocumentManifestIdentity;\n signedAt: string;\n targetHash: string;\n}): Promise<{ writeHeader: WriteHeader; writeHeaderHash: string }> {\n const writeHeader = await signWriteHeader(\n {\n version: 1,\n dependencyManifestHashes: uniqueSortedStrings(\n input.authorizingContainerPathRefs.flatMap((path) =>\n path.map((ref) => ref.manifestHash),\n ),\n ),\n organizationId: input.manifestIdentity.organizationId,\n objectKind: \"blob\",\n objectId: input.blobId,\n accessManifestHash: input.blobAccessManifestHash,\n contentKeyEpoch: input.contentKeyEpoch,\n targetHash: input.targetHash,\n encryptionSuite: CONTENT_RECORD_ENCRYPTION_SUITE,\n contentRecordId: input.blobId,\n nonceDomainHash: await computeContentRecordNonceDomainHash({\n version: 1,\n organizationId: input.manifestIdentity.organizationId,\n objectKind: \"blob\",\n objectId: input.blobId,\n contentKeyEpoch: input.contentKeyEpoch,\n encryptionSuite: CONTENT_RECORD_ENCRYPTION_SUITE,\n contentRecordId: input.blobId,\n }),\n metadataHash: input.encrypted.metadataHash,\n ciphertextHash: input.encrypted.sha256,\n writerUserId: input.author.signerUserId,\n writerDeviceId: input.author.signerDeviceId,\n writerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt,\n },\n input.author.signerPrivateKey,\n );\n\n return {\n writeHeader,\n writeHeaderHash: await computeWriteHeaderHash(writeHeader),\n };\n}\n"]}
|
|
@@ -2,8 +2,8 @@ import type { RequestFailureKind, RequestResultOptions, UploadMultipartBlobPartB
|
|
|
2
2
|
import type { BlobContentKeyTarget, BlobEnvelopeHeaderRecord, BlobEnvelopeRecord, WriteHeader } from "../../../../internal/crypto/index.js";
|
|
3
3
|
import type { BlobAttachmentBindRequest, BlobAttachmentDetachRequest, BlobContentKeyBundleRequest, InitiateMultipartBlobStageRequest } from "../../../../internal/validators/request/index.js";
|
|
4
4
|
import type { BlobAttachmentBindResponse, BlobAttachmentDetachResponse, BlobAttachmentSummary, DocumentWriterProjectionResponse, InitiateMultipartBlobStageResponse, MultipartBlobStageStatusResponse, UploadMultipartBlobPartResponse } from "../../../../internal/validators/response/index.js";
|
|
5
|
-
import type { BlobByteSourceInput, BlobBytes } from "../../../blobContracts.js";
|
|
6
|
-
import type { ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer } from "../../../keyingProjectionVerification.js";
|
|
5
|
+
import type { BlobByteSourceInput, BlobBytes } from "../../../blobs/blobContracts.js";
|
|
6
|
+
import type { ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer } from "../../../keyingProjectionVerification/index.js";
|
|
7
7
|
import type { ExecSql } from "../../../sqlite/sqlSchema.js";
|
|
8
8
|
import type { DocumentCreateAuthor } from "../../shared/types.js";
|
|
9
9
|
export declare const BLOB_CONTENT_RECORD_KEY_INFO_DOMAIN = "tearleads.blob.content-record-key-info";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAqCA,MAAM,CAAC,MAAM,mCAAmC,GAC9C,wCAAwC,CAAC;AAC3C,MAAM,CAAC,MAAM,8BAA8B,GACzC,mCAAmC,CAAC;AACtC,MAAM,CAAC,MAAM,gCAAgC,GAC3C,qCAAqC,CAAC;AACxC,MAAM,CAAC,MAAM,6BAA6B,GACxC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,yCAAyC,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC","sourcesContent":["import type {\n RequestFailureKind,\n RequestResultOptions,\n UploadMultipartBlobPartBytesRequest,\n} from \"@tearleads/api-client\";\nimport type {\n BlobContentKeyTarget,\n BlobEnvelopeHeaderRecord,\n BlobEnvelopeRecord,\n WriteHeader,\n} from \"@tearleads/crypto\";\nimport type {\n BlobAttachmentBindRequest,\n BlobAttachmentDetachRequest,\n BlobContentKeyBundleRequest,\n InitiateMultipartBlobStageRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n BlobAttachmentBindResponse,\n BlobAttachmentDetachResponse,\n BlobAttachmentSummary,\n DocumentWriterProjectionResponse,\n InitiateMultipartBlobStageResponse,\n MultipartBlobStageStatusResponse,\n UploadMultipartBlobPartResponse,\n} from \"@tearleads/validators/response\";\nimport type {\n BlobByteSourceInput,\n BlobBytes,\n} from \"../../../blobs/blobContracts\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../../keyingProjectionVerification\";\nimport type { ExecSql } from \"../../../sqlite/sqlSchema\";\nimport type { DocumentCreateAuthor } from \"../../shared/types\";\n\nexport const BLOB_CONTENT_RECORD_KEY_INFO_DOMAIN =\n \"tearleads.blob.content-record-key-info\";\nexport const BLOB_CONTENT_RECORD_AAD_DOMAIN =\n \"tearleads.blob.content-record-aad\";\nexport const BLOB_CONTENT_RECORD_NONCE_DOMAIN =\n \"tearleads.blob.content-record-nonce\";\nexport const BLOB_CONTENT_RECORD_HKDF_SALT: Uint8Array<ArrayBuffer> =\n new TextEncoder().encode(\"tearleads.blob.content-record-hkdf-salt\");\nexport const TEXT_ENCODER = new TextEncoder();\n\nexport interface BlobAttachmentRequestOptions {\n readonly expectedPaymentRequiredOrganizationId?: string | undefined;\n}\n\nexport interface BlobAttachmentApi {\n bindBlobAttachment(\n blobId: string,\n input: BlobAttachmentBindRequest,\n options?: BlobAttachmentRequestOptions,\n ): Promise<BlobAttachmentBindResponse | null>;\n clearWriterProjectionCaches?(): void;\n evictDocumentWriterProjection?(documentId: string): void;\n getRequestFailure?(input: {\n method: \"DELETE\" | \"GET\" | \"POST\" | \"PUT\";\n path: string;\n }): {\n readonly code?: string | undefined;\n readonly kind: RequestFailureKind;\n readonly message: string;\n readonly status: number | null;\n } | null;\n getDocumentWriterProjection(\n documentId: string,\n ): Promise<DocumentWriterProjectionResponse | null>;\n getMultipartBlobStage(\n stageId: string,\n ): Promise<MultipartBlobStageStatusResponse | null>;\n initiateMultipartBlobStage(\n input: InitiateMultipartBlobStageRequest,\n ): Promise<InitiateMultipartBlobStageResponse | null>;\n uploadMultipartBlobPartBytes(\n stageId: string,\n partNumber: number,\n input: UploadMultipartBlobPartBytesRequest,\n options?: RequestResultOptions,\n ): Promise<UploadMultipartBlobPartResponse | null>;\n}\n\nexport interface BlobAttachmentDetachApi {\n detachBlobAttachment(\n blobId: string,\n bindingId: string,\n input: BlobAttachmentDetachRequest,\n options?: BlobAttachmentRequestOptions,\n ): Promise<BlobAttachmentDetachResponse | null>;\n getDocumentWriterProjection(\n documentId: string,\n ): Promise<DocumentWriterProjectionResponse | null>;\n}\n\nexport type { BlobContentKeyTarget };\n\n/**\n * Aliases of the crypto parser's own types. The parser is shared with the API,\n * so restating these shapes here would let the two drift apart silently.\n */\nexport type BlobEncryptedBytesRecord = BlobEnvelopeRecord;\n\n/**\n * The envelope as the header establishes it. Streaming readers hold this\n * before any ciphertext is read, so it has no `chunks`: an empty array there\n * would read as an empty object rather than an unread one.\n */\nexport type BlobEncryptedBytesHeader = BlobEnvelopeHeaderRecord;\n\nexport type BlobEncryptedChunk = BlobEnvelopeRecord[\"chunks\"][number];\n\nexport interface BlobSourceSnapshot {\n readonly byteLength: number;\n readonly chunkSha256: readonly string[];\n readonly chunkSize: number;\n readonly sha256: string;\n}\n\nexport interface BlobEncryptionPlan {\n readonly byteLength: number;\n readonly chunkSize: number;\n readonly metadataHash: string;\n readonly partCount: number;\n readonly plaintextByteLength: number;\n readonly plaintextSha256: string;\n readonly sha256: string;\n encryptPart(index: number): Promise<BlobBytes>;\n getPartByteLength(index: number): number;\n}\n\nexport interface DocumentManifestIdentity {\n documentId: string;\n manifestHash: string;\n organizationId: string;\n}\n\nexport interface BlobAttachmentMaterial {\n blobAccessManifestHash: string;\n contentKeyBundle: BlobContentKeyBundleRequest;\n encrypted: BlobEncryptionPlan;\n manifestIdentity: DocumentManifestIdentity;\n targetHash: string;\n targets: BlobContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n}\n\n/**\n * Progress for an in-flight multipart blob upload.\n */\nexport interface MultipartUploadProgress {\n readonly bytesTotal: number;\n readonly bytesUploaded: number;\n readonly partsCompleted: number;\n readonly partsTotal: number;\n}\n\nexport type MultipartUploadProgressListener = (\n progress: MultipartUploadProgress,\n) => void;\n\n/**\n * Fires once a multipart stage has been opened (or resumed), with its id and\n * plaintext chunk size. Callers persist both so a later attempt can reproduce\n * the same encrypted parts and resume instead of orphaning the partial upload.\n */\nexport type MultipartStageResolvedListener = (input: {\n readonly partSize: number;\n readonly stageId: string;\n}) => void | Promise<void>;\n\nexport interface UploadDocumentAttachmentInput {\n apiClient: BlobAttachmentApi;\n author: DocumentCreateAuthor;\n blobId?: string | undefined;\n bindingId?: string | undefined;\n bytes: BlobByteSourceInput;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedBindingId: string | null;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n // A persisted nonce seed. The plaintext digest derives the envelope IV from\n // it, then each chunk derives a unique IV. Same-source retries reproduce the\n // encrypted parts; changed bytes cannot reuse their AES-GCM nonces.\n nonceSeed?: Uint8Array | undefined;\n multipart?: MultipartBlobUploadOptions | undefined;\n onMultipartProgress?: MultipartUploadProgressListener | undefined;\n onStageResolved?: MultipartStageResolvedListener | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n slotId: string;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n writerProjection?: DocumentWriterProjectionResponse | undefined;\n}\n\nexport interface MultipartBlobUploadOptions {\n /** Exactly 5 MiB per plaintext encryption chunk; transport parts include envelope overhead. */\n readonly partSize: number;\n // The id of a previously opened stage to resume. When set, the upload refetches\n // that stage and skips parts the server already has instead of opening a new\n // one; if the stage is gone (expired), it falls back to a fresh stage.\n readonly resumeStageId?: string | undefined;\n readonly uploadConcurrency?: number | undefined;\n}\n\nexport interface UploadDocumentAttachmentResult {\n blobId: string;\n bindingId: string;\n request: BlobAttachmentBindRequest;\n response: BlobAttachmentBindResponse;\n sha256: string;\n byteLength: number;\n writeHeader: WriteHeader;\n writeHeaderHash: string;\n writerProjection: DocumentWriterProjectionResponse;\n}\n\nexport interface DetachDocumentAttachmentInput {\n apiClient: BlobAttachmentDetachApi;\n author: DocumentCreateAuthor;\n bindingId: string;\n blobId: string;\n documentId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n slotId: string;\n stillCurrent?: (() => boolean) | undefined;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n writerProjection?: DocumentWriterProjectionResponse | undefined;\n}\n\nexport interface DetachDocumentAttachmentResult {\n request: BlobAttachmentDetachRequest;\n response: BlobAttachmentDetachResponse;\n writerProjection: DocumentWriterProjectionResponse;\n}\n\nexport interface DecryptDocumentAttachmentBlobInput {\n binding: BlobAttachmentSummary;\n encryptedBytes: BlobBytes;\n expectedDocumentId: string;\n expectedSlotId: string;\n execSql: ExecSql;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n targetSecretKey: Uint8Array;\n stillCurrent?: (() => boolean) | undefined;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n writerProjection: DocumentWriterProjectionResponse;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computeContainerKekKeyringHash, computeContainerKekMaterialId, isContainerKekMaterialId, KeyingVerificationError, normalizeContainerAccessEventBody, normalizeContainerKekKeyring, openContainerKekKeyring, } from "../../../internal/crypto/index.js";
|
|
2
|
-
import { readCanonicalJson, readCanonicalRecord, } from "../../
|
|
2
|
+
import { readCanonicalJson, readCanonicalRecord, } from "../../keying/canonicalJson.js";
|
|
3
3
|
import { readContainerKeyEpoch } from "../../keyingProjectionVerification/readers.js";
|
|
4
4
|
import { verifyContainerKekEntries } from "./containerKekEntryVerification.js";
|
|
5
5
|
import { readManifestContainerId } from "./readers.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerKekPathHistory.js","sourceRoot":"","sources":["containerKekPathHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeContainerKekKeyringHash,\n computeContainerKekMaterialId,\n isContainerKekMaterialId,\n KeyingVerificationError,\n normalizeContainerAccessEventBody,\n normalizeContainerKekKeyring,\n openContainerKekKeyring,\n type VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../keyingCanonicalJson\";\nimport { readContainerKeyEpoch } from \"../../keyingProjectionVerification/readers\";\nimport { verifyContainerKekEntries } from \"./containerKekEntryVerification\";\nimport { readManifestContainerId } from \"./readers\";\nimport type { UnwrappedContainerKek } from \"./types\";\n\ntype ProjectionKek = ContainerWriterProjectionResponse[\"containerKeks\"][number];\ntype VerifiedManifests = ReadonlyMap<string, VerifiedContainerAccessManifest>;\n\n/** The projection proves a predecessor existed, but no retained keyring can recover it. */\nexport class ContainerKekHistoryUnavailableError extends Error {\n constructor(label: string) {\n super(`${label} keyring is missing`);\n this.name = \"ContainerKekHistoryUnavailableError\";\n }\n}\n\nexport function projectionKekLabel(index: number): string {\n return `Container writer projection KEK[${index}]`;\n}\n\nexport async function assertUnwrappedContainerKekMatchesMaterialId(input: {\n label: string;\n keyMaterial: Uint8Array;\n kek: Pick<\n ProjectionKek,\n \"containerId\" | \"containerKeyEpoch\" | \"containerKeyEpochId\"\n >;\n}): Promise<void> {\n if (!isContainerKekMaterialId(input.kek.containerKeyEpochId)) {\n throw new Error(\n `${input.label} KEK epoch id does not commit to key material`,\n );\n }\n const expectedId = await computeContainerKekMaterialId({\n containerId: input.kek.containerId,\n keyEpoch: input.kek.containerKeyEpoch,\n keyMaterial: input.keyMaterial,\n });\n if (expectedId !== input.kek.containerKeyEpochId) {\n throw new Error(\n `${input.label} KEK material does not match committed epoch id`,\n );\n }\n}\n\nfunction sameContainerManifestHistory(kek: ProjectionKek) {\n return kek.containerManifestHistory.filter(\n (bundle) => readManifestContainerId(bundle) === kek.containerId,\n );\n}\n\n/**\n * Proves the served keyring is the one the rotation that minted the current\n * epoch committed to in its signed event body.\n */\nasync function assertKeyringCommitment(input: {\n currentManifest: ContainerWriterProjectionResponse[\"path\"][number];\n index: number;\n kek: ProjectionKek;\n keyring: ReturnType<typeof normalizeContainerKekKeyring>;\n}): Promise<void> {\n const rotationManifestHash = readContainerKeyEpoch(\n input.kek.keyEpoch,\n `${projectionKekLabel(input.index)} key epoch`,\n ).accessManifestHash;\n const rotationManifest =\n rotationManifestHash === input.currentManifest.manifestHash\n ? input.currentManifest\n : sameContainerManifestHistory(input.kek).find(\n (bundle) => bundle.manifestHash === rotationManifestHash,\n );\n if (!rotationManifest) {\n throw new Error(\n `${projectionKekLabel(input.index)} keyring signer is missing`,\n );\n }\n const eventBundle = readCanonicalRecord(\n rotationManifest.event,\n `${projectionKekLabel(input.index)} keyring event`,\n );\n const eventBody = normalizeContainerAccessEventBody(\n readCanonicalJson(\n Reflect.get(eventBundle, \"body\"),\n `${projectionKekLabel(input.index)} keyring event body`,\n ),\n );\n if (\n (eventBody.eventType !== \"container.move\" &&\n eventBody.eventType !== \"container.rekey\" &&\n eventBody.eventType !== \"container.revoke\") ||\n eventBody.keyringHash !==\n (await computeContainerKekKeyringHash(input.keyring))\n ) {\n throw new Error(\n `${projectionKekLabel(input.index)} keyring does not match its signed event`,\n );\n }\n}\n\nasync function openVerifiedKeyringEntries(input: {\n currentManifest: ContainerWriterProjectionResponse[\"path\"][number];\n index: number;\n kek: ProjectionKek;\n successorKeyMaterial: Uint8Array;\n verifiedByHash: VerifiedManifests;\n verifyKeyringCommitment: boolean;\n}): Promise<Awaited<ReturnType<typeof openContainerKekKeyring>>> {\n const { kek } = input;\n const keyring = normalizeContainerKekKeyring(kek.keyring);\n if (\n keyring.containerId !== kek.containerId ||\n keyring.containerKeyEpochId !== kek.containerKeyEpochId\n ) {\n throw new Error(\n `${projectionKekLabel(input.index)} keyring is inconsistent`,\n );\n }\n if (input.verifyKeyringCommitment) {\n await assertKeyringCommitment({\n currentManifest: input.currentManifest,\n index: input.index,\n kek,\n keyring,\n });\n }\n\n let entries: Awaited<ReturnType<typeof openContainerKekKeyring>>;\n try {\n entries = await openContainerKekKeyring({\n keyEpoch: kek.containerKeyEpoch,\n keyring,\n successorContainerKey: input.successorKeyMaterial,\n });\n } catch (error) {\n if (error instanceof KeyingVerificationError) {\n throw error;\n }\n // Label opaque AEAD failures; structural verification errors already\n // carry their own diagnosis.\n throw new Error(\n `${projectionKekLabel(input.index)} keyring could not be opened`,\n { cause: error },\n );\n }\n // Per-entry material-id verification proves an entry's key matches the id\n // it declares, but a poisoned keyring can declare a self-consistent FAKE\n // id — fresh key, matching commitment — for an epoch the container never\n // had. Anchor every entry the projection can name to the epoch id its\n // signed history actually committed; anything else is a forged epoch.\n await verifyContainerKekEntries(kek.containerId, entries);\n\n // Every epoch id the signed manifest history names must be present in the\n // keyring. A forged entry can be self-consistent, but it cannot also make\n // the real epoch id — which a signed state already named — disappear.\n const entryEpochIds = new Set(\n entries.map((entry) => entry.containerKeyEpochId),\n );\n const signedEpochIds = signedHistoryEpochIds({\n headManifestHash: input.currentManifest.manifestHash,\n kek,\n verifiedByHash: input.verifiedByHash,\n });\n for (const historicalEpochId of signedEpochIds) {\n if (!entryEpochIds.has(historicalEpochId)) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n `${projectionKekLabel(input.index)} keyring omits an epoch its manifest history commits to`,\n );\n }\n }\n return entries;\n}\n\n/**\n * Epoch ids named by verified historical manifest states for this container.\n * Those states are signed, so an id they name is an epoch the container\n * provably had — and a keyring that omits it in favor of a forged id for the\n * same position is detectable even when no epoch RECORD was shipped.\n */\nexport function manifestHistoryEpochIds(kek: ProjectionKek): Set<string> {\n const epochIds = new Set<string>();\n for (const bundle of sameContainerManifestHistory(kek)) {\n const state = readCanonicalRecord(\n bundle.state,\n \"Container writer projection historical manifest state\",\n );\n const containerKeyEpochId = Reflect.get(state, \"containerKeyEpochId\");\n if (\n typeof containerKeyEpochId === \"string\" &&\n containerKeyEpochId !== kek.containerKeyEpochId\n ) {\n epochIds.add(containerKeyEpochId);\n }\n }\n return epochIds;\n}\n\n/**\n * The epoch ids this KEK's own history names, plus every one its head's\n * verified lineage names wherever the projection served it. Verification pools\n * every KEK's history, so a server can serve a container's older manifests\n * under another KEK; walking the lineage keeps a forged keyring id from passing\n * because the real id it displaces moved (#2365 finding 32). The walk stops at\n * the first manifest verification did not record, so it only ever adds ids.\n */\nexport function signedHistoryEpochIds(input: {\n readonly headManifestHash: string;\n readonly kek: ProjectionKek;\n readonly verifiedByHash: VerifiedManifests;\n}): Set<string> {\n const epochIds = manifestHistoryEpochIds(input.kek);\n const visited = new Set<string>();\n let current = input.verifiedByHash.get(input.headManifestHash);\n while (\n current &&\n current.state.containerId === input.kek.containerId &&\n !visited.has(current.manifestHash)\n ) {\n visited.add(current.manifestHash);\n const epochId = current.state.containerKeyEpochId;\n if (epochId !== null && epochId !== input.kek.containerKeyEpochId) {\n epochIds.add(epochId);\n }\n const previousHash = current.state.previousManifestHash;\n current =\n previousHash === null\n ? undefined\n : input.verifiedByHash.get(previousHash);\n }\n return epochIds;\n}\n\nfunction admitKeyringEntry(input: {\n entry: Awaited<ReturnType<typeof openContainerKekKeyring>>[number];\n index: number;\n kek: ProjectionKek;\n keksByEpochId: Map<string, UnwrappedContainerKek>;\n}): void {\n const { entry, kek } = input;\n const cached = input.keksByEpochId.get(entry.containerKeyEpochId);\n if (cached) {\n if (cached.containerId !== kek.containerId) {\n throw new Error(\n `${projectionKekLabel(input.index)} cached historical KEK is inconsistent`,\n );\n }\n return;\n }\n input.keksByEpochId.set(entry.containerKeyEpochId, {\n containerId: kek.containerId,\n // A keyring entry is key material plus the epoch id that commits to it —\n // there is no epoch record, so no fingerprint. Selection falls back to the\n // epoch id and AEAD authenticates; the commitment check above is what\n // makes the material itself trustworthy.\n keyEpochHash: null,\n keyMaterial: entry.keyMaterial,\n });\n}\n\n/**\n * Opens the sealed keyring for one path index and admits every entry into\n * `keksByEpochId` after verifying it against the material-id commitment its\n * ordinal position implies (entry i is key epoch i + 1). No chain walk:\n * one decrypt yields the container's complete retained history, and entry\n * verification is independent per entry.\n */\nexport async function unwrapKeyringContainerKeksAtIndex(input: {\n currentManifest: ContainerWriterProjectionResponse[\"path\"][number];\n index: number;\n kek: ProjectionKek;\n keksByEpochId: Map<string, UnwrappedContainerKek>;\n successorKeyMaterial: Uint8Array | null;\n /** Every manifest projection verification recorded; anchors the keyring. */\n verifiedByHash: VerifiedManifests;\n verifyKeyringCommitment: boolean;\n}): Promise<void> {\n const { kek, successorKeyMaterial } = input;\n if (!successorKeyMaterial) {\n return;\n }\n\n if (kek.keyring === null) {\n if (kek.containerKeyEpoch !== 1) {\n throw new ContainerKekHistoryUnavailableError(\n projectionKekLabel(input.index),\n );\n }\n return;\n }\n\n const entries = await openVerifiedKeyringEntries({\n currentManifest: input.currentManifest,\n index: input.index,\n kek,\n successorKeyMaterial,\n verifiedByHash: input.verifiedByHash,\n verifyKeyringCommitment: input.verifyKeyringCommitment,\n });\n for (const entry of entries) {\n admitKeyringEntry({\n entry,\n index: input.index,\n kek,\n keksByEpochId: input.keksByEpochId,\n });\n }\n}\n\n/**\n * Epoch ids this projection implies exist but that were not recovered —\n * used to attribute history failures to the material they orphan.\n */\nexport function projectedUnreachablePredecessorEpochIds(input: {\n kek: ProjectionKek;\n keksByEpochId: ReadonlyMap<string, UnwrappedContainerKek>;\n}): string[] {\n const projectedEpochIds = new Set<string>();\n for (const bundle of sameContainerManifestHistory(input.kek)) {\n const state = readCanonicalRecord(\n bundle.state,\n \"Container writer projection historical manifest state\",\n );\n const containerKeyEpochId = Reflect.get(state, \"containerKeyEpochId\");\n if (typeof containerKeyEpochId === \"string\") {\n projectedEpochIds.add(containerKeyEpochId);\n }\n }\n projectedEpochIds.delete(input.kek.containerKeyEpochId);\n return [...projectedEpochIds].filter(\n (containerKeyEpochId) => !input.keksByEpochId.has(containerKeyEpochId),\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"containerKekPathHistory.js","sourceRoot":"","sources":["containerKekPathHistory.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeContainerKekKeyringHash,\n computeContainerKekMaterialId,\n isContainerKekMaterialId,\n KeyingVerificationError,\n normalizeContainerAccessEventBody,\n normalizeContainerKekKeyring,\n openContainerKekKeyring,\n type VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../keying/canonicalJson\";\nimport { readContainerKeyEpoch } from \"../../keyingProjectionVerification/readers\";\nimport { verifyContainerKekEntries } from \"./containerKekEntryVerification\";\nimport { readManifestContainerId } from \"./readers\";\nimport type { UnwrappedContainerKek } from \"./types\";\n\ntype ProjectionKek = ContainerWriterProjectionResponse[\"containerKeks\"][number];\ntype VerifiedManifests = ReadonlyMap<string, VerifiedContainerAccessManifest>;\n\n/** The projection proves a predecessor existed, but no retained keyring can recover it. */\nexport class ContainerKekHistoryUnavailableError extends Error {\n constructor(label: string) {\n super(`${label} keyring is missing`);\n this.name = \"ContainerKekHistoryUnavailableError\";\n }\n}\n\nexport function projectionKekLabel(index: number): string {\n return `Container writer projection KEK[${index}]`;\n}\n\nexport async function assertUnwrappedContainerKekMatchesMaterialId(input: {\n label: string;\n keyMaterial: Uint8Array;\n kek: Pick<\n ProjectionKek,\n \"containerId\" | \"containerKeyEpoch\" | \"containerKeyEpochId\"\n >;\n}): Promise<void> {\n if (!isContainerKekMaterialId(input.kek.containerKeyEpochId)) {\n throw new Error(\n `${input.label} KEK epoch id does not commit to key material`,\n );\n }\n const expectedId = await computeContainerKekMaterialId({\n containerId: input.kek.containerId,\n keyEpoch: input.kek.containerKeyEpoch,\n keyMaterial: input.keyMaterial,\n });\n if (expectedId !== input.kek.containerKeyEpochId) {\n throw new Error(\n `${input.label} KEK material does not match committed epoch id`,\n );\n }\n}\n\nfunction sameContainerManifestHistory(kek: ProjectionKek) {\n return kek.containerManifestHistory.filter(\n (bundle) => readManifestContainerId(bundle) === kek.containerId,\n );\n}\n\n/**\n * Proves the served keyring is the one the rotation that minted the current\n * epoch committed to in its signed event body.\n */\nasync function assertKeyringCommitment(input: {\n currentManifest: ContainerWriterProjectionResponse[\"path\"][number];\n index: number;\n kek: ProjectionKek;\n keyring: ReturnType<typeof normalizeContainerKekKeyring>;\n}): Promise<void> {\n const rotationManifestHash = readContainerKeyEpoch(\n input.kek.keyEpoch,\n `${projectionKekLabel(input.index)} key epoch`,\n ).accessManifestHash;\n const rotationManifest =\n rotationManifestHash === input.currentManifest.manifestHash\n ? input.currentManifest\n : sameContainerManifestHistory(input.kek).find(\n (bundle) => bundle.manifestHash === rotationManifestHash,\n );\n if (!rotationManifest) {\n throw new Error(\n `${projectionKekLabel(input.index)} keyring signer is missing`,\n );\n }\n const eventBundle = readCanonicalRecord(\n rotationManifest.event,\n `${projectionKekLabel(input.index)} keyring event`,\n );\n const eventBody = normalizeContainerAccessEventBody(\n readCanonicalJson(\n Reflect.get(eventBundle, \"body\"),\n `${projectionKekLabel(input.index)} keyring event body`,\n ),\n );\n if (\n (eventBody.eventType !== \"container.move\" &&\n eventBody.eventType !== \"container.rekey\" &&\n eventBody.eventType !== \"container.revoke\") ||\n eventBody.keyringHash !==\n (await computeContainerKekKeyringHash(input.keyring))\n ) {\n throw new Error(\n `${projectionKekLabel(input.index)} keyring does not match its signed event`,\n );\n }\n}\n\nasync function openVerifiedKeyringEntries(input: {\n currentManifest: ContainerWriterProjectionResponse[\"path\"][number];\n index: number;\n kek: ProjectionKek;\n successorKeyMaterial: Uint8Array;\n verifiedByHash: VerifiedManifests;\n verifyKeyringCommitment: boolean;\n}): Promise<Awaited<ReturnType<typeof openContainerKekKeyring>>> {\n const { kek } = input;\n const keyring = normalizeContainerKekKeyring(kek.keyring);\n if (\n keyring.containerId !== kek.containerId ||\n keyring.containerKeyEpochId !== kek.containerKeyEpochId\n ) {\n throw new Error(\n `${projectionKekLabel(input.index)} keyring is inconsistent`,\n );\n }\n if (input.verifyKeyringCommitment) {\n await assertKeyringCommitment({\n currentManifest: input.currentManifest,\n index: input.index,\n kek,\n keyring,\n });\n }\n\n let entries: Awaited<ReturnType<typeof openContainerKekKeyring>>;\n try {\n entries = await openContainerKekKeyring({\n keyEpoch: kek.containerKeyEpoch,\n keyring,\n successorContainerKey: input.successorKeyMaterial,\n });\n } catch (error) {\n if (error instanceof KeyingVerificationError) {\n throw error;\n }\n // Label opaque AEAD failures; structural verification errors already\n // carry their own diagnosis.\n throw new Error(\n `${projectionKekLabel(input.index)} keyring could not be opened`,\n { cause: error },\n );\n }\n // Per-entry material-id verification proves an entry's key matches the id\n // it declares, but a poisoned keyring can declare a self-consistent FAKE\n // id — fresh key, matching commitment — for an epoch the container never\n // had. Anchor every entry the projection can name to the epoch id its\n // signed history actually committed; anything else is a forged epoch.\n await verifyContainerKekEntries(kek.containerId, entries);\n\n // Every epoch id the signed manifest history names must be present in the\n // keyring. A forged entry can be self-consistent, but it cannot also make\n // the real epoch id — which a signed state already named — disappear.\n const entryEpochIds = new Set(\n entries.map((entry) => entry.containerKeyEpochId),\n );\n const signedEpochIds = signedHistoryEpochIds({\n headManifestHash: input.currentManifest.manifestHash,\n kek,\n verifiedByHash: input.verifiedByHash,\n });\n for (const historicalEpochId of signedEpochIds) {\n if (!entryEpochIds.has(historicalEpochId)) {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n `${projectionKekLabel(input.index)} keyring omits an epoch its manifest history commits to`,\n );\n }\n }\n return entries;\n}\n\n/**\n * Epoch ids named by verified historical manifest states for this container.\n * Those states are signed, so an id they name is an epoch the container\n * provably had — and a keyring that omits it in favor of a forged id for the\n * same position is detectable even when no epoch RECORD was shipped.\n */\nexport function manifestHistoryEpochIds(kek: ProjectionKek): Set<string> {\n const epochIds = new Set<string>();\n for (const bundle of sameContainerManifestHistory(kek)) {\n const state = readCanonicalRecord(\n bundle.state,\n \"Container writer projection historical manifest state\",\n );\n const containerKeyEpochId = Reflect.get(state, \"containerKeyEpochId\");\n if (\n typeof containerKeyEpochId === \"string\" &&\n containerKeyEpochId !== kek.containerKeyEpochId\n ) {\n epochIds.add(containerKeyEpochId);\n }\n }\n return epochIds;\n}\n\n/**\n * The epoch ids this KEK's own history names, plus every one its head's\n * verified lineage names wherever the projection served it. Verification pools\n * every KEK's history, so a server can serve a container's older manifests\n * under another KEK; walking the lineage keeps a forged keyring id from passing\n * because the real id it displaces moved (#2365 finding 32). The walk stops at\n * the first manifest verification did not record, so it only ever adds ids.\n */\nexport function signedHistoryEpochIds(input: {\n readonly headManifestHash: string;\n readonly kek: ProjectionKek;\n readonly verifiedByHash: VerifiedManifests;\n}): Set<string> {\n const epochIds = manifestHistoryEpochIds(input.kek);\n const visited = new Set<string>();\n let current = input.verifiedByHash.get(input.headManifestHash);\n while (\n current &&\n current.state.containerId === input.kek.containerId &&\n !visited.has(current.manifestHash)\n ) {\n visited.add(current.manifestHash);\n const epochId = current.state.containerKeyEpochId;\n if (epochId !== null && epochId !== input.kek.containerKeyEpochId) {\n epochIds.add(epochId);\n }\n const previousHash = current.state.previousManifestHash;\n current =\n previousHash === null\n ? undefined\n : input.verifiedByHash.get(previousHash);\n }\n return epochIds;\n}\n\nfunction admitKeyringEntry(input: {\n entry: Awaited<ReturnType<typeof openContainerKekKeyring>>[number];\n index: number;\n kek: ProjectionKek;\n keksByEpochId: Map<string, UnwrappedContainerKek>;\n}): void {\n const { entry, kek } = input;\n const cached = input.keksByEpochId.get(entry.containerKeyEpochId);\n if (cached) {\n if (cached.containerId !== kek.containerId) {\n throw new Error(\n `${projectionKekLabel(input.index)} cached historical KEK is inconsistent`,\n );\n }\n return;\n }\n input.keksByEpochId.set(entry.containerKeyEpochId, {\n containerId: kek.containerId,\n // A keyring entry is key material plus the epoch id that commits to it —\n // there is no epoch record, so no fingerprint. Selection falls back to the\n // epoch id and AEAD authenticates; the commitment check above is what\n // makes the material itself trustworthy.\n keyEpochHash: null,\n keyMaterial: entry.keyMaterial,\n });\n}\n\n/**\n * Opens the sealed keyring for one path index and admits every entry into\n * `keksByEpochId` after verifying it against the material-id commitment its\n * ordinal position implies (entry i is key epoch i + 1). No chain walk:\n * one decrypt yields the container's complete retained history, and entry\n * verification is independent per entry.\n */\nexport async function unwrapKeyringContainerKeksAtIndex(input: {\n currentManifest: ContainerWriterProjectionResponse[\"path\"][number];\n index: number;\n kek: ProjectionKek;\n keksByEpochId: Map<string, UnwrappedContainerKek>;\n successorKeyMaterial: Uint8Array | null;\n /** Every manifest projection verification recorded; anchors the keyring. */\n verifiedByHash: VerifiedManifests;\n verifyKeyringCommitment: boolean;\n}): Promise<void> {\n const { kek, successorKeyMaterial } = input;\n if (!successorKeyMaterial) {\n return;\n }\n\n if (kek.keyring === null) {\n if (kek.containerKeyEpoch !== 1) {\n throw new ContainerKekHistoryUnavailableError(\n projectionKekLabel(input.index),\n );\n }\n return;\n }\n\n const entries = await openVerifiedKeyringEntries({\n currentManifest: input.currentManifest,\n index: input.index,\n kek,\n successorKeyMaterial,\n verifiedByHash: input.verifiedByHash,\n verifyKeyringCommitment: input.verifyKeyringCommitment,\n });\n for (const entry of entries) {\n admitKeyringEntry({\n entry,\n index: input.index,\n kek,\n keksByEpochId: input.keksByEpochId,\n });\n }\n}\n\n/**\n * Epoch ids this projection implies exist but that were not recovered —\n * used to attribute history failures to the material they orphan.\n */\nexport function projectedUnreachablePredecessorEpochIds(input: {\n kek: ProjectionKek;\n keksByEpochId: ReadonlyMap<string, UnwrappedContainerKek>;\n}): string[] {\n const projectedEpochIds = new Set<string>();\n for (const bundle of sameContainerManifestHistory(input.kek)) {\n const state = readCanonicalRecord(\n bundle.state,\n \"Container writer projection historical manifest state\",\n );\n const containerKeyEpochId = Reflect.get(state, \"containerKeyEpochId\");\n if (typeof containerKeyEpochId === \"string\") {\n projectedEpochIds.add(containerKeyEpochId);\n }\n }\n projectedEpochIds.delete(input.kek.containerKeyEpochId);\n return [...projectedEpochIds].filter(\n (containerKeyEpochId) => !input.keksByEpochId.has(containerKeyEpochId),\n );\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { VerifiedContainerAccessManifest } from "../../../internal/crypto/index.js";
|
|
2
2
|
import type { ContainerWriterProjectionResponse } from "../../../internal/validators/response/index.js";
|
|
3
|
-
import { type PrincipalPolicyCache } from "../../keyingProjectionVerification.js";
|
|
3
|
+
import { type PrincipalPolicyCache } from "../../keyingProjectionVerification/index.js";
|
|
4
4
|
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
5
5
|
import type { ProjectionVerificationOptions } from "./types.js";
|
|
6
6
|
export type UnwrapContainerKekPathInput = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { collectContainerWriterProjectionPrincipalPolicies, } from "../../keyingProjectionVerification.js";
|
|
1
|
+
import { collectContainerWriterProjectionPrincipalPolicies, } from "../../keyingProjectionVerification/index.js";
|
|
2
2
|
import { resolveProjectionVerifier } from "./types.js";
|
|
3
3
|
export async function verifyContainerKekPathProjection(input) {
|
|
4
4
|
if (input.projection.path.length !== input.projection.containerKeks.length) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computeAccessEventBodyHash, computeAccessEventHash, computeAccessManifestHash, computeDocumentContentKeyTargetHash, deriveDocumentLinkSetManifest, signAccessEvent, } from "../../../internal/crypto/index.js";
|
|
2
|
-
import { readCanonicalJson, readCanonicalRecord, } from "../../
|
|
2
|
+
import { readCanonicalJson, readCanonicalRecord, } from "../../keying/canonicalJson.js";
|
|
3
3
|
import { authorizingContainerPathRefsForLinkSet, containerPathRefs, deriveDocumentCreateTargets, mergeTargetEnvelopes, } from "./projection.js";
|
|
4
4
|
import { sortDocumentTargets, uniqueSortedStrings } from "./readers.js";
|
|
5
5
|
export async function buildDocumentCreatePlan({ author, containerProjection, contentKeyEpoch = 1, documentId = crypto.randomUUID(), eventId = crypto.randomUUID(), signedAt = new Date().toISOString(), targetEnvelopes, }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["events.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessEventBodyHash,\n computeAccessEventHash,\n computeAccessManifestHash,\n computeDocumentContentKeyTargetHash,\n type DocumentLinkAccessEventBody,\n type DocumentLinkSetManifestState,\n deriveDocumentLinkSetManifest,\n signAccessEvent,\n type UnsignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { ContainerManifestRef } from \"@tearleads/validators/request\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../keyingCanonicalJson\";\nimport {\n authorizingContainerPathRefsForLinkSet,\n containerPathRefs,\n deriveDocumentCreateTargets,\n mergeTargetEnvelopes,\n} from \"./projection\";\nimport { sortDocumentTargets, uniqueSortedStrings } from \"./readers\";\nimport type {\n BuildDocumentCreatePlanInput,\n DocumentCreateAuthor,\n DocumentCreatePlan,\n DocumentLinkSetEventPlan,\n DocumentLinkSetMutationBody,\n DocumentLinkSetMutationOperation,\n DocumentLinkSetTargetState,\n} from \"./types\";\n\nexport async function buildDocumentCreatePlan({\n author,\n containerProjection,\n contentKeyEpoch = 1,\n documentId = crypto.randomUUID(),\n eventId = crypto.randomUUID(),\n signedAt = new Date().toISOString(),\n targetEnvelopes,\n}: BuildDocumentCreatePlanInput): Promise<DocumentCreatePlan> {\n // The document belongs to its container's organization, not the author's. A\n // member authoring a document under another org's shared container creates a\n // document owned by that org; the author supplies only the signer identity.\n const organizationId = containerProjection.organizationId;\n\n const targets = deriveDocumentCreateTargets(containerProjection);\n const targetEnvelopesForRequest = mergeTargetEnvelopes(\n targets,\n targetEnvelopes,\n );\n const targetContainerManifestHash = targets[0]?.containerManifestHash;\n const targetContainerId = targets[0]?.containerId;\n if (!targetContainerManifestHash || !targetContainerId) {\n throw new Error(\"Document create target is unavailable\");\n }\n\n const body: DocumentLinkAccessEventBody = {\n blobRewraps: [],\n eventType: \"document.link\",\n containerId: targetContainerId,\n containerManifestHash: targetContainerManifestHash,\n };\n const bodyHash = await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document create body\"),\n );\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId,\n eventType: \"document.link\",\n objectKind: \"document\",\n objectId: documentId,\n organizationId,\n previousManifestHash: null,\n dependencyManifestHashes: uniqueSortedStrings(\n containerProjection.path.map((bundle) => bundle.manifestHash),\n ),\n bodyHash,\n signerUserId: author.signerUserId,\n signerDeviceId: author.signerDeviceId,\n signerKeyFingerprint: author.signerKeyFingerprint,\n signedAt,\n };\n const event = await signAccessEvent(unsignedEvent, author.signerPrivateKey);\n const eventHash = await computeAccessEventHash(event);\n const state: DocumentLinkSetManifestState = {\n version: 1,\n documentId,\n organizationId,\n epoch: 1,\n previousManifestHash: null,\n eventHash,\n linkedContainerIds: [targetContainerId],\n };\n const manifest = await deriveDocumentLinkSetManifest(state);\n const manifestHash = await computeAccessManifestHash(manifest);\n const targetHash = await computeDocumentContentKeyTargetHash(targets);\n\n return {\n body,\n documentId,\n event,\n eventHash,\n manifest,\n manifestHash,\n request: {\n event: readCanonicalRecord(event, \"Document create event\"),\n body: readCanonicalRecord(body, \"Document create body\"),\n expectedManifestHash: manifestHash,\n manifest: readCanonicalRecord(manifest, \"Document create manifest\"),\n targetContainerPathRefs: containerPathRefs(containerProjection.path),\n contentKeyBundle: {\n contentKeyEpoch,\n linkSetManifestHash: manifestHash,\n targetHash,\n targets: targetEnvelopesForRequest,\n },\n },\n state,\n targetHash,\n targets: sortDocumentTargets(targets),\n };\n}\n\nexport async function buildDocumentLinkSetEventPlan(input: {\n blobRewraps: DocumentLinkAccessEventBody[\"blobRewraps\"];\n author: DocumentCreateAuthor;\n eventId: string;\n operation: DocumentLinkSetMutationOperation;\n // The document's existing organization (from its manifest). Link/unlink does\n // not change ownership, so the event keeps the document's org, which is the\n // container's org — never the acting member's personal org.\n organizationId: string;\n signedAt: string;\n targetContainerPathRefs: readonly ContainerManifestRef[];\n targetState: DocumentLinkSetTargetState;\n writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentLinkSetEventPlan> {\n const eventType =\n input.operation === \"link\" ? \"document.link\" : \"document.unlink\";\n const body: DocumentLinkSetMutationBody = {\n blobRewraps: input.blobRewraps,\n eventType,\n containerId: input.targetState.target.containerId,\n containerManifestHash: input.targetState.target.containerManifestHash,\n };\n const bodyHash = await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document link-set body\"),\n );\n const authorizingContainerPathRefs = authorizingContainerPathRefsForLinkSet({\n operation: input.operation,\n targetContainerId: input.targetState.target.containerId,\n writerProjection: input.writerProjection,\n });\n const dependencyManifestHashes = uniqueSortedStrings(\n [\n ...input.targetContainerPathRefs,\n ...authorizingContainerPathRefs.flat(),\n ].map((ref) => ref.manifestHash),\n );\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId,\n eventType,\n objectKind: \"document\",\n objectId: input.writerProjection.documentId,\n organizationId: input.organizationId,\n previousManifestHash: input.writerProjection.documentManifest.manifestHash,\n dependencyManifestHashes,\n bodyHash,\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt,\n };\n const event = await signAccessEvent(\n unsignedEvent,\n input.author.signerPrivateKey,\n );\n const eventHash = await computeAccessEventHash(event);\n\n return {\n authorizingContainerPathRefs,\n body,\n event,\n eventHash,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["events.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessEventBodyHash,\n computeAccessEventHash,\n computeAccessManifestHash,\n computeDocumentContentKeyTargetHash,\n type DocumentLinkAccessEventBody,\n type DocumentLinkSetManifestState,\n deriveDocumentLinkSetManifest,\n signAccessEvent,\n type UnsignedAccessEvent,\n} from \"@tearleads/crypto\";\nimport type { ContainerManifestRef } from \"@tearleads/validators/request\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n readCanonicalJson,\n readCanonicalRecord,\n} from \"../../keying/canonicalJson\";\nimport {\n authorizingContainerPathRefsForLinkSet,\n containerPathRefs,\n deriveDocumentCreateTargets,\n mergeTargetEnvelopes,\n} from \"./projection\";\nimport { sortDocumentTargets, uniqueSortedStrings } from \"./readers\";\nimport type {\n BuildDocumentCreatePlanInput,\n DocumentCreateAuthor,\n DocumentCreatePlan,\n DocumentLinkSetEventPlan,\n DocumentLinkSetMutationBody,\n DocumentLinkSetMutationOperation,\n DocumentLinkSetTargetState,\n} from \"./types\";\n\nexport async function buildDocumentCreatePlan({\n author,\n containerProjection,\n contentKeyEpoch = 1,\n documentId = crypto.randomUUID(),\n eventId = crypto.randomUUID(),\n signedAt = new Date().toISOString(),\n targetEnvelopes,\n}: BuildDocumentCreatePlanInput): Promise<DocumentCreatePlan> {\n // The document belongs to its container's organization, not the author's. A\n // member authoring a document under another org's shared container creates a\n // document owned by that org; the author supplies only the signer identity.\n const organizationId = containerProjection.organizationId;\n\n const targets = deriveDocumentCreateTargets(containerProjection);\n const targetEnvelopesForRequest = mergeTargetEnvelopes(\n targets,\n targetEnvelopes,\n );\n const targetContainerManifestHash = targets[0]?.containerManifestHash;\n const targetContainerId = targets[0]?.containerId;\n if (!targetContainerManifestHash || !targetContainerId) {\n throw new Error(\"Document create target is unavailable\");\n }\n\n const body: DocumentLinkAccessEventBody = {\n blobRewraps: [],\n eventType: \"document.link\",\n containerId: targetContainerId,\n containerManifestHash: targetContainerManifestHash,\n };\n const bodyHash = await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document create body\"),\n );\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId,\n eventType: \"document.link\",\n objectKind: \"document\",\n objectId: documentId,\n organizationId,\n previousManifestHash: null,\n dependencyManifestHashes: uniqueSortedStrings(\n containerProjection.path.map((bundle) => bundle.manifestHash),\n ),\n bodyHash,\n signerUserId: author.signerUserId,\n signerDeviceId: author.signerDeviceId,\n signerKeyFingerprint: author.signerKeyFingerprint,\n signedAt,\n };\n const event = await signAccessEvent(unsignedEvent, author.signerPrivateKey);\n const eventHash = await computeAccessEventHash(event);\n const state: DocumentLinkSetManifestState = {\n version: 1,\n documentId,\n organizationId,\n epoch: 1,\n previousManifestHash: null,\n eventHash,\n linkedContainerIds: [targetContainerId],\n };\n const manifest = await deriveDocumentLinkSetManifest(state);\n const manifestHash = await computeAccessManifestHash(manifest);\n const targetHash = await computeDocumentContentKeyTargetHash(targets);\n\n return {\n body,\n documentId,\n event,\n eventHash,\n manifest,\n manifestHash,\n request: {\n event: readCanonicalRecord(event, \"Document create event\"),\n body: readCanonicalRecord(body, \"Document create body\"),\n expectedManifestHash: manifestHash,\n manifest: readCanonicalRecord(manifest, \"Document create manifest\"),\n targetContainerPathRefs: containerPathRefs(containerProjection.path),\n contentKeyBundle: {\n contentKeyEpoch,\n linkSetManifestHash: manifestHash,\n targetHash,\n targets: targetEnvelopesForRequest,\n },\n },\n state,\n targetHash,\n targets: sortDocumentTargets(targets),\n };\n}\n\nexport async function buildDocumentLinkSetEventPlan(input: {\n blobRewraps: DocumentLinkAccessEventBody[\"blobRewraps\"];\n author: DocumentCreateAuthor;\n eventId: string;\n operation: DocumentLinkSetMutationOperation;\n // The document's existing organization (from its manifest). Link/unlink does\n // not change ownership, so the event keeps the document's org, which is the\n // container's org — never the acting member's personal org.\n organizationId: string;\n signedAt: string;\n targetContainerPathRefs: readonly ContainerManifestRef[];\n targetState: DocumentLinkSetTargetState;\n writerProjection: DocumentWriterProjectionResponse;\n}): Promise<DocumentLinkSetEventPlan> {\n const eventType =\n input.operation === \"link\" ? \"document.link\" : \"document.unlink\";\n const body: DocumentLinkSetMutationBody = {\n blobRewraps: input.blobRewraps,\n eventType,\n containerId: input.targetState.target.containerId,\n containerManifestHash: input.targetState.target.containerManifestHash,\n };\n const bodyHash = await computeAccessEventBodyHash(\n readCanonicalJson(body, \"Document link-set body\"),\n );\n const authorizingContainerPathRefs = authorizingContainerPathRefsForLinkSet({\n operation: input.operation,\n targetContainerId: input.targetState.target.containerId,\n writerProjection: input.writerProjection,\n });\n const dependencyManifestHashes = uniqueSortedStrings(\n [\n ...input.targetContainerPathRefs,\n ...authorizingContainerPathRefs.flat(),\n ].map((ref) => ref.manifestHash),\n );\n const unsignedEvent: UnsignedAccessEvent = {\n version: 1,\n eventId: input.eventId,\n eventType,\n objectKind: \"document\",\n objectId: input.writerProjection.documentId,\n organizationId: input.organizationId,\n previousManifestHash: input.writerProjection.documentManifest.manifestHash,\n dependencyManifestHashes,\n bodyHash,\n signerUserId: input.author.signerUserId,\n signerDeviceId: input.author.signerDeviceId,\n signerKeyFingerprint: input.author.signerKeyFingerprint,\n signedAt: input.signedAt,\n };\n const event = await signAccessEvent(\n unsignedEvent,\n input.author.signerPrivateKey,\n );\n const eventHash = await computeAccessEventHash(event);\n\n return {\n authorizingContainerPathRefs,\n body,\n event,\n eventHash,\n };\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { computeAccessEventHash, computeAccessManifestHash, deriveDocumentLinkSetManifest, } from "../../../internal/crypto/index.js";
|
|
2
2
|
import { isPlainObject as isPlainRecord } from "../../../internal/validators/isPlainObject.js";
|
|
3
|
-
import { canonicalKeyingJsonString, readCanonicalRecord, } from "../../
|
|
3
|
+
import { canonicalKeyingJsonString, readCanonicalRecord, } from "../../keying/canonicalJson.js";
|
|
4
4
|
import { readAccessEvent, readAccessManifest, } from "../../keyingProjectionVerification/readers.js";
|
|
5
|
-
import { readRecordInteger, readRecordNullableString, readRecordPositiveInteger, readRecordString, readRecordValue, readStringArray, } from "../../recordReaders.js";
|
|
5
|
+
import { readRecordInteger, readRecordNullableString, readRecordPositiveInteger, readRecordString, readRecordValue, readStringArray, } from "../../shared/recordReaders.js";
|
|
6
6
|
function readDocumentLinkSetManifestState(value, label) {
|
|
7
7
|
const record = readCanonicalRecord(value, label);
|
|
8
8
|
if (readRecordInteger(record, "version", label) !== 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestBundleReaders.js","sourceRoot":"","sources":["manifestBundleReaders.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EAEzB,6BAA6B,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,IAAI,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAErF,OAAO,EACL,yBAAyB,EACzB,mBAAmB,GACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"manifestBundleReaders.js","sourceRoot":"","sources":["manifestBundleReaders.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computeAccessEventHash,\n computeAccessManifestHash,\n type DocumentLinkSetManifestState,\n deriveDocumentLinkSetManifest,\n} from \"@tearleads/crypto\";\nimport { isPlainObject as isPlainRecord } from \"@tearleads/validators/isPlainObject\";\nimport type { DocumentCreateResponse } from \"@tearleads/validators/response\";\nimport {\n canonicalKeyingJsonString,\n readCanonicalRecord,\n} from \"../../keying/canonicalJson\";\nimport {\n readAccessEvent,\n readAccessManifest,\n} from \"../../keyingProjectionVerification/readers\";\nimport {\n readRecordInteger,\n readRecordNullableString,\n readRecordPositiveInteger,\n readRecordString,\n readRecordValue,\n readStringArray,\n} from \"../../shared/recordReaders\";\n\nfunction readDocumentLinkSetManifestState(\n value: unknown,\n label: string,\n): DocumentLinkSetManifestState {\n const record = readCanonicalRecord(value, label);\n if (readRecordInteger(record, \"version\", label) !== 1) {\n throw new Error(`${label}.version must be 1`);\n }\n\n return {\n version: 1,\n documentId: readRecordString(record, \"documentId\", label),\n organizationId: readRecordString(record, \"organizationId\", label),\n epoch: readRecordPositiveInteger(record, \"epoch\", label),\n previousManifestHash: readRecordNullableString(\n record,\n \"previousManifestHash\",\n label,\n ),\n eventHash: readRecordString(record, \"eventHash\", label),\n linkedContainerIds: readStringArray(\n readRecordValue(record, \"linkedContainerIds\"),\n `${label}.linkedContainerIds`,\n ),\n };\n}\n\nexport function serializeCanonical(value: unknown, label: string): string {\n if (\n value === undefined ||\n typeof value === \"function\" ||\n typeof value === \"symbol\"\n ) {\n throw new Error(`Document create response ${label} is invalid`);\n }\n\n return canonicalKeyingJsonString(value, `Document create response ${label}`);\n}\n\nexport async function assertDocumentManifestBundleConsistent(input: {\n bundle: DocumentCreateResponse[\"accessManifest\"];\n label: string;\n}): Promise<{ documentId: string; organizationId: string }> {\n const manifestHash = await computeAccessManifestHash(\n readAccessManifest(input.bundle.manifest, `${input.label} manifest`),\n );\n if (manifestHash !== input.bundle.manifestHash) {\n throw new Error(`${input.label} manifest hash mismatch`);\n }\n\n const eventBundle = input.bundle.event;\n if (!isPlainRecord(eventBundle)) {\n throw new Error(`${input.label} event bundle is invalid`);\n }\n const eventHash = readRecordString(eventBundle, \"eventHash\", input.label);\n const event = Reflect.get(eventBundle, \"event\");\n const accessEvent = readAccessEvent(event, `${input.label} signed event`);\n const computedEventHash = await computeAccessEventHash(accessEvent);\n if (computedEventHash !== eventHash) {\n throw new Error(`${input.label} event hash mismatch`);\n }\n\n const state = readDocumentLinkSetManifestState(\n input.bundle.state,\n `${input.label} state`,\n );\n if (state.eventHash !== eventHash) {\n throw new Error(`${input.label} state event hash mismatch`);\n }\n const derivedManifest = await deriveDocumentLinkSetManifest(state);\n if (\n serializeCanonical(input.bundle.manifest, \"manifest\") !==\n serializeCanonical(derivedManifest, \"manifest\")\n ) {\n throw new Error(`${input.label} manifest state mismatch`);\n }\n\n return {\n documentId: state.documentId,\n organizationId: state.organizationId,\n };\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DocumentContentKeyTarget, VerifiedContainerAccessManifest } from "../../../internal/crypto/index.js";
|
|
2
2
|
import type { DocumentWriterProjectionResponse } from "../../../internal/validators/response/index.js";
|
|
3
|
-
import { type DocumentWriterProjectionAuthorization, type PrincipalPolicyCache } from "../../keyingProjectionVerification.js";
|
|
3
|
+
import { type DocumentWriterProjectionAuthorization, type PrincipalPolicyCache } from "../../keyingProjectionVerification/index.js";
|
|
4
4
|
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
5
5
|
export { unwrapContainerKekPath } from "./containerKekPath.js";
|
|
6
6
|
export { ContainerKekHistoryUnavailableError } from "./containerKekPathHistory.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { computeDocumentContentKeyTargetHash } from "../../../internal/crypto/index.js";
|
|
2
|
-
import {
|
|
3
|
-
import { verifyDocumentWriterProjectionAuthorization, } from "../../keyingProjectionVerification.js";
|
|
2
|
+
import { verifyDocumentWriterProjectionAuthorization, } from "../../keyingProjectionVerification/index.js";
|
|
4
3
|
import { throwKeyingVerificationShapeFailure } from "../../keyingProjectionVerification/error.js";
|
|
4
|
+
import { errorMessage } from "../../shared/errorMessage.js";
|
|
5
5
|
import { currentDocumentTargets, deriveDocumentTargetFromProjection, readLinkedContainerIdsFromDocumentManifest, } from "./projectionTargets.js";
|
|
6
6
|
import { assertDocumentManifestBundleConsistent, normalizeDocumentKekTargetResponse, sortDocumentTargets, targetEnvelopeReference, targetKey, uniqueSortedStrings, } from "./readers.js";
|
|
7
7
|
export { unwrapContainerKekPath } from "./containerKekPath.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["projection.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mCAAmC,EAAE,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAGL,2CAA2C,GAC5C,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mCAAmC,EAAE,MAAM,0CAA0C,CAAC;AAE/F,OAAO,EACL,sBAAsB,EACtB,kCAAkC,EAClC,0CAA0C,GAC3C,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,sCAAsC,EACtC,kCAAkC,EAClC,mBAAmB,EACnB,uBAAuB,EACvB,SAAS,EACT,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,mCAAmC,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EACL,oCAAoC,EACpC,mCAAmC,EACnC,kCAAkC,EAClC,+BAA+B,EAC/B,kCAAkC,EAClC,4CAA4C,EAC5C,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,4BAA4B,EAC5B,sCAAsC,EACtC,iBAAiB,EACjB,sBAAsB,EACtB,2BAA2B,EAC3B,kCAAkC,EAClC,oBAAoB,EACpB,0CAA0C,EAC1C,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAEpD,SAAS,wBAAwB,CAC/B,IAAuB,EACvB,KAAwB,EACxB,OAAe;IAEf,IACE,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAC5B,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,EACnD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,mDAAmD,CAAC,KAG5D;IACC,IAAI,KAAK,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,KAAK,MAAM,CACT,KAAK,EACL,UAAU,EACX,IAAI,KAAK,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,OAAO,EAAE,EAAE,CAAC;QAChE,IAAI,gBAA0C,CAAC;QAC/C,IAAI,CAAC;YACH,gBAAgB,GAAG,kCAAkC,CAAC,UAAU,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,iDAAiD,KAAK,iBAAiB,YAAY,CAAC,KAAK,CAAC,EAAE,CAC7F,CAAC;QACJ,CAAC;QAED,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC;YAChD,SAAS;QACX,CAAC;QAED,sEAAsE;QACtE,kEAAkE;QAClE,MAAM,IAAI,KAAK,CACb,iDAAiD,KAAK,4BAA4B,CACnF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,0CAA0C,CACjD,OAA4C,EAC5C,gBAAkD;IAElD,yEAAyE;IACzE,kEAAkE;IAClE,IACE,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,EAC5E,CAAC;QACD,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,wBAAwB,CACtB,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,EAChE,0CAA0C,CAAC,gBAAgB,CAAC,EAC5D,mEAAmE,CACpE,CAAC;IACF,wBAAwB,CACtB,mBAAmB,CACjB,gBAAgB,CAAC,kBAAkB,CAAC,6BAA6B,CAClE,EACD,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,EAC1E,6DAA6D,CAC9D,CAAC;IACF,wBAAwB,CACtB,mBAAmB,CACjB,gBAAgB,CAAC,kBAAkB,CAAC,0BAA0B,CAC/D,EACD,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,EACxE,wDAAwD,CACzD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,0CAA0C,CACvD,gBAAkD,EAClD,qBAA8B;IAE9B,MAAM,EAAE,YAAY,EAAE,GAAG,gBAAgB,CAAC,gBAAgB,CAAC;IAC3D,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,mBAAmB,KAAK,YAAY,EAAE,CAAC;QAC3E,sEAAsE;QACtE,uCAAuC;QACvC,IACE,CAAC,qBAAqB;YACtB,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,IAAI,CAC5C,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,YAAY;gBACnB,gBAAgB,CAAC,gBAAgB,CAAC,mBAAmB,CACxD,EACD,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,IACE,gBAAgB,CAAC,kBAAkB,CAAC,qBAAqB;YACzD,gBAAgB,CAAC,gBAAgB,CAAC,UAAU,EAC5C,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QACD,OAAO;IACT,CAAC;IAED,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,qBAAqB,GAAG,MAAM,mCAAmC,CACrE,mBAAmB,CACjB,gBAAgB,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CACvE,CACF,CAAC;IACF,IAAI,qBAAqB,KAAK,gBAAgB,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CACb,sEAAsE,CACvE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gDAAgD,CAC7D,gBAAkD,EAClD,KAgBC;IAED,MAAM,wBAAwB,GAAG,yBAAyB,CACxD,KAAK,EACL,4BAA4B,CAC7B,CAAC;IACF,IACE,KAAK,CAAC,sBAAsB,KAAK,IAAI;QACrC,wBAAwB,KAAK,IAAI,EACjC,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,2CAA2C,CAAC;YACtE,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,8BAA8B,EAAE,KAAK,CAAC,8BAA8B;YACpE,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;YAChD,UAAU,EAAE,gBAAgB;YAC5B,cAAc,EAAE,wBAAwB;YACxC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,+BAA+B,EAAE,KAAK,CAAC,+BAA+B;SACvE,CAAC,CAAC;QACH,KAAK,CAAC,uBAAuB,EAAE,CAAC,aAAa,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,qBAAqB,KAAK,IAAI,CAAC;IAC9E,IAAI,qBAAqB,IAAI,KAAK,CAAC,0BAA0B,KAAK,IAAI,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,sCAAsC,CAAC;QACpE,MAAM,EAAE,gBAAgB,CAAC,gBAAgB;QACzC,KAAK,EAAE,qCAAqC;KAC7C,CAAC,CAAC;IACH,MAAM,EAAE,UAAU,EAAE,GAAG,gBAAgB,CAAC;IACxC,IACE,gBAAgB,CAAC,UAAU,KAAK,UAAU;QAC1C,gBAAgB,CAAC,kBAAkB,CAAC,UAAU,KAAK,UAAU;QAC7D,gBAAgB,CAAC,gBAAgB,CAAC,UAAU,KAAK,UAAU,EAC3D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IACE,gBAAgB,CAAC,kBAAkB,CAAC,mBAAmB;QACvD,gBAAgB,CAAC,gBAAgB,CAAC,YAAY,EAC9C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,0CAA0C,CAC9C,gBAAgB,EAChB,qBAAqB,CACtB,CAAC;IAEF,MAAM,OAAO,GAAG,qBAAqB;QACnC,CAAC,CAAC,kCAAkC,CAAC,gBAAgB,CAAC,kBAAkB,CAAC;QACzE,CAAC,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IAC7C,MAAM,mBAAmB,GACvB,MAAM,mCAAmC,CAAC,OAAO,CAAC,CAAC;IACrD,IACE,mBAAmB;QACnB,gBAAgB,CAAC,kBAAkB,CAAC,qBAAqB,EACzD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,0CAA0C,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IACtE,mDAAmD,CAAC;QAClD,OAAO;QACP,gBAAgB;KACjB,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wCAAwC,CAC5D,GAAG,KAA0E;IAE7E,IAAI,CAAC;QACH,OAAO,MAAM,gDAAgD,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mCAAmC,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC","sourcesContent":["import type {\n DocumentContentKeyTarget,\n VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { computeDocumentContentKeyTargetHash } from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport { errorMessage } from \"../../errorMessage\";\nimport {\n type DocumentWriterProjectionAuthorization,\n type PrincipalPolicyCache,\n verifyDocumentWriterProjectionAuthorization,\n} from \"../../keyingProjectionVerification\";\nimport { throwKeyingVerificationShapeFailure } from \"../../keyingProjectionVerification/error\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport {\n currentDocumentTargets,\n deriveDocumentTargetFromProjection,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"./projectionTargets\";\nimport {\n assertDocumentManifestBundleConsistent,\n normalizeDocumentKekTargetResponse,\n sortDocumentTargets,\n targetEnvelopeReference,\n targetKey,\n uniqueSortedStrings,\n} from \"./readers\";\n\nexport { unwrapContainerKekPath } from \"./containerKekPath\";\nexport { ContainerKekHistoryUnavailableError } from \"./containerKekPathHistory\";\nexport {\n buildRotatedDocumentContentKeyBundle,\n collectContainerKeksForDocumentSync,\n DocumentContentKeyUnavailableError,\n DocumentHistoryUnavailableError,\n unwrapDocumentContentKeyFromBundle,\n unwrapDocumentContentKeyFromWriterProjection,\n unwrapDocumentContentKeyTarget,\n wrapDocumentContentKeyForCreate,\n} from \"./projectionContentKeys\";\nexport {\n authorizingContainerPathRefs,\n authorizingContainerPathRefsForLinkSet,\n containerPathRefs,\n currentDocumentTargets,\n deriveDocumentCreateTargets,\n deriveDocumentTargetFromProjection,\n mergeTargetEnvelopes,\n readLinkedContainerIdsFromDocumentManifest,\n verifiedDocumentWrapTargets,\n} from \"./projectionTargets\";\n\nimport type { ProjectionVerificationOptions } from \"./types\";\nimport { resolveProjectionVerifier } from \"./types\";\n\nfunction assertSortedStringsEqual(\n left: readonly string[],\n right: readonly string[],\n message: string,\n): void {\n if (\n left.length !== right.length ||\n left.some((value, index) => value !== right[index])\n ) {\n throw new Error(message);\n }\n}\n\nfunction assertAuthorizingContainerPathsMatchDocumentTargets(input: {\n targets: readonly DocumentContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n}): void {\n if (input.writerProjection.authorizingContainerPaths.length === 0) {\n throw new Error(\"Document writer projection authorization paths missing\");\n }\n\n const targetKeys = new Set(input.targets.map(targetKey));\n for (const [\n index,\n projection,\n ] of input.writerProjection.authorizingContainerPaths.entries()) {\n let projectionTarget: DocumentContentKeyTarget;\n try {\n projectionTarget = deriveDocumentTargetFromProjection(projection);\n } catch (error) {\n throw new Error(\n `Document writer projection authorization path[${index}] is invalid: ${errorMessage(error)}`,\n );\n }\n\n if (targetKeys.has(targetKey(projectionTarget))) {\n continue;\n }\n\n // Bind server-supplied KEK paths to committed document targets before\n // using any unwrapped path KEK for document content-key material.\n throw new Error(\n `Document writer projection authorization path[${index}] is not a document target`,\n );\n }\n}\n\nfunction assertDocumentTargetsCoverLinkedContainers(\n targets: readonly DocumentContentKeyTarget[],\n writerProjection: DocumentWriterProjectionResponse,\n): void {\n // One target per linked container: a second epoch for the same container\n // would let a re-wrap land on a KEK a revoked member still holds.\n if (\n new Set(targets.map((target) => target.containerId)).size !== targets.length\n ) {\n throw new Error(\n \"Document writer projection targets name a linked container more than once\",\n );\n }\n assertSortedStringsEqual(\n uniqueSortedStrings(targets.map((target) => target.containerId)),\n readLinkedContainerIdsFromDocumentManifest(writerProjection),\n \"Document writer projection targets do not match linked containers\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerManifestHashes,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerManifestHash)),\n \"Document writer projection target manifest summary mismatch\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerKeyEpochIds,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerKeyEpochId)),\n \"Document writer projection target KEK summary mismatch\",\n );\n}\n\nasync function assertProjectionContentKeyBundleConsistent(\n writerProjection: DocumentWriterProjectionResponse,\n staleContentKeyBundle: boolean,\n): Promise<void> {\n const { manifestHash } = writerProjection.documentManifest;\n if (writerProjection.contentKeyBundle.linkSetManifestHash !== manifestHash) {\n // A stale bundle may lag the link-set head, but it must still descend\n // from this document's manifest chain.\n if (\n !staleContentKeyBundle ||\n !writerProjection.documentManifestHistory.some(\n (bundle) =>\n bundle.manifestHash ===\n writerProjection.contentKeyBundle.linkSetManifestHash,\n )\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n }\n\n if (!staleContentKeyBundle) {\n if (\n writerProjection.documentKekTargets.documentKeyTargetHash !==\n writerProjection.contentKeyBundle.targetHash\n ) {\n throw new Error(\"Document writer projection target hash mismatch\");\n }\n return;\n }\n\n // The stale bundle cannot match the current targets; pin it to its own\n // canonical hash instead so a tampered envelope set still fails closed.\n const staleBundleTargetHash = await computeDocumentContentKeyTargetHash(\n sortDocumentTargets(\n writerProjection.contentKeyBundle.targets.map(targetEnvelopeReference),\n ),\n );\n if (staleBundleTargetHash !== writerProjection.contentKeyBundle.targetHash) {\n throw new Error(\n \"Document writer projection stale bundle target hash is not canonical\",\n );\n }\n}\n\nasync function assertDocumentWriterProjectionConsistentInternal(\n writerProjection: DocumentWriterProjectionResponse,\n input: ProjectionVerificationOptions & {\n /**\n * Accept a projection whose content-key bundle is marked stale (wrapped\n * to superseded KEK targets after e.g. a revoke rotation). Document sync\n * opts in to heal the bundle. Attachment reads opt in because their DEK\n * is independent and opens through verified retained container KEKs.\n */\n allowStaleContentKeyBundle?: boolean | undefined;\n execSql?: ExecSql | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n onVerifiedAuthorization?:\n | ((authorization: DocumentWriterProjectionAuthorization) => void)\n | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n stillCurrent?: (() => boolean) | undefined;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n },\n): Promise<DocumentContentKeyTarget[]> {\n const resolveProjectionUserKey = resolveProjectionVerifier(\n input,\n \"Document writer projection\",\n );\n if (\n input.trustedLocalProjection !== true &&\n resolveProjectionUserKey !== null\n ) {\n const authorization = await verifyDocumentWriterProjectionAuthorization({\n execSql: input.execSql,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n principalPolicyCache: input.principalPolicyCache,\n projection: writerProjection,\n resolveUserKey: resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n verifiedByHash: input.verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n input.onVerifiedAuthorization?.(authorization);\n }\n\n const staleContentKeyBundle = writerProjection.contentKeyBundleStale === true;\n if (staleContentKeyBundle && input.allowStaleContentKeyBundle !== true) {\n throw new Error(\"Document writer projection content-key bundle is stale\");\n }\n\n const manifestIdentity = await assertDocumentManifestBundleConsistent({\n bundle: writerProjection.documentManifest,\n label: \"Document writer projection manifest\",\n });\n const { documentId } = manifestIdentity;\n if (\n writerProjection.documentId !== documentId ||\n writerProjection.documentKekTargets.documentId !== documentId ||\n writerProjection.contentKeyBundle.documentId !== documentId\n ) {\n throw new Error(\"Document writer projection document id mismatch\");\n }\n if (\n writerProjection.documentKekTargets.linkSetManifestHash !==\n writerProjection.documentManifest.manifestHash\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n await assertProjectionContentKeyBundleConsistent(\n writerProjection,\n staleContentKeyBundle,\n );\n\n const targets = staleContentKeyBundle\n ? normalizeDocumentKekTargetResponse(writerProjection.documentKekTargets)\n : currentDocumentTargets(writerProjection);\n const canonicalTargetHash =\n await computeDocumentContentKeyTargetHash(targets);\n if (\n canonicalTargetHash !==\n writerProjection.documentKekTargets.documentKeyTargetHash\n ) {\n throw new Error(\"Document writer projection target hash is not canonical\");\n }\n\n assertDocumentTargetsCoverLinkedContainers(targets, writerProjection);\n assertAuthorizingContainerPathsMatchDocumentTargets({\n targets,\n writerProjection,\n });\n\n return targets;\n}\n\nexport async function assertDocumentWriterProjectionConsistent(\n ...input: Parameters<typeof assertDocumentWriterProjectionConsistentInternal>\n): ReturnType<typeof assertDocumentWriterProjectionConsistentInternal> {\n try {\n return await assertDocumentWriterProjectionConsistentInternal(...input);\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"projection.js","sourceRoot":"","sources":["projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DocumentContentKeyTarget,\n VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { computeDocumentContentKeyTargetHash } from \"@tearleads/crypto\";\nimport type { DocumentWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport {\n type DocumentWriterProjectionAuthorization,\n type PrincipalPolicyCache,\n verifyDocumentWriterProjectionAuthorization,\n} from \"../../keyingProjectionVerification\";\nimport { throwKeyingVerificationShapeFailure } from \"../../keyingProjectionVerification/error\";\nimport { errorMessage } from \"../../shared/errorMessage\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport {\n currentDocumentTargets,\n deriveDocumentTargetFromProjection,\n readLinkedContainerIdsFromDocumentManifest,\n} from \"./projectionTargets\";\nimport {\n assertDocumentManifestBundleConsistent,\n normalizeDocumentKekTargetResponse,\n sortDocumentTargets,\n targetEnvelopeReference,\n targetKey,\n uniqueSortedStrings,\n} from \"./readers\";\n\nexport { unwrapContainerKekPath } from \"./containerKekPath\";\nexport { ContainerKekHistoryUnavailableError } from \"./containerKekPathHistory\";\nexport {\n buildRotatedDocumentContentKeyBundle,\n collectContainerKeksForDocumentSync,\n DocumentContentKeyUnavailableError,\n DocumentHistoryUnavailableError,\n unwrapDocumentContentKeyFromBundle,\n unwrapDocumentContentKeyFromWriterProjection,\n unwrapDocumentContentKeyTarget,\n wrapDocumentContentKeyForCreate,\n} from \"./projectionContentKeys\";\nexport {\n authorizingContainerPathRefs,\n authorizingContainerPathRefsForLinkSet,\n containerPathRefs,\n currentDocumentTargets,\n deriveDocumentCreateTargets,\n deriveDocumentTargetFromProjection,\n mergeTargetEnvelopes,\n readLinkedContainerIdsFromDocumentManifest,\n verifiedDocumentWrapTargets,\n} from \"./projectionTargets\";\n\nimport type { ProjectionVerificationOptions } from \"./types\";\nimport { resolveProjectionVerifier } from \"./types\";\n\nfunction assertSortedStringsEqual(\n left: readonly string[],\n right: readonly string[],\n message: string,\n): void {\n if (\n left.length !== right.length ||\n left.some((value, index) => value !== right[index])\n ) {\n throw new Error(message);\n }\n}\n\nfunction assertAuthorizingContainerPathsMatchDocumentTargets(input: {\n targets: readonly DocumentContentKeyTarget[];\n writerProjection: DocumentWriterProjectionResponse;\n}): void {\n if (input.writerProjection.authorizingContainerPaths.length === 0) {\n throw new Error(\"Document writer projection authorization paths missing\");\n }\n\n const targetKeys = new Set(input.targets.map(targetKey));\n for (const [\n index,\n projection,\n ] of input.writerProjection.authorizingContainerPaths.entries()) {\n let projectionTarget: DocumentContentKeyTarget;\n try {\n projectionTarget = deriveDocumentTargetFromProjection(projection);\n } catch (error) {\n throw new Error(\n `Document writer projection authorization path[${index}] is invalid: ${errorMessage(error)}`,\n );\n }\n\n if (targetKeys.has(targetKey(projectionTarget))) {\n continue;\n }\n\n // Bind server-supplied KEK paths to committed document targets before\n // using any unwrapped path KEK for document content-key material.\n throw new Error(\n `Document writer projection authorization path[${index}] is not a document target`,\n );\n }\n}\n\nfunction assertDocumentTargetsCoverLinkedContainers(\n targets: readonly DocumentContentKeyTarget[],\n writerProjection: DocumentWriterProjectionResponse,\n): void {\n // One target per linked container: a second epoch for the same container\n // would let a re-wrap land on a KEK a revoked member still holds.\n if (\n new Set(targets.map((target) => target.containerId)).size !== targets.length\n ) {\n throw new Error(\n \"Document writer projection targets name a linked container more than once\",\n );\n }\n assertSortedStringsEqual(\n uniqueSortedStrings(targets.map((target) => target.containerId)),\n readLinkedContainerIdsFromDocumentManifest(writerProjection),\n \"Document writer projection targets do not match linked containers\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerManifestHashes,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerManifestHash)),\n \"Document writer projection target manifest summary mismatch\",\n );\n assertSortedStringsEqual(\n uniqueSortedStrings(\n writerProjection.documentKekTargets.linkedContainerKeyEpochIds,\n ),\n uniqueSortedStrings(targets.map((target) => target.containerKeyEpochId)),\n \"Document writer projection target KEK summary mismatch\",\n );\n}\n\nasync function assertProjectionContentKeyBundleConsistent(\n writerProjection: DocumentWriterProjectionResponse,\n staleContentKeyBundle: boolean,\n): Promise<void> {\n const { manifestHash } = writerProjection.documentManifest;\n if (writerProjection.contentKeyBundle.linkSetManifestHash !== manifestHash) {\n // A stale bundle may lag the link-set head, but it must still descend\n // from this document's manifest chain.\n if (\n !staleContentKeyBundle ||\n !writerProjection.documentManifestHistory.some(\n (bundle) =>\n bundle.manifestHash ===\n writerProjection.contentKeyBundle.linkSetManifestHash,\n )\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n }\n\n if (!staleContentKeyBundle) {\n if (\n writerProjection.documentKekTargets.documentKeyTargetHash !==\n writerProjection.contentKeyBundle.targetHash\n ) {\n throw new Error(\"Document writer projection target hash mismatch\");\n }\n return;\n }\n\n // The stale bundle cannot match the current targets; pin it to its own\n // canonical hash instead so a tampered envelope set still fails closed.\n const staleBundleTargetHash = await computeDocumentContentKeyTargetHash(\n sortDocumentTargets(\n writerProjection.contentKeyBundle.targets.map(targetEnvelopeReference),\n ),\n );\n if (staleBundleTargetHash !== writerProjection.contentKeyBundle.targetHash) {\n throw new Error(\n \"Document writer projection stale bundle target hash is not canonical\",\n );\n }\n}\n\nasync function assertDocumentWriterProjectionConsistentInternal(\n writerProjection: DocumentWriterProjectionResponse,\n input: ProjectionVerificationOptions & {\n /**\n * Accept a projection whose content-key bundle is marked stale (wrapped\n * to superseded KEK targets after e.g. a revoke rotation). Document sync\n * opts in to heal the bundle. Attachment reads opt in because their DEK\n * is independent and opens through verified retained container KEKs.\n */\n allowStaleContentKeyBundle?: boolean | undefined;\n execSql?: ExecSql | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n onVerifiedAuthorization?:\n | ((authorization: DocumentWriterProjectionAuthorization) => void)\n | undefined;\n principalPolicyCache?: PrincipalPolicyCache | undefined;\n stillCurrent?: (() => boolean) | undefined;\n verifiedByHash?: Map<string, VerifiedContainerAccessManifest> | undefined;\n },\n): Promise<DocumentContentKeyTarget[]> {\n const resolveProjectionUserKey = resolveProjectionVerifier(\n input,\n \"Document writer projection\",\n );\n if (\n input.trustedLocalProjection !== true &&\n resolveProjectionUserKey !== null\n ) {\n const authorization = await verifyDocumentWriterProjectionAuthorization({\n execSql: input.execSql,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n principalPolicyCache: input.principalPolicyCache,\n projection: writerProjection,\n resolveUserKey: resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n verifiedByHash: input.verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n input.onVerifiedAuthorization?.(authorization);\n }\n\n const staleContentKeyBundle = writerProjection.contentKeyBundleStale === true;\n if (staleContentKeyBundle && input.allowStaleContentKeyBundle !== true) {\n throw new Error(\"Document writer projection content-key bundle is stale\");\n }\n\n const manifestIdentity = await assertDocumentManifestBundleConsistent({\n bundle: writerProjection.documentManifest,\n label: \"Document writer projection manifest\",\n });\n const { documentId } = manifestIdentity;\n if (\n writerProjection.documentId !== documentId ||\n writerProjection.documentKekTargets.documentId !== documentId ||\n writerProjection.contentKeyBundle.documentId !== documentId\n ) {\n throw new Error(\"Document writer projection document id mismatch\");\n }\n if (\n writerProjection.documentKekTargets.linkSetManifestHash !==\n writerProjection.documentManifest.manifestHash\n ) {\n throw new Error(\"Document writer projection link manifest mismatch\");\n }\n await assertProjectionContentKeyBundleConsistent(\n writerProjection,\n staleContentKeyBundle,\n );\n\n const targets = staleContentKeyBundle\n ? normalizeDocumentKekTargetResponse(writerProjection.documentKekTargets)\n : currentDocumentTargets(writerProjection);\n const canonicalTargetHash =\n await computeDocumentContentKeyTargetHash(targets);\n if (\n canonicalTargetHash !==\n writerProjection.documentKekTargets.documentKeyTargetHash\n ) {\n throw new Error(\"Document writer projection target hash is not canonical\");\n }\n\n assertDocumentTargetsCoverLinkedContainers(targets, writerProjection);\n assertAuthorizingContainerPathsMatchDocumentTargets({\n targets,\n writerProjection,\n });\n\n return targets;\n}\n\nexport async function assertDocumentWriterProjectionConsistent(\n ...input: Parameters<typeof assertDocumentWriterProjectionConsistentInternal>\n): ReturnType<typeof assertDocumentWriterProjectionConsistentInternal> {\n try {\n return await assertDocumentWriterProjectionConsistentInternal(...input);\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ContentKeyEnvelopeKind, type VerifiedContainerAccessManifest } from "../../../internal/crypto/index.js";
|
|
2
2
|
import type { DocumentContentKeyTargetEnvelope } from "../../../internal/validators/request/index.js";
|
|
3
3
|
import type { ContainerWriterProjectionResponse, DocumentContentKeyBundleResponse, DocumentWriterProjectionResponse } from "../../../internal/validators/response/index.js";
|
|
4
|
-
import type { PrincipalPolicyCache } from "../../keyingProjectionVerification.js";
|
|
4
|
+
import type { PrincipalPolicyCache } from "../../keyingProjectionVerification/index.js";
|
|
5
5
|
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
6
6
|
import type { ProjectionVerificationOptions } from "./types.js";
|
|
7
7
|
export declare function wrapDocumentContentKeyForCreate(input: {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { readRecordNullableString, readRecordPositiveInteger, readRecordString, } from "../../recordReaders.js";
|
|
1
|
+
export { readRecordNullableString, readRecordPositiveInteger, readRecordString, } from "../../shared/recordReaders.js";
|
|
2
2
|
import { CONTENT_RECORD_ENCRYPTION_SUITE, compareCanonicalStrings, } from "../../../internal/crypto/index.js";
|
|
3
3
|
import { isPlainObject as isPlainRecord } from "../../../internal/validators/isPlainObject.js";
|
|
4
|
-
import { readCanonicalRecord } from "../../
|
|
5
|
-
import { readRecordInteger, readRecordPositiveInteger, readRecordString, readRecordValue, readStringArray, } from "../../recordReaders.js";
|
|
4
|
+
import { readCanonicalRecord } from "../../keying/canonicalJson.js";
|
|
5
|
+
import { readRecordInteger, readRecordPositiveInteger, readRecordString, readRecordValue, readStringArray, } from "../../shared/recordReaders.js";
|
|
6
6
|
export { assertDocumentManifestBundleConsistent, serializeCanonical, } from "./manifestBundleReaders.js";
|
|
7
7
|
function isContentObjectKind(value) {
|
|
8
8
|
return value === "blob" || value === "document";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readers.js","sourceRoot":"","sources":["readers.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n readRecordNullableString,\n readRecordPositiveInteger,\n readRecordString,\n} from \"../../recordReaders\";\n\nimport {\n CONTENT_RECORD_ENCRYPTION_SUITE,\n type ContainerKeyWrap,\n compareCanonicalStrings,\n type DocumentContentKeyTarget,\n type WriteHeader,\n} from \"@tearleads/crypto\";\nimport { isPlainObject as isPlainRecord } from \"@tearleads/validators/isPlainObject\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentCreateResponse,\n DocumentSyncResponse,\n} from \"@tearleads/validators/response\";\nimport { readCanonicalRecord } from \"../../keyingCanonicalJson\";\nimport {\n readRecordInteger,\n readRecordPositiveInteger,\n readRecordString,\n readRecordValue,\n readStringArray,\n} from \"../../recordReaders\";\n\nexport {\n assertDocumentManifestBundleConsistent,\n serializeCanonical,\n} from \"./manifestBundleReaders\";\n\nfunction isContentObjectKind(\n value: unknown,\n): value is WriteHeader[\"objectKind\"] {\n return value === \"blob\" || value === \"document\";\n}\n\nexport function readWriteHeader(value: unknown, label: string): WriteHeader {\n const record = readCanonicalRecord(value, label);\n const objectKind = readRecordValue(record, \"objectKind\");\n if (!isContentObjectKind(objectKind)) {\n throw new Error(`${label}.objectKind is invalid`);\n }\n if (readRecordInteger(record, \"version\", label) !== 1) {\n throw new Error(`${label}.version must be 1`);\n }\n const encryptionSuite = readRecordValue(record, \"encryptionSuite\");\n if (encryptionSuite !== CONTENT_RECORD_ENCRYPTION_SUITE) {\n throw new Error(`${label}.encryptionSuite is invalid`);\n }\n\n return {\n version: 1,\n dependencyManifestHashes: readStringArray(\n readRecordValue(record, \"dependencyManifestHashes\"),\n `${label}.dependencyManifestHashes`,\n ),\n organizationId: readRecordString(record, \"organizationId\", label),\n objectKind,\n objectId: readRecordString(record, \"objectId\", label),\n accessManifestHash: readRecordString(record, \"accessManifestHash\", label),\n contentKeyEpoch: readRecordPositiveInteger(\n record,\n \"contentKeyEpoch\",\n label,\n ),\n targetHash: readRecordString(record, \"targetHash\", label),\n encryptionSuite,\n contentRecordId: readRecordString(record, \"contentRecordId\", label),\n nonceDomainHash: readRecordString(record, \"nonceDomainHash\", label),\n metadataHash: readRecordString(record, \"metadataHash\", label),\n ciphertextHash: readRecordString(record, \"ciphertextHash\", label),\n writerUserId: readRecordString(record, \"writerUserId\", label),\n writerDeviceId: readRecordString(record, \"writerDeviceId\", label),\n writerKeyFingerprint: readRecordString(\n record,\n \"writerKeyFingerprint\",\n label,\n ),\n signedAt: readRecordString(record, \"signedAt\", label),\n signature: readRecordString(record, \"signature\", label),\n };\n}\n\nexport function readManifestContainerId(\n bundle: ContainerWriterProjectionResponse[\"path\"][number],\n): string | null {\n const containerId = isPlainRecord(bundle.state)\n ? Reflect.get(bundle.state, \"containerId\")\n : undefined;\n\n return typeof containerId === \"string\" && containerId.length > 0\n ? containerId\n : null;\n}\n\nexport function targetKey(target: DocumentContentKeyTarget): string {\n return [\n target.containerId,\n target.containerManifestHash,\n target.containerKeyEpochId,\n String(target.containerKeyEpoch),\n ].join(\":\");\n}\n\nexport function sortTargets<T>(\n targets: readonly T[],\n keyOf: (target: T) => string,\n): T[] {\n return [...targets].sort((left, right) =>\n compareCanonicalStrings(keyOf(left), keyOf(right)),\n );\n}\n\nexport function sortDocumentTargets<T extends DocumentContentKeyTarget>(\n targets: readonly T[],\n): T[] {\n return sortTargets(targets, targetKey);\n}\n\nexport function describeDocumentTargetKek(\n target: DocumentContentKeyTarget,\n): string {\n return `container ${target.containerId} epoch ${target.containerKeyEpochId}`;\n}\n\nexport function uniqueSortedStrings(values: readonly string[]): string[] {\n return [...new Set(values)].sort();\n}\n\nexport function asWebCryptoBytes(bytes: Uint8Array): Uint8Array<ArrayBuffer> {\n const buffer = bytes.buffer;\n if (!(buffer instanceof ArrayBuffer)) {\n throw new Error(\"Document byte material must be ArrayBuffer-backed\");\n }\n return new Uint8Array(buffer, bytes.byteOffset, bytes.byteLength);\n}\n\nexport function assertOnlyRecordKeys(\n record: Record<string, unknown>,\n allowedKeys: ReadonlySet<string>,\n label: string,\n): void {\n const unexpectedKeys = Object.keys(record).filter(\n (key) => !allowedKeys.has(key),\n );\n if (unexpectedKeys.length === 0) return;\n const named = unexpectedKeys\n .slice(0, 3)\n .map((key) => JSON.stringify(key.slice(0, 32)))\n .join(\",\");\n const remaining = unexpectedKeys.length - 3;\n throw new Error(\n `${label} has unexpected keys: ${named}${remaining > 0 ? ` and ${remaining} more` : \"\"}`,\n );\n}\n\nexport function normalizeContainerKeyWrap(value: unknown): ContainerKeyWrap {\n if (!isPlainRecord(value)) {\n throw new Error(\"Container writer projection KEK wrap is invalid\");\n }\n\n const recipientKind = readRecordString(\n value,\n \"recipientKind\",\n \"container KEK wrap\",\n );\n if (\n recipientKind !== \"user\" &&\n recipientKind !== \"group\" &&\n recipientKind !== \"container\"\n ) {\n throw new Error(\n \"Container writer projection KEK wrap recipient is invalid\",\n );\n }\n\n return {\n containerKeyEpochId: readRecordString(\n value,\n \"containerKeyEpochId\",\n \"container KEK wrap\",\n ),\n recipientKind,\n recipientId: readRecordString(value, \"recipientId\", \"container KEK wrap\"),\n recipientKeyEpochId: readRecordString(\n value,\n \"recipientKeyEpochId\",\n \"container KEK wrap\",\n ),\n recipientKeyFingerprint: readRecordString(\n value,\n \"recipientKeyFingerprint\",\n \"container KEK wrap\",\n ),\n kemCipherText: readRecordString(\n value,\n \"kemCipherText\",\n \"container KEK wrap\",\n ),\n wrappedKey: readRecordString(value, \"wrappedKey\", \"container KEK wrap\"),\n wrapManifestHash: readRecordString(\n value,\n \"wrapManifestHash\",\n \"container KEK wrap\",\n ),\n };\n}\n\nexport function assertEqualBytes(\n left: Uint8Array,\n right: Uint8Array,\n message: string,\n): void {\n let mismatch = left.byteLength ^ right.byteLength;\n const length = Math.max(left.byteLength, right.byteLength);\n for (let index = 0; index < length; index += 1) {\n mismatch |= (left[index] ?? 0) ^ (right[index] ?? 0);\n }\n\n if (mismatch !== 0) {\n throw new Error(message);\n }\n}\n\nfunction readDocumentTarget(\n value: Record<string, unknown>,\n label: string,\n): DocumentContentKeyTarget {\n return {\n containerId: readRecordString(value, \"containerId\", label),\n containerManifestHash: readRecordString(\n value,\n \"containerManifestHash\",\n label,\n ),\n containerKeyEpochId: readRecordString(value, \"containerKeyEpochId\", label),\n containerKeyEpoch: readRecordPositiveInteger(\n value,\n \"containerKeyEpoch\",\n label,\n ),\n };\n}\n\nexport function normalizeDocumentKekTargetResponse(\n targets: DocumentSyncResponse[\"documentKekTargets\"],\n): DocumentContentKeyTarget[] {\n return sortDocumentTargets(\n targets.targets.map((target, index) => {\n if (!isPlainRecord(target)) {\n throw new Error(`Document KEK target[${index}] is invalid`);\n }\n return readDocumentTarget(target, `Document KEK target[${index}]`);\n }),\n );\n}\n\nexport function targetEnvelopeReference(\n envelope: DocumentCreateResponse[\"contentKeyBundle\"][\"targets\"][number],\n): DocumentContentKeyTarget {\n return {\n containerId: envelope.containerId,\n containerManifestHash: envelope.containerManifestHash,\n containerKeyEpochId: envelope.containerKeyEpochId,\n containerKeyEpoch: envelope.containerKeyEpoch,\n };\n}\n\nfunction serializeState(value: unknown): string {\n return JSON.stringify(value);\n}\n\nexport function serializedPersistedDocumentState(input: {\n contentKeyBundle: unknown;\n documentId: string;\n documentKekTargets: unknown;\n documentManifestBundle: unknown;\n}): {\n contentKeyBundle: string;\n documentId: string;\n documentKekTargets: string;\n documentManifestBundle: string;\n} {\n return {\n documentId: input.documentId,\n contentKeyBundle: serializeState(input.contentKeyBundle),\n documentKekTargets: serializeState(input.documentKekTargets),\n documentManifestBundle: serializeState(input.documentManifestBundle),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"readers.js","sourceRoot":"","sources":["readers.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n readRecordNullableString,\n readRecordPositiveInteger,\n readRecordString,\n} from \"../../shared/recordReaders\";\n\nimport {\n CONTENT_RECORD_ENCRYPTION_SUITE,\n type ContainerKeyWrap,\n compareCanonicalStrings,\n type DocumentContentKeyTarget,\n type WriteHeader,\n} from \"@tearleads/crypto\";\nimport { isPlainObject as isPlainRecord } from \"@tearleads/validators/isPlainObject\";\nimport type {\n ContainerWriterProjectionResponse,\n DocumentCreateResponse,\n DocumentSyncResponse,\n} from \"@tearleads/validators/response\";\nimport { readCanonicalRecord } from \"../../keying/canonicalJson\";\nimport {\n readRecordInteger,\n readRecordPositiveInteger,\n readRecordString,\n readRecordValue,\n readStringArray,\n} from \"../../shared/recordReaders\";\n\nexport {\n assertDocumentManifestBundleConsistent,\n serializeCanonical,\n} from \"./manifestBundleReaders\";\n\nfunction isContentObjectKind(\n value: unknown,\n): value is WriteHeader[\"objectKind\"] {\n return value === \"blob\" || value === \"document\";\n}\n\nexport function readWriteHeader(value: unknown, label: string): WriteHeader {\n const record = readCanonicalRecord(value, label);\n const objectKind = readRecordValue(record, \"objectKind\");\n if (!isContentObjectKind(objectKind)) {\n throw new Error(`${label}.objectKind is invalid`);\n }\n if (readRecordInteger(record, \"version\", label) !== 1) {\n throw new Error(`${label}.version must be 1`);\n }\n const encryptionSuite = readRecordValue(record, \"encryptionSuite\");\n if (encryptionSuite !== CONTENT_RECORD_ENCRYPTION_SUITE) {\n throw new Error(`${label}.encryptionSuite is invalid`);\n }\n\n return {\n version: 1,\n dependencyManifestHashes: readStringArray(\n readRecordValue(record, \"dependencyManifestHashes\"),\n `${label}.dependencyManifestHashes`,\n ),\n organizationId: readRecordString(record, \"organizationId\", label),\n objectKind,\n objectId: readRecordString(record, \"objectId\", label),\n accessManifestHash: readRecordString(record, \"accessManifestHash\", label),\n contentKeyEpoch: readRecordPositiveInteger(\n record,\n \"contentKeyEpoch\",\n label,\n ),\n targetHash: readRecordString(record, \"targetHash\", label),\n encryptionSuite,\n contentRecordId: readRecordString(record, \"contentRecordId\", label),\n nonceDomainHash: readRecordString(record, \"nonceDomainHash\", label),\n metadataHash: readRecordString(record, \"metadataHash\", label),\n ciphertextHash: readRecordString(record, \"ciphertextHash\", label),\n writerUserId: readRecordString(record, \"writerUserId\", label),\n writerDeviceId: readRecordString(record, \"writerDeviceId\", label),\n writerKeyFingerprint: readRecordString(\n record,\n \"writerKeyFingerprint\",\n label,\n ),\n signedAt: readRecordString(record, \"signedAt\", label),\n signature: readRecordString(record, \"signature\", label),\n };\n}\n\nexport function readManifestContainerId(\n bundle: ContainerWriterProjectionResponse[\"path\"][number],\n): string | null {\n const containerId = isPlainRecord(bundle.state)\n ? Reflect.get(bundle.state, \"containerId\")\n : undefined;\n\n return typeof containerId === \"string\" && containerId.length > 0\n ? containerId\n : null;\n}\n\nexport function targetKey(target: DocumentContentKeyTarget): string {\n return [\n target.containerId,\n target.containerManifestHash,\n target.containerKeyEpochId,\n String(target.containerKeyEpoch),\n ].join(\":\");\n}\n\nexport function sortTargets<T>(\n targets: readonly T[],\n keyOf: (target: T) => string,\n): T[] {\n return [...targets].sort((left, right) =>\n compareCanonicalStrings(keyOf(left), keyOf(right)),\n );\n}\n\nexport function sortDocumentTargets<T extends DocumentContentKeyTarget>(\n targets: readonly T[],\n): T[] {\n return sortTargets(targets, targetKey);\n}\n\nexport function describeDocumentTargetKek(\n target: DocumentContentKeyTarget,\n): string {\n return `container ${target.containerId} epoch ${target.containerKeyEpochId}`;\n}\n\nexport function uniqueSortedStrings(values: readonly string[]): string[] {\n return [...new Set(values)].sort();\n}\n\nexport function asWebCryptoBytes(bytes: Uint8Array): Uint8Array<ArrayBuffer> {\n const buffer = bytes.buffer;\n if (!(buffer instanceof ArrayBuffer)) {\n throw new Error(\"Document byte material must be ArrayBuffer-backed\");\n }\n return new Uint8Array(buffer, bytes.byteOffset, bytes.byteLength);\n}\n\nexport function assertOnlyRecordKeys(\n record: Record<string, unknown>,\n allowedKeys: ReadonlySet<string>,\n label: string,\n): void {\n const unexpectedKeys = Object.keys(record).filter(\n (key) => !allowedKeys.has(key),\n );\n if (unexpectedKeys.length === 0) return;\n const named = unexpectedKeys\n .slice(0, 3)\n .map((key) => JSON.stringify(key.slice(0, 32)))\n .join(\",\");\n const remaining = unexpectedKeys.length - 3;\n throw new Error(\n `${label} has unexpected keys: ${named}${remaining > 0 ? ` and ${remaining} more` : \"\"}`,\n );\n}\n\nexport function normalizeContainerKeyWrap(value: unknown): ContainerKeyWrap {\n if (!isPlainRecord(value)) {\n throw new Error(\"Container writer projection KEK wrap is invalid\");\n }\n\n const recipientKind = readRecordString(\n value,\n \"recipientKind\",\n \"container KEK wrap\",\n );\n if (\n recipientKind !== \"user\" &&\n recipientKind !== \"group\" &&\n recipientKind !== \"container\"\n ) {\n throw new Error(\n \"Container writer projection KEK wrap recipient is invalid\",\n );\n }\n\n return {\n containerKeyEpochId: readRecordString(\n value,\n \"containerKeyEpochId\",\n \"container KEK wrap\",\n ),\n recipientKind,\n recipientId: readRecordString(value, \"recipientId\", \"container KEK wrap\"),\n recipientKeyEpochId: readRecordString(\n value,\n \"recipientKeyEpochId\",\n \"container KEK wrap\",\n ),\n recipientKeyFingerprint: readRecordString(\n value,\n \"recipientKeyFingerprint\",\n \"container KEK wrap\",\n ),\n kemCipherText: readRecordString(\n value,\n \"kemCipherText\",\n \"container KEK wrap\",\n ),\n wrappedKey: readRecordString(value, \"wrappedKey\", \"container KEK wrap\"),\n wrapManifestHash: readRecordString(\n value,\n \"wrapManifestHash\",\n \"container KEK wrap\",\n ),\n };\n}\n\nexport function assertEqualBytes(\n left: Uint8Array,\n right: Uint8Array,\n message: string,\n): void {\n let mismatch = left.byteLength ^ right.byteLength;\n const length = Math.max(left.byteLength, right.byteLength);\n for (let index = 0; index < length; index += 1) {\n mismatch |= (left[index] ?? 0) ^ (right[index] ?? 0);\n }\n\n if (mismatch !== 0) {\n throw new Error(message);\n }\n}\n\nfunction readDocumentTarget(\n value: Record<string, unknown>,\n label: string,\n): DocumentContentKeyTarget {\n return {\n containerId: readRecordString(value, \"containerId\", label),\n containerManifestHash: readRecordString(\n value,\n \"containerManifestHash\",\n label,\n ),\n containerKeyEpochId: readRecordString(value, \"containerKeyEpochId\", label),\n containerKeyEpoch: readRecordPositiveInteger(\n value,\n \"containerKeyEpoch\",\n label,\n ),\n };\n}\n\nexport function normalizeDocumentKekTargetResponse(\n targets: DocumentSyncResponse[\"documentKekTargets\"],\n): DocumentContentKeyTarget[] {\n return sortDocumentTargets(\n targets.targets.map((target, index) => {\n if (!isPlainRecord(target)) {\n throw new Error(`Document KEK target[${index}] is invalid`);\n }\n return readDocumentTarget(target, `Document KEK target[${index}]`);\n }),\n );\n}\n\nexport function targetEnvelopeReference(\n envelope: DocumentCreateResponse[\"contentKeyBundle\"][\"targets\"][number],\n): DocumentContentKeyTarget {\n return {\n containerId: envelope.containerId,\n containerManifestHash: envelope.containerManifestHash,\n containerKeyEpochId: envelope.containerKeyEpochId,\n containerKeyEpoch: envelope.containerKeyEpoch,\n };\n}\n\nfunction serializeState(value: unknown): string {\n return JSON.stringify(value);\n}\n\nexport function serializedPersistedDocumentState(input: {\n contentKeyBundle: unknown;\n documentId: string;\n documentKekTargets: unknown;\n documentManifestBundle: unknown;\n}): {\n contentKeyBundle: string;\n documentId: string;\n documentKekTargets: string;\n documentManifestBundle: string;\n} {\n return {\n documentId: input.documentId,\n contentKeyBundle: serializeState(input.contentKeyBundle),\n documentKekTargets: serializeState(input.documentKekTargets),\n documentManifestBundle: serializeState(input.documentManifestBundle),\n };\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { deriveStableUuidV4Shaped } from "../../stableUuid.js";
|
|
1
|
+
import { deriveStableUuidV4Shaped } from "../../keying/stableUuid.js";
|
|
2
2
|
// A namespace distinct from every other stable-id namespace (e.g. the system
|
|
3
3
|
// container namespace) so a document id derived from a local id never collides
|
|
4
4
|
// with an id derived from the same string in another domain.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stableDocumentId.js","sourceRoot":"","sources":["stableDocumentId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"stableDocumentId.js","sourceRoot":"","sources":["stableDocumentId.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,6EAA6E;AAC7E,+EAA+E;AAC/E,6DAA6D;AAC7D,MAAM,kCAAkC,GAAG,IAAI,UAAU,CAAC;IACxD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IAC5E,IAAI,EAAE,IAAI,EAAE,IAAI;CACjB,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,OAAO,wBAAwB,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;AAC/E,CAAC","sourcesContent":["import { deriveStableUuidV4Shaped } from \"../../keying/stableUuid\";\n\n// A namespace distinct from every other stable-id namespace (e.g. the system\n// container namespace) so a document id derived from a local id never collides\n// with an id derived from the same string in another domain.\nconst STABLE_DOCUMENT_ID_NAMESPACE_BYTES = new Uint8Array([\n 0x7a, 0x1c, 0x94, 0xe0, 0x5b, 0x63, 0x4e, 0x11, 0x9f, 0x2d, 0xa8, 0x74, 0x36,\n 0xc1, 0x0e, 0x52,\n]);\n\n/**\n * Derives the remote document id for a local document from its stable `localId`.\n *\n * Deriving (rather than generating a fresh `crypto.randomUUID()` per attempt)\n * makes the first remote create idempotent: if the server commits the create but\n * the response is lost, the retry re-sends the same id and the server reports a\n * conflict the client can adopt, instead of creating a second orphan document.\n */\nexport function deriveStableDocumentId(localId: string): Promise<string> {\n return deriveStableUuidV4Shaped(STABLE_DOCUMENT_ID_NAMESPACE_BYTES, localId);\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import type { AccessEvent, AccessManifest, DocumentContentKeyTarget, DocumentLin
|
|
|
3
3
|
import type { ContainerManifestRef, DocumentContentKeyTargetEnvelope, DocumentCreateRequest, DocumentLinkSetMutationRequest, DocumentOutgoingUpdate, DocumentSyncRequest } from "../../../internal/validators/request/index.js";
|
|
4
4
|
import type { ContainerWriterProjectionResponse, DocumentCreateResponse, DocumentLinkSetMutationResponse, DocumentPurgeProofResponse, DocumentSyncResponse, DocumentWriterProjectionResponse, ListDocumentAttachmentsResponse } from "../../../internal/validators/response/index.js";
|
|
5
5
|
import type { ContainerMutationAuthor, ContainerRekeyApi } from "../../containers/shared/types.js";
|
|
6
|
-
import type { ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer, DocumentWriterProjectionAuthorization as WriterAuthorization } from "../../keyingProjectionVerification.js";
|
|
6
|
+
import type { ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer, DocumentWriterProjectionAuthorization as WriterAuthorization } from "../../keyingProjectionVerification/index.js";
|
|
7
7
|
import type { DocumentRecord } from "../../sqlite/documentPersistence.js";
|
|
8
8
|
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
9
9
|
import type { DocumentSyncSubmitFailure } from "./syncSubmitFailure.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { requireProjectionUserKeyResolver } from "../../keyingProjectionVerification.js";
|
|
1
|
+
import { requireProjectionUserKeyResolver } from "../../keyingProjectionVerification/index.js";
|
|
2
2
|
export const DOCUMENT_ENCRYPTED_LORO_UPDATE_FORMAT = "tearleads.document.loro-update";
|
|
3
3
|
export const DOCUMENT_CONTENT_RECORD_KEY_INFO_DOMAIN = "tearleads.document.content-record-key-info";
|
|
4
4
|
export const DOCUMENT_CONTENT_RECORD_PLAINTEXT_HASH_KEY_INFO_DOMAIN = "tearleads.document.content-record-plaintext-hash-key-info";
|