@tearleads/client-sdk 0.1.14 → 0.1.15
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/client/containerContents.js +2 -1
- package/client/containerContents.js.map +1 -1
- package/data/documents/blob/shared/types.d.ts +4 -0
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js +2 -0
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +1 -1
- package/data/keyingProjectionVerification/checkpointContext.d.ts +2 -1
- package/data/keyingProjectionVerification/checkpointContext.js +22 -0
- package/data/keyingProjectionVerification/checkpointContext.js.map +1 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js +11 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerPathVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerProjectionVerification.d.ts +3 -2
- package/data/keyingProjectionVerification/containerProjectionVerification.js +10 -11
- package/data/keyingProjectionVerification/containerProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestPolicies.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentProjectionVerification.d.ts +2 -3
- package/data/keyingProjectionVerification/documentProjectionVerification.js +4 -0
- package/data/keyingProjectionVerification/documentProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js +14 -12
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/organizationFounderBinding.js.map +1 -1
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js +33 -6
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/projectionLifetimes.js +13 -0
- package/data/keyingProjectionVerification/projectionLifetimes.js.map +1 -0
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js +19 -66
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/types.d.ts +13 -2
- package/data/keyingProjectionVerification/types.js +15 -0
- package/data/keyingProjectionVerification/types.js.map +1 -1
- package/data/persistence/keyingCheckpointAdvancePersistence.js +4 -1
- package/data/persistence/keyingCheckpointAdvancePersistence.js.map +1 -1
- package/data/persistence/organizationFounderPersistence.js +2 -2
- package/data/persistence/organizationFounderPersistence.js.map +1 -1
- package/data/persistence/principalAuthorizationCheckpoints.js +29 -0
- package/data/persistence/principalAuthorizationCheckpoints.js.map +1 -0
- package/data/persistence/principalHistoryEvidencePersistence.d.ts +30 -0
- package/data/persistence/principalHistoryPrefixPersistence.d.ts +24 -0
- package/data/persistence/principalHistoryPrefixPersistence.js +6 -2
- package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
- package/data/persistence/principalHistoryStagePersistence.d.ts +21 -0
- package/data/principals/principalHistoryRuntime.js +12 -0
- package/data/principals/principalHistoryRuntime.js.map +1 -0
- package/data/principals/principalHistoryStageProtection.js +2 -12
- package/data/principals/principalHistoryStageProtection.js.map +1 -1
- package/data/principals/principalPolicyEvidence.d.ts +2 -2
- package/data/principals/principalPolicyEvidence.js.map +1 -1
- package/data/sqlite/principalHistoryEvidenceSchema.d.ts +308 -0
- package/data/sqlite/principalHistoryStageSchema.d.ts +119 -0
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/internal/api-client/ApiCache.d.ts +54 -0
- package/internal/api-client/ApiClient.d.ts +255 -309
- package/internal/api-client/ApiClient.js +15 -6
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/index.d.ts +1 -0
- package/internal/api-client/index.js.map +1 -1
- package/internal/api-client/principalHistoryDeadline.js +20 -0
- package/internal/api-client/principalHistoryDeadline.js.map +1 -0
- package/internal/api-client/principalHistoryRequest.js +59 -22
- package/internal/api-client/principalHistoryRequest.js.map +1 -1
- package/internal/api-client/principalHistoryRequestContext.js +18 -5
- package/internal/api-client/principalHistoryRequestContext.js.map +1 -1
- package/internal/api-client/principalPolicyRequests.d.ts +799 -0
- package/internal/api-client/principalPolicyRequests.js +9 -4
- package/internal/api-client/principalPolicyRequests.js.map +1 -1
- package/internal/api-client/projectionPolicyHistoryPages.d.ts +9 -0
- package/internal/api-client/projectionPolicyHistoryPages.js +88 -0
- package/internal/api-client/projectionPolicyHistoryPages.js.map +1 -0
- package/internal/api-client/writerProjectionRequests.js +26 -0
- package/internal/api-client/writerProjectionRequests.js.map +1 -0
- package/internal/crypto/keying/principalPolicyHistory.js +4 -0
- package/internal/crypto/keying/principalPolicyHistory.js.map +1 -1
- package/internal/crypto/keying/principalPolicyHistoryTypes.d.ts +2 -0
- package/internal/crypto/keying/principalPolicyHistoryTypes.js.map +1 -1
- package/internal/crypto/projectionHistorySlots.js +0 -4
- package/internal/crypto/projectionHistorySlots.js.map +1 -1
- package/internal/validators/operation/index.d.ts +1 -0
- package/internal/validators/operation/index.js +1 -0
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/principals.d.ts +38 -16
- package/internal/validators/operation/principals.js +11 -5
- package/internal/validators/operation/principals.js.map +1 -1
- package/internal/validators/operation/projectionPolicyHistory.d.ts +512 -0
- package/internal/validators/operation/projectionPolicyHistory.js +37 -0
- package/internal/validators/operation/projectionPolicyHistory.js.map +1 -0
- package/internal/validators/operation/registry.d.ts +2 -0
- package/internal/validators/operation/registry.js +2 -0
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/operation/writerProjections.d.ts +178 -1224
- package/internal/validators/operation/writerProjections.js +9 -2
- package/internal/validators/operation/writerProjections.js.map +1 -1
- package/internal/validators/response/container.d.ts +84 -612
- package/internal/validators/response/documentMutation.d.ts +84 -612
- package/internal/validators/response/index.d.ts +1 -0
- package/internal/validators/response/index.js +1 -0
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationBilling.d.ts +1 -0
- package/internal/validators/response/organizationBilling.js +1 -1
- package/internal/validators/response/organizationBilling.js.map +1 -1
- package/internal/validators/response/principalHistoryPreparation.js +28 -1
- package/internal/validators/response/principalHistoryPreparation.js.map +1 -1
- package/internal/validators/response/principalPolicySnapshotPage.d.ts +388 -0
- package/internal/validators/response/principalPolicySnapshotPage.js +24 -0
- package/internal/validators/response/principalPolicySnapshotPage.js.map +1 -0
- package/internal/validators/response/projectionPolicyEvidence.d.ts +85 -613
- package/internal/validators/response/projectionPolicyEvidence.js +10 -5
- package/internal/validators/response/projectionPolicyEvidence.js.map +1 -1
- package/package.json +1 -1
- package/stores/documents/documentStore/attachmentHydration.js +3 -0
- package/stores/documents/documentStore/attachmentHydration.js.map +1 -1
- package/stores/documents/documentStore/syncDetachedAttachments.js +3 -0
- package/stores/documents/documentStore/syncDetachedAttachments.js.map +1 -1
- package/workflows/blobs/decrypt.d.ts +1 -1
- package/workflows/blobs/decrypt.js +3 -1
- package/workflows/blobs/decrypt.js.map +1 -1
- package/workflows/blobs/detach.js +6 -1
- package/workflows/blobs/detach.js.map +1 -1
- package/workflows/blobs/hydrate.d.ts +3 -1
- package/workflows/blobs/hydrate.js +2 -0
- package/workflows/blobs/hydrate.js.map +1 -1
- package/workflows/blobs/retainedAttachmentVerification.js +2 -0
- package/workflows/blobs/retainedAttachmentVerification.js.map +1 -1
- package/workflows/container-contents/container-state/createAdoption.js +2 -0
- package/workflows/container-contents/container-state/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/createWithMetadata.js +7 -39
- package/workflows/container-contents/container-state/createWithMetadata.js.map +1 -1
- package/workflows/container-contents/container-state/createWithMetadataPlan.js +68 -0
- package/workflows/container-contents/container-state/createWithMetadataPlan.js.map +1 -0
- package/workflows/container-contents/remoteContainerState.js +3 -1
- package/workflows/container-contents/remoteContainerState.js.map +1 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js +3 -0
- package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +1 -1
- package/workflows/container-contents/runtime.d.ts +3 -0
- package/workflows/container-contents/runtime.js +7 -6
- package/workflows/container-contents/runtime.js.map +1 -1
- package/workflows/documents/create.d.ts +2 -15
- package/workflows/documents/create.js +9 -64
- package/workflows/documents/create.js.map +1 -1
- package/workflows/documents/createProjection.d.ts +14 -0
- package/workflows/documents/createProjection.js +26 -0
- package/workflows/documents/createProjection.js.map +1 -0
- package/workflows/documents/createResponse.js +49 -0
- package/workflows/documents/createResponse.js.map +1 -0
- package/workflows/documents/linkSetBlobRewraps.js +2 -0
- package/workflows/documents/linkSetBlobRewraps.js.map +1 -1
- package/workflows/documents/runtime.d.ts +3 -0
- package/workflows/documents/runtime.js +3 -2
- package/workflows/documents/runtime.js.map +1 -1
- package/workflows/documents/syncFailureClassification.js +3 -1
- package/workflows/documents/syncFailureClassification.js.map +1 -1
- package/workflows/principals/index.d.ts +2 -0
- package/workflows/principals/index.js +1 -0
- package/workflows/principals/index.js.map +1 -1
- package/workflows/principals/policyVerification.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryAuthority.js +20 -0
- package/workflows/principals/principalHistoryRecoveryAuthority.js.map +1 -0
- package/workflows/principals/principalHistoryRecoveryStage.js +1 -1
- package/workflows/principals/principalHistoryRecoveryStage.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryTypes.d.ts +3 -3
- package/workflows/principals/principalHistoryRecoveryTypes.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryVerification.js +6 -1
- package/workflows/principals/principalHistoryRecoveryVerification.js.map +1 -1
- package/workflows/principals/principalRecoveryOutage.js +1 -1
- package/workflows/principals/principalRecoveryOutage.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryAuthority.js +60 -0
- package/workflows/principals/publicPrincipalHistoryAuthority.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryPage.js +87 -0
- package/workflows/principals/publicPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js +178 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryTypes.d.ts +39 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js +2 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -0
- package/workflows/principals/publicProjectionDirectory.js +40 -0
- package/workflows/principals/publicProjectionDirectory.js.map +1 -0
- package/workflows/principals/publicProjectionPrincipal.js +53 -0
- package/workflows/principals/publicProjectionPrincipal.js.map +1 -0
- package/workflows/principals/recoverPrincipalPolicyHistory.js +4 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/recoverProjectionPolicyHistory.d.ts +9 -0
- package/workflows/principals/recoverProjectionPolicyHistory.js +98 -0
- package/workflows/principals/recoverProjectionPolicyHistory.js.map +1 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js +176 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -0
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +2 -5
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js +2 -1
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimePolicyWarmer.js +2 -0
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
- package/workflows/principals/runtimeProjectionPolicyRecovery.js +56 -0
- package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -0
- package/workflows/principals/selectPublicPrincipalHistory.js +90 -0
- package/workflows/principals/selectPublicPrincipalHistory.js.map +1 -0
- package/workflows/registration/provisioningBootstrapBuilders.d.ts +21 -153
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verifiedDestination.js","sourceRoot":"","sources":["verifiedDestination.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { deriveOrganizationMetadataContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport {\n type HeldContainerBinding,\n listingRepeatsHeldOrdinaryBinding,\n} from \"../../../data/containers/containerBinding\";\nimport { verifiedContainerCreateManifest } from \"../../../data/keyingProjectionVerification/containerCreateManifest\";\nimport { verifyContainerDestinationProjection } from \"../../../data/keyingProjectionVerification/containerDestinationVerification\";\nimport { verifyContainerWriterProjection } from \"../../../data/keyingProjectionVerification/containerProjectionVerification\";\nimport {\n isKeyingVerificationError,\n reportKeyingVerificationErrorInCauseChain,\n runWithSecurityIncidentReporting,\n} from \"../../../data/keyingProjectionVerification/error\";\nimport { createGroupMetadataContainerVerifier } from \"../../organizations/groupMetadataContainerAuthority\";\nimport type { PrefetchedDestinationProjection } from \"./destinationPrefetch\";\nimport {\n cachedDestinationRole,\n type DestinationRole,\n rememberDestinationRole,\n} from \"./destinationRoleCache\";\nimport { resolveWithMetadataRootReload } from \"./destinationRootReload\";\nimport { assertPermittedDestinationBinding } from \"./replacementBinding\";\nimport type {\n ContainerState,\n RemoteContainer,\n RemoteContainerHydrationState,\n} from \"./types\";\n\n/** The identity a role is verified and cached under. */\ntype DestinationIdentity = Pick<RemoteContainer, \"id\" | \"organizationId\">;\n\nasync function destinationRoleFromPath(input: {\n listed: DestinationIdentity;\n path: readonly VerifiedContainerAccessManifest[];\n verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n}): Promise<{ role: DestinationRole; parentId: string | null }> {\n const { listed, path } = input;\n const head = path.at(-1);\n if (\n !head ||\n head.state.containerId !== listed.id ||\n head.state.organizationId !== listed.organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"container destination manifest has the wrong identity\",\n );\n }\n const metadataSlot = await deriveOrganizationMetadataContainerSystemSlot({\n organizationId: listed.organizationId,\n });\n if (\n head.state.systemSlot !== null &&\n path.length !== (head.state.systemSlot === metadataSlot ? 1 : 2)\n ) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"system destination has the wrong signed topology\",\n );\n }\n // The head may be a later grant signed by any admin; only the epoch-1\n // create names the creator, and roots are always created by the org owner.\n const created = verifiedContainerCreateManifest({\n head,\n label: \"Container destination\",\n verifiedByHash: input.verifiedByHash,\n });\n const root = path[0];\n if (!root) throw new Error(\"Destination root is unavailable\");\n const rootCreated = verifiedContainerCreateManifest({\n head: root,\n label: \"Destination root\",\n verifiedByHash: input.verifiedByHash,\n });\n return {\n parentId: head.state.parentContainerId,\n role: {\n createSignerUserId: created.event.event.signerUserId,\n rootContainerId: rootCreated.state.containerId,\n rootCreateManifestHash: rootCreated.manifestHash,\n rootMetadataDocumentId: rootCreated.state.metadataDocumentId,\n metadataDocumentId: head.state.metadataDocumentId,\n ...(head.state.parentContainerId === null ||\n head.state.systemSlot !== null\n ? { parentId: head.state.parentContainerId }\n : {}),\n systemSlot: head.state.systemSlot,\n },\n };\n}\n\n/**\n * The session's root id arrives in an unsigned login response, so the root it\n * names must prove it belongs to this user: every acknowledged organization was\n * created by the session user, whose device signed the root's `container.create`.\n * A verified root created by anyone else is a substitution, never the merge\n * target for pre-login local content, whatever grants it carries. The check\n * runs on cache reuse too, since the cache is not scoped to the session user.\n */\nfunction assertRootCreatedBySessionUser(\n role: DestinationRole,\n runtime: RemoteContainerHydrationState[\"runtime\"],\n): void {\n if (role.systemSlot !== null) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"acknowledged session root cannot be a system container\",\n );\n }\n if (role.createSignerUserId !== runtime.auth.userId) {\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"acknowledged session root was not created by the session user\",\n );\n }\n}\n\nfunction assertAcknowledgedRootSigner(input: {\n listed: DestinationIdentity;\n role: DestinationRole;\n runtime: RemoteContainerHydrationState[\"runtime\"];\n}): void {\n const { listed, role, runtime } = input;\n if (role.parentId !== null || listed.id !== runtime.auth.rootContainerId) {\n return;\n }\n assertRootCreatedBySessionUser(role, runtime);\n}\n\n/**\n * Authenticate destination roles before admitting a binding or advancing any\n * placement pin. Shared rehomes additionally require signed replacement evidence.\n */\nasync function verifyDestinationRole(input: {\n heldBinding: HeldContainerBinding | null;\n prefetched: PrefetchedDestinationProjection | undefined;\n verifyCurrentPlacement: boolean;\n onVerifiedCheckpoint:\n | ((checkpoint: AccessManifestCheckpoint) => void)\n | undefined;\n isCurrent?: (() => boolean) | undefined;\n listed: DestinationIdentity;\n runtime: RemoteContainerHydrationState[\"runtime\"];\n}): Promise<{ role: DestinationRole; parentId: string | null } | null> {\n const { isCurrent, listed, runtime } = input;\n const projection = input.prefetched\n ? input.prefetched.projection\n : await runtime.apiClient.getContainerWriterProjection(listed.id);\n if (!projection || isCurrent?.() === false) return null;\n if (\n projection.containerId !== listed.id ||\n projection.organizationId !== listed.organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"container destination projection has the wrong identity\",\n );\n }\n const verificationInput = {\n execSql: runtime.infra.execSql,\n projection,\n resolveUserKey: runtime.resolveTrustedUserIdentity,\n };\n const { path, verifiedByHash } =\n await verifyContainerDestinationProjection(verificationInput);\n if (isCurrent?.() === false) return null;\n const destination = await destinationRoleFromPath({\n listed,\n path,\n verifiedByHash,\n });\n const { role } = destination;\n // Refuse a rebinding before group checks or placement pins run for it.\n await assertPermittedDestinationBinding({\n stillCurrent: isCurrent,\n heldBinding: input.heldBinding,\n listed,\n role,\n runtime,\n });\n if (isCurrent?.() === false) return null;\n if (role.parentId === null && role.systemSlot !== null) {\n const head = path.at(-1);\n if (!head) throw new Error(\"Metadata root manifest is unavailable\");\n await createGroupMetadataContainerVerifier({\n apiClient: runtime.apiClient,\n execSql: runtime.infra.execSql,\n organizationId: listed.organizationId,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n stillCurrent: isCurrent ?? (() => true),\n })(head.state);\n }\n if (isCurrent?.() === false) return null;\n if (input.verifyCurrentPlacement) {\n // Check the immutable role before allowing current placement to advance pins.\n assertAcknowledgedRootSigner({ listed, role, runtime });\n const currentPath = await verifyContainerWriterProjection({\n ...verificationInput,\n stillCurrent: isCurrent,\n });\n const currentHead = currentPath.at(-1);\n if (!currentHead)\n throw new Error(\"Recovery placement manifest is unavailable\");\n input.onVerifiedCheckpoint?.(currentHead.checkpoint);\n }\n if (isCurrent?.() === false) return null;\n return destination;\n}\n\ntype VerifyRemoteContainerDestinationInput = {\n heldBinding: HeldContainerBinding | null;\n /** The held folder was re-homed away from the listed organization. */\n supersededListing?: boolean | undefined;\n /** Fetched ahead by page hydration; ignored when placement is refreshed. */\n prefetchedProjection?: PrefetchedDestinationProjection | undefined;\n refresh?: boolean;\n onVerifiedCheckpoint?:\n | ((checkpoint: AccessManifestCheckpoint) => void)\n | undefined;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n isCurrent?: (() => boolean) | undefined;\n};\n\n/** A cached immutable role, or a freshly verified one with its signed parent. */\nasync function resolveDestinationRole(\n input: VerifyRemoteContainerDestinationInput,\n): Promise<{\n freshlyVerified: boolean;\n parentId: string | null | undefined;\n role: DestinationRole;\n} | null> {\n const { remoteContainer: listed, isCurrent } = input;\n const runtime = input.state.runtime;\n const cached = input.refresh\n ? undefined\n : cachedDestinationRole(runtime.infra.execSql, listed);\n // Ordinary parent edges are not immutable. A refresh authenticates current\n // placement; a forged root hint must also be corrected from a signed path.\n if (cached && !(cached.parentId === undefined && listed.parentId === null)) {\n return { freshlyVerified: false, parentId: cached.parentId, role: cached };\n }\n const verified = await verifyDestinationRole({\n heldBinding: input.heldBinding,\n prefetched: input.refresh ? undefined : input.prefetchedProjection,\n isCurrent,\n listed,\n runtime,\n verifyCurrentPlacement: input.refresh === true,\n onVerifiedCheckpoint: input.onVerifiedCheckpoint,\n });\n if (!verified) return null;\n return {\n freshlyVerified: true,\n parentId:\n input.refresh || listed.parentId === null\n ? verified.parentId\n : verified.role.parentId,\n role: verified.role,\n };\n}\n\n/**\n * Listing hints never establish a metadata target or a system/root role, and a\n * held folder keeps its organization and metadata target unless its own user\n * re-created it or its pinned founder authorized a verified replacement.\n * A conflicting proof is refused before placement pins\n * advance or its role is cached.\n */\nexport async function verifyRemoteContainerDestination(\n input: VerifyRemoteContainerDestinationInput,\n): Promise<RemoteContainer | null> {\n const { remoteContainer: listed, state, isCurrent } = input;\n const runtime = state.runtime;\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: listed.id,\n objectKind: \"container\",\n operation: \"container.destination.verify\",\n organizationId: listed.organizationId,\n },\n async () => {\n if (input.supersededListing) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"container was re-homed away from the listed organization\",\n );\n }\n // A held ordinary binding was verified (or signed by this device) when\n // it was stored; a listing that repeats it needs no second proof.\n if (\n !input.refresh &&\n listingRepeatsHeldOrdinaryBinding(input.heldBinding, listed)\n ) {\n return { ...listed, systemSlot: null };\n }\n if (input.refresh)\n runtime.apiClient.evictContainerWriterProjection(listed.id);\n // A metadata root read before a reserved-group commit is reloaded once.\n const resolved = await resolveWithMetadataRootReload(\n input,\n resolveDestinationRole,\n () => runtime.apiClient.evictContainerWriterProjection(listed.id),\n ).catch((error: unknown) => {\n // Never re-serve a cached projection that failed verification.\n if (isKeyingVerificationError(error))\n runtime.apiClient.evictContainerWriterProjection(listed.id);\n throw error;\n });\n if (!resolved || isCurrent?.() === false) return null;\n const { role, parentId } = resolved;\n // Fresh verification checked this binding before any placement pins.\n // A cached role still needs the held binding and replacement proof checked.\n if (!resolved.freshlyVerified)\n await assertPermittedDestinationBinding({\n stillCurrent: isCurrent,\n heldBinding: input.heldBinding,\n listed,\n role,\n runtime,\n });\n if (isCurrent?.() === false) return null;\n if (resolved.freshlyVerified)\n rememberDestinationRole(runtime.infra.execSql, listed, role);\n assertAcknowledgedRootSigner({ listed, role, runtime });\n return {\n ...listed,\n metadataDocumentId: role.metadataDocumentId,\n parentId: parentId === undefined ? listed.parentId : parentId,\n systemSlot: role.systemSlot,\n };\n },\n );\n}\n\n/** The root the unsigned login answer named, in the expected organization. */\nexport function isSessionRootState(\n remoteRootState: ContainerState,\n state: RemoteContainerHydrationState,\n): boolean {\n const { container } = remoteRootState;\n const { auth } = state.runtime;\n return (\n container.parentId === null &&\n !container.systemSlot &&\n container.id === auth.rootContainerId &&\n container.organizationId === auth.organizationId\n );\n}\n\n/**\n * Whether the session root may absorb the pre-login local roots. The unsigned\n * login answer only names the root; the merge target must also be the verified\n * root whose epoch-1 `container.create` the session user signed. A row persisted\n * earlier as an ordinary shared container (another user's root this device once\n * hydrated) never passed that check for this session, so the creator is checked\n * here, at the reconciliation boundary itself, before any local content is\n * re-parented. The role comes only from the cache remote hydration fills when\n * it verifies the destination: this gate never fetches, so a local refresh stays\n * independent of the network. Without a cached role the merge is left pending\n * (no incident) until hydration verifies the root and reconciles from the\n * cache. A different creator is a `signer_mismatch` incident and never a merge;\n * the refusal is the \"no merge\" outcome, so the refresh that carried it\n * completes with the local content left in place.\n */\nexport async function isVerifiedLocalRootReconciliationTarget(input: {\n remoteRootState: ContainerState;\n state: RemoteContainerHydrationState;\n}): Promise<boolean> {\n const { remoteRootState, state } = input;\n const { container } = remoteRootState;\n const runtime = state.runtime;\n if (!isSessionRootState(remoteRootState, state)) return false;\n const role = cachedDestinationRole(runtime.infra.execSql, container);\n if (!role) return false;\n try {\n if (role.parentId !== null) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"session root reconciliation target is not a verified root\",\n );\n }\n assertRootCreatedBySessionUser(role, runtime);\n return true;\n } catch (error) {\n const reported = await reportKeyingVerificationErrorInCauseChain(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: container.id,\n objectKind: \"container\",\n operation: \"container.root.reconcile\",\n organizationId: container.organizationId,\n },\n );\n if (!reported) throw error;\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"verifiedDestination.js","sourceRoot":"","sources":["verifiedDestination.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { deriveOrganizationMetadataContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport {\n type HeldContainerBinding,\n listingRepeatsHeldOrdinaryBinding,\n} from \"../../../data/containers/containerBinding\";\nimport { verifiedContainerCreateManifest } from \"../../../data/keyingProjectionVerification/containerCreateManifest\";\nimport { verifyContainerDestinationProjection } from \"../../../data/keyingProjectionVerification/containerDestinationVerification\";\nimport { verifyContainerWriterProjection } from \"../../../data/keyingProjectionVerification/containerProjectionVerification\";\nimport {\n isKeyingVerificationError,\n reportKeyingVerificationErrorInCauseChain,\n runWithSecurityIncidentReporting,\n} from \"../../../data/keyingProjectionVerification/error\";\nimport { createGroupMetadataContainerVerifier } from \"../../organizations/groupMetadataContainerAuthority\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../principals/runtimePolicyWarmer\";\nimport type { PrefetchedDestinationProjection } from \"./destinationPrefetch\";\nimport {\n cachedDestinationRole,\n type DestinationRole,\n rememberDestinationRole,\n} from \"./destinationRoleCache\";\nimport { resolveWithMetadataRootReload } from \"./destinationRootReload\";\nimport { assertPermittedDestinationBinding } from \"./replacementBinding\";\nimport type {\n ContainerState,\n RemoteContainer,\n RemoteContainerHydrationState,\n} from \"./types\";\n\n/** The identity a role is verified and cached under. */\ntype DestinationIdentity = Pick<RemoteContainer, \"id\" | \"organizationId\">;\n\nasync function destinationRoleFromPath(input: {\n listed: DestinationIdentity;\n path: readonly VerifiedContainerAccessManifest[];\n verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n}): Promise<{ role: DestinationRole; parentId: string | null }> {\n const { listed, path } = input;\n const head = path.at(-1);\n if (\n !head ||\n head.state.containerId !== listed.id ||\n head.state.organizationId !== listed.organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"container destination manifest has the wrong identity\",\n );\n }\n const metadataSlot = await deriveOrganizationMetadataContainerSystemSlot({\n organizationId: listed.organizationId,\n });\n if (\n head.state.systemSlot !== null &&\n path.length !== (head.state.systemSlot === metadataSlot ? 1 : 2)\n ) {\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"system destination has the wrong signed topology\",\n );\n }\n // The head may be a later grant signed by any admin; only the epoch-1\n // create names the creator, and roots are always created by the org owner.\n const created = verifiedContainerCreateManifest({\n head,\n label: \"Container destination\",\n verifiedByHash: input.verifiedByHash,\n });\n const root = path[0];\n if (!root) throw new Error(\"Destination root is unavailable\");\n const rootCreated = verifiedContainerCreateManifest({\n head: root,\n label: \"Destination root\",\n verifiedByHash: input.verifiedByHash,\n });\n return {\n parentId: head.state.parentContainerId,\n role: {\n createSignerUserId: created.event.event.signerUserId,\n rootContainerId: rootCreated.state.containerId,\n rootCreateManifestHash: rootCreated.manifestHash,\n rootMetadataDocumentId: rootCreated.state.metadataDocumentId,\n metadataDocumentId: head.state.metadataDocumentId,\n ...(head.state.parentContainerId === null ||\n head.state.systemSlot !== null\n ? { parentId: head.state.parentContainerId }\n : {}),\n systemSlot: head.state.systemSlot,\n },\n };\n}\n\n/**\n * The session's root id arrives in an unsigned login response, so the root it\n * names must prove it belongs to this user: every acknowledged organization was\n * created by the session user, whose device signed the root's `container.create`.\n * A verified root created by anyone else is a substitution, never the merge\n * target for pre-login local content, whatever grants it carries. The check\n * runs on cache reuse too, since the cache is not scoped to the session user.\n */\nfunction assertRootCreatedBySessionUser(\n role: DestinationRole,\n runtime: RemoteContainerHydrationState[\"runtime\"],\n): void {\n if (role.systemSlot !== null) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"acknowledged session root cannot be a system container\",\n );\n }\n if (role.createSignerUserId !== runtime.auth.userId) {\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"acknowledged session root was not created by the session user\",\n );\n }\n}\n\nfunction assertAcknowledgedRootSigner(input: {\n listed: DestinationIdentity;\n role: DestinationRole;\n runtime: RemoteContainerHydrationState[\"runtime\"];\n}): void {\n const { listed, role, runtime } = input;\n if (role.parentId !== null || listed.id !== runtime.auth.rootContainerId) {\n return;\n }\n assertRootCreatedBySessionUser(role, runtime);\n}\n\n/**\n * Authenticate destination roles before admitting a binding or advancing any\n * placement pin. Shared rehomes additionally require signed replacement evidence.\n */\nasync function verifyDestinationRole(input: {\n heldBinding: HeldContainerBinding | null;\n prefetched: PrefetchedDestinationProjection | undefined;\n verifyCurrentPlacement: boolean;\n onVerifiedCheckpoint:\n | ((checkpoint: AccessManifestCheckpoint) => void)\n | undefined;\n isCurrent?: (() => boolean) | undefined;\n listed: DestinationIdentity;\n runtime: RemoteContainerHydrationState[\"runtime\"];\n}): Promise<{ role: DestinationRole; parentId: string | null } | null> {\n const { isCurrent, listed, runtime } = input;\n const projection = input.prefetched\n ? input.prefetched.projection\n : await runtime.apiClient.getContainerWriterProjection(listed.id);\n if (!projection || isCurrent?.() === false) return null;\n if (\n projection.containerId !== listed.id ||\n projection.organizationId !== listed.organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"container destination projection has the wrong identity\",\n );\n }\n const verificationInput = {\n execSql: runtime.infra.execSql,\n projection,\n resolveUserKey: runtime.resolveTrustedUserIdentity,\n stillCurrent: isCurrent,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(runtime),\n };\n const { path, verifiedByHash } =\n await verifyContainerDestinationProjection(verificationInput);\n if (isCurrent?.() === false) return null;\n const destination = await destinationRoleFromPath({\n listed,\n path,\n verifiedByHash,\n });\n const { role } = destination;\n // Refuse a rebinding before group checks or placement pins run for it.\n await assertPermittedDestinationBinding({\n stillCurrent: isCurrent,\n heldBinding: input.heldBinding,\n listed,\n role,\n runtime,\n });\n if (isCurrent?.() === false) return null;\n if (role.parentId === null && role.systemSlot !== null) {\n const head = path.at(-1);\n if (!head) throw new Error(\"Metadata root manifest is unavailable\");\n await createGroupMetadataContainerVerifier({\n apiClient: runtime.apiClient,\n execSql: runtime.infra.execSql,\n organizationId: listed.organizationId,\n reportSecurityIncident: runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n stillCurrent: isCurrent ?? (() => true),\n })(head.state);\n }\n if (isCurrent?.() === false) return null;\n if (input.verifyCurrentPlacement) {\n // Check the immutable role before allowing current placement to advance pins.\n assertAcknowledgedRootSigner({ listed, role, runtime });\n const currentPath = await verifyContainerWriterProjection({\n ...verificationInput,\n stillCurrent: isCurrent,\n });\n const currentHead = currentPath.at(-1);\n if (!currentHead)\n throw new Error(\"Recovery placement manifest is unavailable\");\n input.onVerifiedCheckpoint?.(currentHead.checkpoint);\n }\n if (isCurrent?.() === false) return null;\n return destination;\n}\n\ntype VerifyRemoteContainerDestinationInput = {\n heldBinding: HeldContainerBinding | null;\n /** The held folder was re-homed away from the listed organization. */\n supersededListing?: boolean | undefined;\n /** Fetched ahead by page hydration; ignored when placement is refreshed. */\n prefetchedProjection?: PrefetchedDestinationProjection | undefined;\n refresh?: boolean;\n onVerifiedCheckpoint?:\n | ((checkpoint: AccessManifestCheckpoint) => void)\n | undefined;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n isCurrent?: (() => boolean) | undefined;\n};\n\n/** A cached immutable role, or a freshly verified one with its signed parent. */\nasync function resolveDestinationRole(\n input: VerifyRemoteContainerDestinationInput,\n): Promise<{\n freshlyVerified: boolean;\n parentId: string | null | undefined;\n role: DestinationRole;\n} | null> {\n const { remoteContainer: listed, isCurrent } = input;\n const runtime = input.state.runtime;\n const cached = input.refresh\n ? undefined\n : cachedDestinationRole(runtime.infra.execSql, listed);\n // Ordinary parent edges are not immutable. A refresh authenticates current\n // placement; a forged root hint must also be corrected from a signed path.\n if (cached && !(cached.parentId === undefined && listed.parentId === null)) {\n return { freshlyVerified: false, parentId: cached.parentId, role: cached };\n }\n const verified = await verifyDestinationRole({\n heldBinding: input.heldBinding,\n prefetched: input.refresh ? undefined : input.prefetchedProjection,\n isCurrent,\n listed,\n runtime,\n verifyCurrentPlacement: input.refresh === true,\n onVerifiedCheckpoint: input.onVerifiedCheckpoint,\n });\n if (!verified) return null;\n return {\n freshlyVerified: true,\n parentId:\n input.refresh || listed.parentId === null\n ? verified.parentId\n : verified.role.parentId,\n role: verified.role,\n };\n}\n\n/**\n * Listing hints never establish a metadata target or a system/root role, and a\n * held folder keeps its organization and metadata target unless its own user\n * re-created it or its pinned founder authorized a verified replacement.\n * A conflicting proof is refused before placement pins\n * advance or its role is cached.\n */\nexport async function verifyRemoteContainerDestination(\n input: VerifyRemoteContainerDestinationInput,\n): Promise<RemoteContainer | null> {\n const { remoteContainer: listed, state, isCurrent } = input;\n const runtime = state.runtime;\n return runWithSecurityIncidentReporting(\n runtime.util.reportSecurityIncident,\n {\n objectId: listed.id,\n objectKind: \"container\",\n operation: \"container.destination.verify\",\n organizationId: listed.organizationId,\n },\n async () => {\n if (input.supersededListing) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"container was re-homed away from the listed organization\",\n );\n }\n // A held ordinary binding was verified (or signed by this device) when\n // it was stored; a listing that repeats it needs no second proof.\n if (\n !input.refresh &&\n listingRepeatsHeldOrdinaryBinding(input.heldBinding, listed)\n ) {\n return { ...listed, systemSlot: null };\n }\n if (input.refresh)\n runtime.apiClient.evictContainerWriterProjection(listed.id);\n // A metadata root read before a reserved-group commit is reloaded once.\n const resolved = await resolveWithMetadataRootReload(\n input,\n resolveDestinationRole,\n () => runtime.apiClient.evictContainerWriterProjection(listed.id),\n ).catch((error: unknown) => {\n // Never re-serve a cached projection that failed verification.\n if (isKeyingVerificationError(error))\n runtime.apiClient.evictContainerWriterProjection(listed.id);\n throw error;\n });\n if (!resolved || isCurrent?.() === false) return null;\n const { role, parentId } = resolved;\n // Fresh verification checked this binding before any placement pins.\n // A cached role still needs the held binding and replacement proof checked.\n if (!resolved.freshlyVerified)\n await assertPermittedDestinationBinding({\n stillCurrent: isCurrent,\n heldBinding: input.heldBinding,\n listed,\n role,\n runtime,\n });\n if (isCurrent?.() === false) return null;\n if (resolved.freshlyVerified)\n rememberDestinationRole(runtime.infra.execSql, listed, role);\n assertAcknowledgedRootSigner({ listed, role, runtime });\n return {\n ...listed,\n metadataDocumentId: role.metadataDocumentId,\n parentId: parentId === undefined ? listed.parentId : parentId,\n systemSlot: role.systemSlot,\n };\n },\n );\n}\n\n/** The root the unsigned login answer named, in the expected organization. */\nexport function isSessionRootState(\n remoteRootState: ContainerState,\n state: RemoteContainerHydrationState,\n): boolean {\n const { container } = remoteRootState;\n const { auth } = state.runtime;\n return (\n container.parentId === null &&\n !container.systemSlot &&\n container.id === auth.rootContainerId &&\n container.organizationId === auth.organizationId\n );\n}\n\n/**\n * Whether the session root may absorb the pre-login local roots. The unsigned\n * login answer only names the root; the merge target must also be the verified\n * root whose epoch-1 `container.create` the session user signed. A row persisted\n * earlier as an ordinary shared container (another user's root this device once\n * hydrated) never passed that check for this session, so the creator is checked\n * here, at the reconciliation boundary itself, before any local content is\n * re-parented. The role comes only from the cache remote hydration fills when\n * it verifies the destination: this gate never fetches, so a local refresh stays\n * independent of the network. Without a cached role the merge is left pending\n * (no incident) until hydration verifies the root and reconciles from the\n * cache. A different creator is a `signer_mismatch` incident and never a merge;\n * the refusal is the \"no merge\" outcome, so the refresh that carried it\n * completes with the local content left in place.\n */\nexport async function isVerifiedLocalRootReconciliationTarget(input: {\n remoteRootState: ContainerState;\n state: RemoteContainerHydrationState;\n}): Promise<boolean> {\n const { remoteRootState, state } = input;\n const { container } = remoteRootState;\n const runtime = state.runtime;\n if (!isSessionRootState(remoteRootState, state)) return false;\n const role = cachedDestinationRole(runtime.infra.execSql, container);\n if (!role) return false;\n try {\n if (role.parentId !== null) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"session root reconciliation target is not a verified root\",\n );\n }\n assertRootCreatedBySessionUser(role, runtime);\n return true;\n } catch (error) {\n const reported = await reportKeyingVerificationErrorInCauseChain(\n error,\n runtime.util.reportSecurityIncident,\n {\n objectId: container.id,\n objectKind: \"container\",\n operation: \"container.root.reconcile\",\n organizationId: container.organizationId,\n },\n );\n if (!reported) throw error;\n return false;\n }\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApiClient } from "../../internal/api-client/index.js";
|
|
2
2
|
import { type DocumentProjectorRegistryInput } from "../../data/documents/documentKinds.js";
|
|
3
|
+
import type { PrincipalHistoryProtectionLease } from "../../data/principals/principalHistoryProtection.js";
|
|
3
4
|
import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
|
|
4
5
|
import { type TrustedUserIdentityResolver } from "../../data/trustedUserIdentity/index.js";
|
|
5
6
|
import { createDocumentsWorkflowRuntime, type DocumentsWorkflowRuntime } from "../documents/index.js";
|
|
@@ -44,6 +45,8 @@ export interface ContainerContentsWorkflowRuntimeInputGroups {
|
|
|
44
45
|
readonly util: ContainerContentsWorkflowRuntimeUtil;
|
|
45
46
|
}
|
|
46
47
|
export interface ContainerContentsWorkflowRuntimeInput extends ContainerContentsWorkflowRuntimeInputGroups {
|
|
48
|
+
/** Private host custody, inherited by container and derived document runtimes. */
|
|
49
|
+
readonly withPrincipalHistoryProtection?: PrincipalHistoryProtectionLease | undefined;
|
|
47
50
|
readonly apiClient: ContainerContentsWorkflowApi;
|
|
48
51
|
readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;
|
|
49
52
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { resolveDocumentProjectorRegistry, } from "../../data/documents/documentKinds.js";
|
|
2
|
+
import { inheritPrincipalHistoryProtection } from "../../data/principals/principalHistoryRuntime.js";
|
|
2
3
|
import { requireTrustedUserIdentityResolver, } from "../../data/trustedUserIdentity/index.js";
|
|
3
4
|
import { createDocumentsWorkflowRuntime, } from "../documents/index.js";
|
|
4
5
|
function documentsRuntimeInput(runtime, containerId) {
|
|
5
|
-
return {
|
|
6
|
+
return inheritPrincipalHistoryProtection(runtime, {
|
|
6
7
|
apiClient: runtime.apiClient,
|
|
7
8
|
auth: runtime.auth,
|
|
8
9
|
crypto: runtime.crypto,
|
|
@@ -10,7 +11,7 @@ function documentsRuntimeInput(runtime, containerId) {
|
|
|
10
11
|
resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,
|
|
11
12
|
state: { ...runtime.state, containerId },
|
|
12
13
|
util: runtime.util,
|
|
13
|
-
};
|
|
14
|
+
});
|
|
14
15
|
}
|
|
15
16
|
export function createContainerContentsDocumentsRuntime(runtime, containerId) {
|
|
16
17
|
return createDocumentsWorkflowRuntime(documentsRuntimeInput(runtime, containerId));
|
|
@@ -21,7 +22,7 @@ function createContainerContentsWorkflowRuntimeWithRootAdopter(input, adoptRootC
|
|
|
21
22
|
...input.infra,
|
|
22
23
|
documentProjectors,
|
|
23
24
|
};
|
|
24
|
-
return {
|
|
25
|
+
return inheritPrincipalHistoryProtection(input, {
|
|
25
26
|
...(adoptRootContainer ? { adoptRootContainer } : {}),
|
|
26
27
|
apiClient: input.apiClient,
|
|
27
28
|
auth: input.auth,
|
|
@@ -30,16 +31,16 @@ function createContainerContentsWorkflowRuntimeWithRootAdopter(input, adoptRootC
|
|
|
30
31
|
resolveTrustedUserIdentity: requireTrustedUserIdentityResolver(input.resolveTrustedUserIdentity),
|
|
31
32
|
state: input.state,
|
|
32
33
|
util: input.util,
|
|
33
|
-
};
|
|
34
|
+
});
|
|
34
35
|
}
|
|
35
36
|
export function createContainerContentsWorkflowRuntime(input) {
|
|
36
37
|
return createContainerContentsWorkflowRuntimeWithRootAdopter(input);
|
|
37
38
|
}
|
|
38
39
|
/** Internal store runtime with the session-root adoption capability wired. */
|
|
39
40
|
export function createContainerContentsStoreWorkflowRuntime(input, adoptRootContainer) {
|
|
40
|
-
return {
|
|
41
|
+
return inheritPrincipalHistoryProtection(input, {
|
|
41
42
|
...createContainerContentsWorkflowRuntimeWithRootAdopter(input, adoptRootContainer),
|
|
42
43
|
adoptRootContainer,
|
|
43
|
-
};
|
|
44
|
+
});
|
|
44
45
|
}
|
|
45
46
|
//# sourceMappingURL=runtime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,gCAAgC,GACjC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACL,kCAAkC,GAEnC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,8BAA8B,GAE/B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["runtime.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,gCAAgC,GACjC,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAElG,OAAO,EACL,kCAAkC,GAEnC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,8BAA8B,GAE/B,MAAM,cAAc,CAAC;AAqGtB,SAAS,qBAAqB,CAC5B,OAAyC,EACzC,WAA0B;IAE1B,OAAO,iCAAiC,CAAC,OAAO,EAAE;QAChD,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;QAC9D,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE;QACxC,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,OAAyC,EACzC,WAA0B;IAE1B,OAAO,8BAA8B,CACnC,qBAAqB,CAAC,OAAO,EAAE,WAAW,CAAC,CAC5C,CAAC;AACJ,CAAC;AAED,SAAS,qDAAqD,CAC5D,KAA4C,EAC5C,kBAA6D;IAE7D,MAAM,kBAAkB,GAAG,gCAAgC,CACzD,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAC/B,CAAC;IACF,MAAM,KAAK,GAAG;QACZ,GAAG,KAAK,CAAC,KAAK;QACd,kBAAkB;KACnB,CAAC;IAEF,OAAO,iCAAiC,CAAC,KAAK,EAAE;QAC9C,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK;QACL,0BAA0B,EAAE,kCAAkC,CAC5D,KAAK,CAAC,0BAA0B,CACjC;QACD,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,sCAAsC,CACpD,KAA4C;IAE5C,OAAO,qDAAqD,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,2CAA2C,CACzD,KAA4C,EAC5C,kBAAgD;IAEhD,OAAO,iCAAiC,CAAC,KAAK,EAAE;QAC9C,GAAG,qDAAqD,CACtD,KAAK,EACL,kBAAkB,CACnB;QACD,kBAAkB;KACnB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport {\n type DocumentProjectorRegistryInput,\n resolveDocumentProjectorRegistry,\n} from \"../../data/documents/documentKinds\";\nimport type { PrincipalHistoryProtectionLease } from \"../../data/principals/principalHistoryProtection\";\nimport { inheritPrincipalHistoryProtection } from \"../../data/principals/principalHistoryRuntime\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport {\n requireTrustedUserIdentityResolver,\n type TrustedUserIdentityResolver,\n} from \"../../data/trustedUserIdentity\";\nimport {\n createDocumentsWorkflowRuntime,\n type DocumentsWorkflowRuntime,\n} from \"../documents\";\nimport type {\n WorkflowRuntimeAuthInput,\n WorkflowRuntimeCryptoInput,\n WorkflowRuntimeInfraInput,\n WorkflowRuntimeStateInput,\n WorkflowRuntimeUtilInput,\n} from \"../runtimeInput\";\n\ntype DocumentsWorkflowRuntimeInput = Parameters<\n typeof createDocumentsWorkflowRuntime\n>[0];\n\ntype ContainerContentsWorkflowApi = ApiClient &\n DocumentsWorkflowRuntimeInput[\"apiClient\"];\n\nexport interface ContainerContentsWorkflowRuntimeAuth\n extends WorkflowRuntimeAuthInput {}\n\nexport interface ContainerContentsWorkflowRuntimeCrypto\n extends WorkflowRuntimeCryptoInput {}\n\nexport interface ContainerContentsWorkflowRuntimeInfra\n extends Omit<WorkflowRuntimeInfraInput, \"dbStatus\"> {\n readonly dbStatus: string;\n}\n\ninterface ContainerContentsWorkflowRuntimeInputInfra\n extends Omit<ContainerContentsWorkflowRuntimeInfra, \"documentProjectors\"> {\n readonly documentProjectors: DocumentProjectorRegistryInput;\n}\n\nexport interface ContainerContentsWorkflowRuntimeState\n extends WorkflowRuntimeStateInput {}\n\nexport interface ContainerContentsWorkflowRuntimeUtil\n extends Omit<WorkflowRuntimeUtilInput, \"logError\"> {\n // Store recovery is best-effort, so hosts may retain the causal error without\n // making structured error logging mandatory for general workflow runtimes.\n readonly logError?: WorkflowRuntimeUtilInput[\"logError\"] | undefined;\n}\n\nexport interface ContainerContentsRootAdoptionInput {\n readonly domainScope: ContainerContentsWorkflowRuntimeState[\"domainScope\"];\n readonly expectedContainerId: string;\n readonly nextContainerId: string;\n readonly organizationId: string;\n readonly userId: string;\n}\n\nexport type ContainerContentsRootAdopter = (\n input: ContainerContentsRootAdoptionInput,\n) => boolean | \"already-adopted\";\n\nexport interface ContainerContentsWorkflowRuntimeGroups {\n readonly auth: ContainerContentsWorkflowRuntimeAuth;\n readonly crypto: ContainerContentsWorkflowRuntimeCrypto;\n readonly infra: ContainerContentsWorkflowRuntimeInfra;\n readonly state: ContainerContentsWorkflowRuntimeState;\n readonly util: ContainerContentsWorkflowRuntimeUtil;\n}\n\nexport interface ContainerContentsWorkflowRuntimeInputGroups {\n readonly auth: ContainerContentsWorkflowRuntimeAuth;\n readonly crypto: ContainerContentsWorkflowRuntimeCrypto;\n readonly infra: ContainerContentsWorkflowRuntimeInputInfra;\n readonly state: ContainerContentsWorkflowRuntimeState;\n readonly util: ContainerContentsWorkflowRuntimeUtil;\n}\n\nexport interface ContainerContentsWorkflowRuntimeInput\n extends ContainerContentsWorkflowRuntimeInputGroups {\n /** Private host custody, inherited by container and derived document runtimes. */\n readonly withPrincipalHistoryProtection?:\n | PrincipalHistoryProtectionLease\n | undefined;\n readonly apiClient: ContainerContentsWorkflowApi;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}\n\nexport interface ContainerContentsWorkflowRuntime\n extends ContainerContentsWorkflowRuntimeGroups,\n Pick<ContainerContentsWorkflowRuntimeInput, \"apiClient\"> {\n readonly adoptRootContainer?: ContainerContentsRootAdopter | undefined;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n}\n\nexport interface ContainerContentsStoreWorkflowRuntime\n extends ContainerContentsWorkflowRuntime {\n readonly adoptRootContainer: ContainerContentsRootAdopter;\n}\n\nexport interface ContainerContentsWorkflowSqlRuntime {\n readonly auth?: {\n readonly organizationId?: string | null | undefined;\n };\n readonly infra: {\n readonly execSql: ExecSql;\n };\n}\n\nfunction documentsRuntimeInput(\n runtime: ContainerContentsWorkflowRuntime,\n containerId: string | null,\n): DocumentsWorkflowRuntimeInput {\n return inheritPrincipalHistoryProtection(runtime, {\n apiClient: runtime.apiClient,\n auth: runtime.auth,\n crypto: runtime.crypto,\n infra: runtime.infra,\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n state: { ...runtime.state, containerId },\n util: runtime.util,\n });\n}\n\nexport function createContainerContentsDocumentsRuntime(\n runtime: ContainerContentsWorkflowRuntime,\n containerId: string | null,\n): DocumentsWorkflowRuntime {\n return createDocumentsWorkflowRuntime(\n documentsRuntimeInput(runtime, containerId),\n );\n}\n\nfunction createContainerContentsWorkflowRuntimeWithRootAdopter(\n input: ContainerContentsWorkflowRuntimeInput,\n adoptRootContainer?: ContainerContentsRootAdopter | undefined,\n): ContainerContentsWorkflowRuntime {\n const documentProjectors = resolveDocumentProjectorRegistry(\n input.infra.documentProjectors,\n );\n const infra = {\n ...input.infra,\n documentProjectors,\n };\n\n return inheritPrincipalHistoryProtection(input, {\n ...(adoptRootContainer ? { adoptRootContainer } : {}),\n apiClient: input.apiClient,\n auth: input.auth,\n crypto: input.crypto,\n infra,\n resolveTrustedUserIdentity: requireTrustedUserIdentityResolver(\n input.resolveTrustedUserIdentity,\n ),\n state: input.state,\n util: input.util,\n });\n}\n\nexport function createContainerContentsWorkflowRuntime(\n input: ContainerContentsWorkflowRuntimeInput,\n): ContainerContentsWorkflowRuntime {\n return createContainerContentsWorkflowRuntimeWithRootAdopter(input);\n}\n\n/** Internal store runtime with the session-root adoption capability wired. */\nexport function createContainerContentsStoreWorkflowRuntime(\n input: ContainerContentsWorkflowRuntimeInput,\n adoptRootContainer: ContainerContentsRootAdopter,\n): ContainerContentsStoreWorkflowRuntime {\n return inheritPrincipalHistoryProtection(input, {\n ...createContainerContentsWorkflowRuntimeWithRootAdopter(\n input,\n adoptRootContainer,\n ),\n adoptRootContainer,\n });\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ContainerWriterProjectionResponse, type DocumentCreateResponse
|
|
1
|
+
import { type ContainerWriterProjectionResponse, type DocumentCreateResponse } from "../../internal/validators/response/index.js";
|
|
2
2
|
import type { CreateRemoteDocumentResult, DocumentCreateApi, DocumentCreateAuthor, MaterializedDocumentCreatePlan, ProjectionVerificationOptions } from "../../data/documents/shared/types.js";
|
|
3
3
|
import type { ProjectionUserKeyResolver, ReferencedPrincipalPolicyWarmer } from "../../data/keyingProjectionVerification.js";
|
|
4
4
|
import type { ExecSql } from "../../data/sqlite/sqlSchema.js";
|
|
@@ -16,19 +16,7 @@ export declare function buildMaterializedDocumentCreatePlan(input: {
|
|
|
16
16
|
signedAt?: string | undefined;
|
|
17
17
|
targetSecretKey: Uint8Array;
|
|
18
18
|
} & ProjectionVerificationOptions): Promise<MaterializedDocumentCreatePlan>;
|
|
19
|
-
|
|
20
|
-
* Build the writer projection a document-create response establishes, from the
|
|
21
|
-
* container projection the create was authored against plus the manifest,
|
|
22
|
-
* content-key bundle, and KEK targets the server just returned. This is the
|
|
23
|
-
* same material a cold `GET /documents/:id/writer-projection` would yield, so
|
|
24
|
-
* seeding it lets the first read after a create resolve locally. Shared by the
|
|
25
|
-
* plain document-create path and the container-with-metadata-document path,
|
|
26
|
-
* whose response carries an equivalent `DocumentCreateResponse`.
|
|
27
|
-
*/
|
|
28
|
-
export declare function documentWriterProjectionFromCreateResponse(input: {
|
|
29
|
-
containerProjection: ContainerWriterProjectionResponse;
|
|
30
|
-
response: DocumentCreateResponse;
|
|
31
|
-
}): DocumentWriterProjectionResponse;
|
|
19
|
+
export { documentWriterProjectionFromCreateResponse } from "./createProjection.js";
|
|
32
20
|
interface RemoteDocumentCreateInput {
|
|
33
21
|
apiClient: DocumentCreateApi;
|
|
34
22
|
author: DocumentCreateAuthor;
|
|
@@ -66,4 +54,3 @@ type DocumentCreateSubmission = {
|
|
|
66
54
|
readonly status: number | null;
|
|
67
55
|
};
|
|
68
56
|
export declare function isStaleDocumentCreateTargetConflict(submission: DocumentCreateSubmission): boolean;
|
|
69
|
-
export {};
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { DOCUMENT_SYNC_ERROR_CODES, } from "../../internal/validators/response/index.js";
|
|
2
2
|
import { assertContainerAuthorAccess } from "../../data/containers/shared/authorAccess.js";
|
|
3
3
|
import { buildDocumentCreatePlan } from "../../data/documents/shared/events.js";
|
|
4
|
-
import {
|
|
5
|
-
import { assertDocumentWriterProjectionConsistent, wrapDocumentContentKeyForCreate, } from "../../data/documents/shared/projection.js";
|
|
6
|
-
import { persistedDocumentCreateStateFromResponse } from "../../data/documents/shared/responses.js";
|
|
4
|
+
import { wrapDocumentContentKeyForCreate } from "../../data/documents/shared/projection.js";
|
|
7
5
|
import { projectionVerificationOptions } from "../../data/documents/shared/types.js";
|
|
8
6
|
import { collectContainerWriterProjectionPrincipalPolicies, nullOnProjectionVerificationCancellation, requireProjectionUserKeyResolver, } from "../../data/keyingProjectionVerification.js";
|
|
9
7
|
import { isContainerCreatePending } from "../../data/persistence/container-contents/pendingContainerCreate.js";
|
|
10
8
|
import { recordDocumentAuthorAccessFailure } from "./authorAccessFailure.js";
|
|
11
9
|
import { adoptExistingRemoteDocument } from "./createAdoption.js";
|
|
12
10
|
import { fetchContainerWriterProjectionForCreate } from "./createProjectionFetch.js";
|
|
11
|
+
import { acknowledgeRemoteDocumentCreate } from "./createResponse.js";
|
|
13
12
|
import { isDocumentManifestAlreadyExistsConflict, shouldRetryWithFreshProjection, } from "./syncFailureClassification.js";
|
|
14
13
|
export async function buildMaterializedDocumentCreatePlan(input) {
|
|
15
14
|
const contentKey = input.contentKey ?? crypto.getRandomValues(new Uint8Array(32));
|
|
@@ -65,31 +64,7 @@ export async function buildMaterializedDocumentCreatePlan(input) {
|
|
|
65
64
|
plan,
|
|
66
65
|
};
|
|
67
66
|
}
|
|
68
|
-
|
|
69
|
-
* Build the writer projection a document-create response establishes, from the
|
|
70
|
-
* container projection the create was authored against plus the manifest,
|
|
71
|
-
* content-key bundle, and KEK targets the server just returned. This is the
|
|
72
|
-
* same material a cold `GET /documents/:id/writer-projection` would yield, so
|
|
73
|
-
* seeding it lets the first read after a create resolve locally. Shared by the
|
|
74
|
-
* plain document-create path and the container-with-metadata-document path,
|
|
75
|
-
* whose response carries an equivalent `DocumentCreateResponse`.
|
|
76
|
-
*/
|
|
77
|
-
export function documentWriterProjectionFromCreateResponse(input) {
|
|
78
|
-
return {
|
|
79
|
-
policyEvidence: input.containerProjection.policyEvidence,
|
|
80
|
-
authorizingContainerPaths: [input.containerProjection],
|
|
81
|
-
contentKeyBundle: input.response.contentKeyBundle,
|
|
82
|
-
documentContainerManifestHistory: [
|
|
83
|
-
...input.containerProjection.path,
|
|
84
|
-
...input.containerProjection.containerKeks.flatMap((kek) => kek.containerManifestHistory),
|
|
85
|
-
],
|
|
86
|
-
documentId: input.response.id,
|
|
87
|
-
documentKekTargets: input.response.documentKekTargets,
|
|
88
|
-
documentManifest: input.response.accessManifest,
|
|
89
|
-
documentManifestContainerPaths: [[...input.containerProjection.path]],
|
|
90
|
-
documentManifestHistory: [],
|
|
91
|
-
};
|
|
92
|
-
}
|
|
67
|
+
export { documentWriterProjectionFromCreateResponse } from "./createProjection.js";
|
|
93
68
|
async function buildMaterializedDocumentCreatePlanWithFreshProjection(input) {
|
|
94
69
|
const buildWithProjection = async (containerProjection) => {
|
|
95
70
|
if (containerProjection.containerId !== input.containerId ||
|
|
@@ -227,43 +202,13 @@ export async function createRemoteDocument(input) {
|
|
|
227
202
|
const { createPlan, submission } = plannedSubmission;
|
|
228
203
|
if (input.stillCurrent?.() === false)
|
|
229
204
|
return null;
|
|
230
|
-
if (submission.ok)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
execSql: input.execSql,
|
|
235
|
-
plan: createPlan.materializedPlan.plan,
|
|
236
|
-
stillCurrent: input.stillCurrent,
|
|
237
|
-
});
|
|
238
|
-
if (input.stillCurrent?.() === false)
|
|
239
|
-
return null;
|
|
240
|
-
const writerProjection = documentWriterProjectionFromCreateResponse({
|
|
241
|
-
containerProjection: createPlan.containerProjection,
|
|
242
|
-
response,
|
|
243
|
-
});
|
|
244
|
-
const verifiedTargets = await nullOnProjectionVerificationCancellation(() => assertDocumentWriterProjectionConsistent(writerProjection, {
|
|
245
|
-
execSql: input.execSql,
|
|
205
|
+
if (submission.ok)
|
|
206
|
+
return acknowledgeRemoteDocumentCreate({
|
|
207
|
+
...input,
|
|
208
|
+
...createPlan,
|
|
246
209
|
resolveProjectionUserKey,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}));
|
|
250
|
-
if (!verifiedTargets)
|
|
251
|
-
return null;
|
|
252
|
-
if (input.stillCurrent?.() === false)
|
|
253
|
-
return null;
|
|
254
|
-
// Seed the projection the create response already gave us so the first read
|
|
255
|
-
// after create (sync, blob attach, container-contents hydration) resolves
|
|
256
|
-
// locally instead of a cold GET writer-projection.
|
|
257
|
-
input.apiClient.primeDocumentWriterProjection(response.id, writerProjection);
|
|
258
|
-
return {
|
|
259
|
-
contentKey: createPlan.materializedPlan.contentKey,
|
|
260
|
-
documentId: response.id,
|
|
261
|
-
persistedState,
|
|
262
|
-
plan: createPlan.materializedPlan.plan,
|
|
263
|
-
response,
|
|
264
|
-
writerProjection,
|
|
265
|
-
};
|
|
266
|
-
}
|
|
210
|
+
response: submission.data,
|
|
211
|
+
});
|
|
267
212
|
// A stable documentId means a retry after a lost create response re-submits
|
|
268
213
|
// the same id; the server then reports the manifest already exists. That is
|
|
269
214
|
// not a failure — the first attempt committed. Adopt the existing remote
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["create.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentCreateRequest } from \"@tearleads/validators/request\";\nimport {\n type ContainerWriterProjectionResponse,\n DOCUMENT_SYNC_ERROR_CODES,\n type DocumentCreateResponse,\n type DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport { assertContainerAuthorAccess } from \"../../data/containers/shared/authorAccess\";\nimport { buildDocumentCreatePlan } from \"../../data/documents/shared/events\";\nimport { acknowledgeDocumentMutation } from \"../../data/documents/shared/mutationAcknowledgement\";\nimport {\n assertDocumentWriterProjectionConsistent,\n wrapDocumentContentKeyForCreate,\n} from \"../../data/documents/shared/projection\";\nimport { persistedDocumentCreateStateFromResponse } from \"../../data/documents/shared/responses\";\nimport type {\n CreateRemoteDocumentResult,\n DocumentCreateApi,\n DocumentCreateAuthor,\n MaterializedDocumentCreatePlan,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { projectionVerificationOptions } from \"../../data/documents/shared/types\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport {\n collectContainerWriterProjectionPrincipalPolicies,\n nullOnProjectionVerificationCancellation,\n requireProjectionUserKeyResolver,\n} from \"../../data/keyingProjectionVerification\";\nimport { isContainerCreatePending } from \"../../data/persistence/container-contents/pendingContainerCreate\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { recordDocumentAuthorAccessFailure } from \"./authorAccessFailure\";\nimport { adoptExistingRemoteDocument } from \"./createAdoption\";\nimport type { DocumentCreateTerminalFailureHandler } from \"./createProjectionFetch\";\nimport { fetchContainerWriterProjectionForCreate } from \"./createProjectionFetch\";\nimport {\n isDocumentManifestAlreadyExistsConflict,\n shouldRetryWithFreshProjection,\n} from \"./syncFailureClassification\";\n\nexport async function buildMaterializedDocumentCreatePlan(\n input: {\n author: DocumentCreateAuthor;\n containerProjection: ContainerWriterProjectionResponse;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql?: ExecSql | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n signedAt?: string | undefined;\n targetSecretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<MaterializedDocumentCreatePlan> {\n const contentKey =\n input.contentKey ?? crypto.getRandomValues(new Uint8Array(32));\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Document content key must be 32 bytes\");\n }\n // Resolved before wrapping: each envelope is sealed to its document and\n // content-key epoch.\n const documentId = input.documentId ?? crypto.randomUUID();\n const contentKeyEpoch = input.contentKeyEpoch ?? 1;\n const targetEnvelopes = await wrapDocumentContentKeyForCreate({\n contentKey,\n contentKeyEpoch,\n documentId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n projection: input.containerProjection,\n secretKey: input.targetSecretKey,\n ...projectionVerificationOptions(input),\n });\n if (input.resolveProjectionUserKey) {\n const principalPolicies =\n await collectContainerWriterProjectionPrincipalPolicies({\n ...projectionVerificationOptions(input),\n execSql: input.execSql,\n projection: input.containerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n });\n assertContainerAuthorAccess({\n // Document signing derives its organization from the verified target.\n author: {\n ...input.author,\n organizationId: input.containerProjection.organizationId,\n },\n projection: input.containerProjection,\n principalPolicies,\n minimumAccess: \"write\",\n });\n }\n // The explicit local-trust variant builds provisioning artifacts before\n // their new principal policies exist remotely; remote creates cannot use it.\n const plan = await buildDocumentCreatePlan({\n author: input.author,\n containerProjection: input.containerProjection,\n contentKeyEpoch,\n documentId,\n ...(input.eventId === undefined ? {} : { eventId: input.eventId }),\n ...(input.signedAt === undefined ? {} : { signedAt: input.signedAt }),\n targetEnvelopes,\n });\n\n return {\n contentKey,\n plan,\n };\n}\n\n/**\n * Build the writer projection a document-create response establishes, from the\n * container projection the create was authored against plus the manifest,\n * content-key bundle, and KEK targets the server just returned. This is the\n * same material a cold `GET /documents/:id/writer-projection` would yield, so\n * seeding it lets the first read after a create resolve locally. Shared by the\n * plain document-create path and the container-with-metadata-document path,\n * whose response carries an equivalent `DocumentCreateResponse`.\n */\nexport function documentWriterProjectionFromCreateResponse(input: {\n containerProjection: ContainerWriterProjectionResponse;\n response: DocumentCreateResponse;\n}): DocumentWriterProjectionResponse {\n return {\n policyEvidence: input.containerProjection.policyEvidence,\n authorizingContainerPaths: [input.containerProjection],\n contentKeyBundle: input.response.contentKeyBundle,\n documentContainerManifestHistory: [\n ...input.containerProjection.path,\n ...input.containerProjection.containerKeks.flatMap(\n (kek) => kek.containerManifestHistory,\n ),\n ],\n documentId: input.response.id,\n documentKekTargets: input.response.documentKekTargets,\n documentManifest: input.response.accessManifest,\n documentManifestContainerPaths: [[...input.containerProjection.path]],\n documentManifestHistory: [],\n };\n}\n\ninterface MaterializedDocumentCreatePlanWithProjection {\n readonly containerProjection: ContainerWriterProjectionResponse;\n readonly materializedPlan: MaterializedDocumentCreatePlan;\n}\n\nasync function buildMaterializedDocumentCreatePlanWithFreshProjection(input: {\n apiClient: DocumentCreateApi;\n author: DocumentCreateAuthor;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | undefined;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedOrganizationId?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<MaterializedDocumentCreatePlanWithProjection | null> {\n const buildWithProjection = async (\n containerProjection: ContainerWriterProjectionResponse,\n ) => {\n if (\n containerProjection.containerId !== input.containerId ||\n (input.expectedOrganizationId !== undefined &&\n containerProjection.organizationId !== input.expectedOrganizationId)\n ) {\n throw new Error(\n \"Container writer projection belongs to another container or organization\",\n );\n }\n return {\n containerProjection,\n materializedPlan: await buildMaterializedDocumentCreatePlan({\n author: input.author,\n containerProjection,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n documentId: input.documentId,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n };\n };\n\n const containerProjection =\n input.containerProjection ??\n (await fetchContainerWriterProjectionForCreate({\n apiClient: input.apiClient,\n containerId: input.containerId,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n }));\n if (!containerProjection) {\n return null;\n }\n\n try {\n return await buildWithProjection(containerProjection);\n } catch (error) {\n if (\n !shouldRetryWithFreshProjection(error, (message) =>\n message.includes(\"could not be unwrapped\"),\n )\n ) {\n throw error;\n }\n }\n\n // Only this container's projection was stale; evict just it rather than\n // wiping every cached projection.\n input.apiClient.evictContainerWriterProjection(input.containerId);\n const refreshedProjection = await fetchContainerWriterProjectionForCreate({\n apiClient: input.apiClient,\n containerId: input.containerId,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n });\n return refreshedProjection ? buildWithProjection(refreshedProjection) : null;\n}\n\ninterface RemoteDocumentCreateInput {\n apiClient: DocumentCreateApi;\n author: DocumentCreateAuthor;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | undefined;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedOrganizationId?: string | undefined;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n /**\n * Invoked when the create submission fails terminally (not a benign\n * adopt/stale-target conflict) — e.g. the server denies the write. Callers\n * persist the failure so the write queue can surface it.\n */\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\nfunction isRemoteDocumentCreatePlanBlocked(\n input: RemoteDocumentCreateInput,\n createPlan: MaterializedDocumentCreatePlanWithProjection,\n): boolean {\n const organizationId = createPlan.containerProjection.organizationId;\n return input.isRemoteSyncBlocked?.(organizationId) ?? false;\n}\n\nasync function submitPlannedDocumentCreate(\n input: RemoteDocumentCreateInput,\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<{\n readonly createPlan: MaterializedDocumentCreatePlanWithProjection;\n readonly submission: DocumentCreateSubmission;\n} | null> {\n const verificationOptions = { stillCurrent: input.stillCurrent };\n const warmReferencedPrincipalPolicies = input.warmReferencedPrincipalPolicies;\n let createPlan = await buildMaterializedDocumentCreatePlanWithFreshProjection(\n {\n apiClient: input.apiClient,\n author: input.author,\n containerId: input.containerId,\n containerProjection: input.containerProjection,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n documentId: input.documentId,\n eventId: input.eventId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n knownContainerKeks: input.knownContainerKeks,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies,\n ...verificationOptions,\n },\n );\n if (!createPlan) {\n return null;\n }\n if (isRemoteDocumentCreatePlanBlocked(input, createPlan)) return null;\n if (input.stillCurrent?.() === false) return null;\n let submission = await submitDocumentCreate(\n input.apiClient,\n createPlan.materializedPlan.plan.request,\n createPlan.containerProjection.organizationId,\n );\n if (isStaleDocumentCreateTargetConflict(submission)) {\n if (input.stillCurrent?.() === false) {\n return { createPlan, submission };\n }\n input.apiClient.evictContainerWriterProjection(input.containerId);\n const firstPlan = createPlan.materializedPlan;\n const refreshedPlan =\n await buildMaterializedDocumentCreatePlanWithFreshProjection({\n apiClient: input.apiClient,\n author: input.author,\n containerId: input.containerId,\n contentKey: firstPlan.contentKey,\n contentKeyEpoch:\n firstPlan.plan.request.contentKeyBundle.contentKeyEpoch,\n documentId: firstPlan.plan.documentId,\n eventId: firstPlan.plan.event.eventId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n knownContainerKeks: input.knownContainerKeks,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n resolveProjectionUserKey,\n signedAt: firstPlan.plan.event.signedAt,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies,\n ...verificationOptions,\n });\n if (!refreshedPlan) {\n return null;\n }\n if (isRemoteDocumentCreatePlanBlocked(input, refreshedPlan)) return null;\n createPlan = refreshedPlan;\n if (input.stillCurrent?.() === false) return null;\n submission = await submitDocumentCreate(\n input.apiClient,\n createPlan.materializedPlan.plan.request,\n createPlan.containerProjection.organizationId,\n );\n }\n return { createPlan, submission };\n}\n\nexport async function createRemoteDocument(\n input: RemoteDocumentCreateInput,\n): Promise<CreateRemoteDocumentResult | null> {\n // The store retries once the folder's own create settles.\n if (await isContainerCreatePending(input.execSql, input.containerId)) {\n return null;\n }\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote document create\",\n );\n const plannedSubmission = await recordDocumentAuthorAccessFailure(\n () =>\n nullOnProjectionVerificationCancellation(() =>\n submitPlannedDocumentCreate(input, resolveProjectionUserKey),\n ),\n input.onTerminalSubmitFailure,\n );\n if (!plannedSubmission) {\n return null;\n }\n const { createPlan, submission } = plannedSubmission;\n if (input.stillCurrent?.() === false) return null;\n if (submission.ok) {\n const response = submission.data;\n const persistedState = persistedDocumentCreateStateFromResponse(\n createPlan.materializedPlan.plan,\n response,\n );\n await acknowledgeDocumentMutation({\n execSql: input.execSql,\n plan: createPlan.materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n const writerProjection = documentWriterProjectionFromCreateResponse({\n containerProjection: createPlan.containerProjection,\n response,\n });\n const verifiedTargets = await nullOnProjectionVerificationCancellation(() =>\n assertDocumentWriterProjectionConsistent(writerProjection, {\n execSql: input.execSql,\n resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n );\n if (!verifiedTargets) return null;\n if (input.stillCurrent?.() === false) return null;\n // Seed the projection the create response already gave us so the first read\n // after create (sync, blob attach, container-contents hydration) resolves\n // locally instead of a cold GET writer-projection.\n input.apiClient.primeDocumentWriterProjection(\n response.id,\n writerProjection,\n );\n\n return {\n contentKey: createPlan.materializedPlan.contentKey,\n documentId: response.id,\n persistedState,\n plan: createPlan.materializedPlan.plan,\n response,\n writerProjection,\n };\n }\n\n // A stable documentId means a retry after a lost create response re-submits\n // the same id; the server then reports the manifest already exists. That is\n // not a failure — the first attempt committed. Adopt the existing remote\n // document instead of leaking a duplicate. Requires the stable id we sent, so\n // we can fetch its projection back.\n const stableDocumentId = input.documentId;\n if (stableDocumentId && isDocumentManifestAlreadyExistsConflict(submission)) {\n if (input.stillCurrent?.() === false) return null;\n const adopted = await nullOnProjectionVerificationCancellation(() =>\n adoptExistingRemoteDocument({\n apiClient: input.apiClient,\n documentId: stableDocumentId,\n execSql: input.execSql,\n expectedContainerId: input.containerId,\n expectedOrganizationId:\n input.expectedOrganizationId ??\n createPlan.containerProjection.organizationId,\n expectedSignerUserId: input.author.signerUserId,\n resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n );\n if (adopted) {\n return adopted;\n }\n // A conflict is the expected, benign outcome of an idempotent retry after a\n // lost create response. If adoption cannot complete yet (e.g. the writer\n // projection fetch failed transiently), do not surface the conflict as a UI\n // error — the sync engine retries and adopts it on a later tick.\n return null;\n }\n\n submission.report?.();\n await input.onTerminalSubmitFailure?.(submission);\n return null;\n}\n\ntype DocumentCreateSubmission =\n | {\n readonly data: DocumentCreateResponse;\n readonly ok: true;\n }\n | {\n readonly code?: string | undefined;\n readonly message: string;\n readonly ok: false;\n readonly report?: (() => void) | undefined;\n readonly status: number | null;\n };\n\nexport function isStaleDocumentCreateTargetConflict(\n submission: DocumentCreateSubmission,\n): boolean {\n return (\n !submission.ok &&\n submission.status === 409 &&\n submission.code === DOCUMENT_SYNC_ERROR_CODES.stateStale\n );\n}\n\nasync function submitDocumentCreate(\n apiClient: DocumentCreateApi,\n request: DocumentCreateRequest,\n expectedOrganizationId: string,\n): Promise<DocumentCreateSubmission> {\n return apiClient.createDocumentResult(request, {\n expectedPaymentRequiredOrganizationId: expectedOrganizationId,\n reportErrors: false,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["create.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DocumentCreateRequest } from \"@tearleads/validators/request\";\nimport {\n type ContainerWriterProjectionResponse,\n DOCUMENT_SYNC_ERROR_CODES,\n type DocumentCreateResponse,\n} from \"@tearleads/validators/response\";\nimport { assertContainerAuthorAccess } from \"../../data/containers/shared/authorAccess\";\nimport { buildDocumentCreatePlan } from \"../../data/documents/shared/events\";\nimport { wrapDocumentContentKeyForCreate } from \"../../data/documents/shared/projection\";\nimport type {\n CreateRemoteDocumentResult,\n DocumentCreateApi,\n DocumentCreateAuthor,\n MaterializedDocumentCreatePlan,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport { projectionVerificationOptions } from \"../../data/documents/shared/types\";\nimport type {\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification\";\nimport {\n collectContainerWriterProjectionPrincipalPolicies,\n nullOnProjectionVerificationCancellation,\n requireProjectionUserKeyResolver,\n} from \"../../data/keyingProjectionVerification\";\nimport { isContainerCreatePending } from \"../../data/persistence/container-contents/pendingContainerCreate\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { recordDocumentAuthorAccessFailure } from \"./authorAccessFailure\";\nimport { adoptExistingRemoteDocument } from \"./createAdoption\";\nimport type { DocumentCreateTerminalFailureHandler } from \"./createProjectionFetch\";\nimport { fetchContainerWriterProjectionForCreate } from \"./createProjectionFetch\";\nimport { acknowledgeRemoteDocumentCreate } from \"./createResponse\";\nimport {\n isDocumentManifestAlreadyExistsConflict,\n shouldRetryWithFreshProjection,\n} from \"./syncFailureClassification\";\n\nexport async function buildMaterializedDocumentCreatePlan(\n input: {\n author: DocumentCreateAuthor;\n containerProjection: ContainerWriterProjectionResponse;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql?: ExecSql | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n signedAt?: string | undefined;\n targetSecretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<MaterializedDocumentCreatePlan> {\n const contentKey =\n input.contentKey ?? crypto.getRandomValues(new Uint8Array(32));\n if (contentKey.byteLength !== 32) {\n throw new Error(\"Document content key must be 32 bytes\");\n }\n // Resolved before wrapping: each envelope is sealed to its document and\n // content-key epoch.\n const documentId = input.documentId ?? crypto.randomUUID();\n const contentKeyEpoch = input.contentKeyEpoch ?? 1;\n const targetEnvelopes = await wrapDocumentContentKeyForCreate({\n contentKey,\n contentKeyEpoch,\n documentId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n projection: input.containerProjection,\n secretKey: input.targetSecretKey,\n ...projectionVerificationOptions(input),\n });\n if (input.resolveProjectionUserKey) {\n const principalPolicies =\n await collectContainerWriterProjectionPrincipalPolicies({\n ...projectionVerificationOptions(input),\n execSql: input.execSql,\n projection: input.containerProjection,\n resolveUserKey: input.resolveProjectionUserKey,\n });\n assertContainerAuthorAccess({\n // Document signing derives its organization from the verified target.\n author: {\n ...input.author,\n organizationId: input.containerProjection.organizationId,\n },\n projection: input.containerProjection,\n principalPolicies,\n minimumAccess: \"write\",\n });\n }\n // The explicit local-trust variant builds provisioning artifacts before\n // their new principal policies exist remotely; remote creates cannot use it.\n const plan = await buildDocumentCreatePlan({\n author: input.author,\n containerProjection: input.containerProjection,\n contentKeyEpoch,\n documentId,\n ...(input.eventId === undefined ? {} : { eventId: input.eventId }),\n ...(input.signedAt === undefined ? {} : { signedAt: input.signedAt }),\n targetEnvelopes,\n });\n\n return {\n contentKey,\n plan,\n };\n}\n\nexport { documentWriterProjectionFromCreateResponse } from \"./createProjection\";\n\ninterface MaterializedDocumentCreatePlanWithProjection {\n readonly containerProjection: ContainerWriterProjectionResponse;\n readonly materializedPlan: MaterializedDocumentCreatePlan;\n}\n\nasync function buildMaterializedDocumentCreatePlanWithFreshProjection(input: {\n apiClient: DocumentCreateApi;\n author: DocumentCreateAuthor;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | undefined;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedOrganizationId?: string | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n persistVerificationCheckpoints?: boolean | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<MaterializedDocumentCreatePlanWithProjection | null> {\n const buildWithProjection = async (\n containerProjection: ContainerWriterProjectionResponse,\n ) => {\n if (\n containerProjection.containerId !== input.containerId ||\n (input.expectedOrganizationId !== undefined &&\n containerProjection.organizationId !== input.expectedOrganizationId)\n ) {\n throw new Error(\n \"Container writer projection belongs to another container or organization\",\n );\n }\n return {\n containerProjection,\n materializedPlan: await buildMaterializedDocumentCreatePlan({\n author: input.author,\n containerProjection,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n documentId: input.documentId,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n persistVerificationCheckpoints: input.persistVerificationCheckpoints,\n resolveProjectionUserKey: input.resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n };\n };\n\n const containerProjection =\n input.containerProjection ??\n (await fetchContainerWriterProjectionForCreate({\n apiClient: input.apiClient,\n containerId: input.containerId,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n }));\n if (!containerProjection) {\n return null;\n }\n\n try {\n return await buildWithProjection(containerProjection);\n } catch (error) {\n if (\n !shouldRetryWithFreshProjection(error, (message) =>\n message.includes(\"could not be unwrapped\"),\n )\n ) {\n throw error;\n }\n }\n\n // Only this container's projection was stale; evict just it rather than\n // wiping every cached projection.\n input.apiClient.evictContainerWriterProjection(input.containerId);\n const refreshedProjection = await fetchContainerWriterProjectionForCreate({\n apiClient: input.apiClient,\n containerId: input.containerId,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n });\n return refreshedProjection ? buildWithProjection(refreshedProjection) : null;\n}\n\ninterface RemoteDocumentCreateInput {\n apiClient: DocumentCreateApi;\n author: DocumentCreateAuthor;\n containerId: string;\n containerProjection?: ContainerWriterProjectionResponse | undefined;\n contentKey?: Uint8Array | undefined;\n contentKeyEpoch?: number | undefined;\n documentId?: string | undefined;\n eventId?: string | undefined;\n execSql: ExecSql;\n expectedOrganizationId?: string | undefined;\n isRemoteSyncBlocked?: ((organizationId: string) => boolean) | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n /**\n * Invoked when the create submission fails terminally (not a benign\n * adopt/stale-target conflict) — e.g. the server denies the write. Callers\n * persist the failure so the write queue can surface it.\n */\n onTerminalSubmitFailure?: DocumentCreateTerminalFailureHandler | undefined;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\nfunction isRemoteDocumentCreatePlanBlocked(\n input: RemoteDocumentCreateInput,\n createPlan: MaterializedDocumentCreatePlanWithProjection,\n): boolean {\n const organizationId = createPlan.containerProjection.organizationId;\n return input.isRemoteSyncBlocked?.(organizationId) ?? false;\n}\n\nasync function submitPlannedDocumentCreate(\n input: RemoteDocumentCreateInput,\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<{\n readonly createPlan: MaterializedDocumentCreatePlanWithProjection;\n readonly submission: DocumentCreateSubmission;\n} | null> {\n const verificationOptions = { stillCurrent: input.stillCurrent };\n const warmReferencedPrincipalPolicies = input.warmReferencedPrincipalPolicies;\n let createPlan = await buildMaterializedDocumentCreatePlanWithFreshProjection(\n {\n apiClient: input.apiClient,\n author: input.author,\n containerId: input.containerId,\n containerProjection: input.containerProjection,\n contentKey: input.contentKey,\n contentKeyEpoch: input.contentKeyEpoch,\n documentId: input.documentId,\n eventId: input.eventId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n knownContainerKeks: input.knownContainerKeks,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies,\n ...verificationOptions,\n },\n );\n if (!createPlan) {\n return null;\n }\n if (isRemoteDocumentCreatePlanBlocked(input, createPlan)) return null;\n if (input.stillCurrent?.() === false) return null;\n let submission = await submitDocumentCreate(\n input.apiClient,\n createPlan.materializedPlan.plan.request,\n createPlan.containerProjection.organizationId,\n );\n if (isStaleDocumentCreateTargetConflict(submission)) {\n if (input.stillCurrent?.() === false) {\n return { createPlan, submission };\n }\n input.apiClient.evictContainerWriterProjection(input.containerId);\n const firstPlan = createPlan.materializedPlan;\n const refreshedPlan =\n await buildMaterializedDocumentCreatePlanWithFreshProjection({\n apiClient: input.apiClient,\n author: input.author,\n containerId: input.containerId,\n contentKey: firstPlan.contentKey,\n contentKeyEpoch:\n firstPlan.plan.request.contentKeyBundle.contentKeyEpoch,\n documentId: firstPlan.plan.documentId,\n eventId: firstPlan.plan.event.eventId,\n execSql: input.execSql,\n expectedOrganizationId: input.expectedOrganizationId,\n knownContainerKeks: input.knownContainerKeks,\n onTerminalSubmitFailure: input.onTerminalSubmitFailure,\n resolveProjectionUserKey,\n signedAt: firstPlan.plan.event.signedAt,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies,\n ...verificationOptions,\n });\n if (!refreshedPlan) {\n return null;\n }\n if (isRemoteDocumentCreatePlanBlocked(input, refreshedPlan)) return null;\n createPlan = refreshedPlan;\n if (input.stillCurrent?.() === false) return null;\n submission = await submitDocumentCreate(\n input.apiClient,\n createPlan.materializedPlan.plan.request,\n createPlan.containerProjection.organizationId,\n );\n }\n return { createPlan, submission };\n}\n\nexport async function createRemoteDocument(\n input: RemoteDocumentCreateInput,\n): Promise<CreateRemoteDocumentResult | null> {\n // The store retries once the folder's own create settles.\n if (await isContainerCreatePending(input.execSql, input.containerId)) {\n return null;\n }\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote document create\",\n );\n const plannedSubmission = await recordDocumentAuthorAccessFailure(\n () =>\n nullOnProjectionVerificationCancellation(() =>\n submitPlannedDocumentCreate(input, resolveProjectionUserKey),\n ),\n input.onTerminalSubmitFailure,\n );\n if (!plannedSubmission) {\n return null;\n }\n const { createPlan, submission } = plannedSubmission;\n if (input.stillCurrent?.() === false) return null;\n if (submission.ok)\n return acknowledgeRemoteDocumentCreate({\n ...input,\n ...createPlan,\n resolveProjectionUserKey,\n response: submission.data,\n });\n\n // A stable documentId means a retry after a lost create response re-submits\n // the same id; the server then reports the manifest already exists. That is\n // not a failure — the first attempt committed. Adopt the existing remote\n // document instead of leaking a duplicate. Requires the stable id we sent, so\n // we can fetch its projection back.\n const stableDocumentId = input.documentId;\n if (stableDocumentId && isDocumentManifestAlreadyExistsConflict(submission)) {\n if (input.stillCurrent?.() === false) return null;\n const adopted = await nullOnProjectionVerificationCancellation(() =>\n adoptExistingRemoteDocument({\n apiClient: input.apiClient,\n documentId: stableDocumentId,\n execSql: input.execSql,\n expectedContainerId: input.containerId,\n expectedOrganizationId:\n input.expectedOrganizationId ??\n createPlan.containerProjection.organizationId,\n expectedSignerUserId: input.author.signerUserId,\n resolveProjectionUserKey,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n }),\n );\n if (adopted) {\n return adopted;\n }\n // A conflict is the expected, benign outcome of an idempotent retry after a\n // lost create response. If adoption cannot complete yet (e.g. the writer\n // projection fetch failed transiently), do not surface the conflict as a UI\n // error — the sync engine retries and adopts it on a later tick.\n return null;\n }\n\n submission.report?.();\n await input.onTerminalSubmitFailure?.(submission);\n return null;\n}\n\ntype DocumentCreateSubmission =\n | {\n readonly data: DocumentCreateResponse;\n readonly ok: true;\n }\n | {\n readonly code?: string | undefined;\n readonly message: string;\n readonly ok: false;\n readonly report?: (() => void) | undefined;\n readonly status: number | null;\n };\n\nexport function isStaleDocumentCreateTargetConflict(\n submission: DocumentCreateSubmission,\n): boolean {\n return (\n !submission.ok &&\n submission.status === 409 &&\n submission.code === DOCUMENT_SYNC_ERROR_CODES.stateStale\n );\n}\n\nasync function submitDocumentCreate(\n apiClient: DocumentCreateApi,\n request: DocumentCreateRequest,\n expectedOrganizationId: string,\n): Promise<DocumentCreateSubmission> {\n return apiClient.createDocumentResult(request, {\n expectedPaymentRequiredOrganizationId: expectedOrganizationId,\n reportErrors: false,\n });\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ContainerWriterProjectionResponse, DocumentCreateResponse, DocumentWriterProjectionResponse } from "../../internal/validators/response/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build the writer projection a document-create response establishes, from the
|
|
4
|
+
* container projection the create was authored against plus the manifest,
|
|
5
|
+
* content-key bundle, and KEK targets the server just returned. This is the
|
|
6
|
+
* same material a cold `GET /documents/:id/writer-projection` would yield, so
|
|
7
|
+
* seeding it lets the first read after a create resolve locally. Shared by the
|
|
8
|
+
* plain document-create path and the container-with-metadata-document path,
|
|
9
|
+
* whose response carries an equivalent `DocumentCreateResponse`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function documentWriterProjectionFromCreateResponse(input: {
|
|
12
|
+
containerProjection: ContainerWriterProjectionResponse;
|
|
13
|
+
response: DocumentCreateResponse;
|
|
14
|
+
}): DocumentWriterProjectionResponse;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the writer projection a document-create response establishes, from the
|
|
3
|
+
* container projection the create was authored against plus the manifest,
|
|
4
|
+
* content-key bundle, and KEK targets the server just returned. This is the
|
|
5
|
+
* same material a cold `GET /documents/:id/writer-projection` would yield, so
|
|
6
|
+
* seeding it lets the first read after a create resolve locally. Shared by the
|
|
7
|
+
* plain document-create path and the container-with-metadata-document path,
|
|
8
|
+
* whose response carries an equivalent `DocumentCreateResponse`.
|
|
9
|
+
*/
|
|
10
|
+
export function documentWriterProjectionFromCreateResponse(input) {
|
|
11
|
+
return {
|
|
12
|
+
policyEvidence: input.containerProjection.policyEvidence,
|
|
13
|
+
authorizingContainerPaths: [input.containerProjection],
|
|
14
|
+
contentKeyBundle: input.response.contentKeyBundle,
|
|
15
|
+
documentContainerManifestHistory: [
|
|
16
|
+
...input.containerProjection.path,
|
|
17
|
+
...input.containerProjection.containerKeks.flatMap((kek) => kek.containerManifestHistory),
|
|
18
|
+
],
|
|
19
|
+
documentId: input.response.id,
|
|
20
|
+
documentKekTargets: input.response.documentKekTargets,
|
|
21
|
+
documentManifest: input.response.accessManifest,
|
|
22
|
+
documentManifestContainerPaths: [[...input.containerProjection.path]],
|
|
23
|
+
documentManifestHistory: [],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=createProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createProjection.js","sourceRoot":"","sources":["createProjection.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,MAAM,UAAU,0CAA0C,CAAC,KAG1D;IACC,OAAO;QACL,cAAc,EAAE,KAAK,CAAC,mBAAmB,CAAC,cAAc;QACxD,yBAAyB,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC;QACtD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,gBAAgB;QACjD,gCAAgC,EAAE;YAChC,GAAG,KAAK,CAAC,mBAAmB,CAAC,IAAI;YACjC,GAAG,KAAK,CAAC,mBAAmB,CAAC,aAAa,CAAC,OAAO,CAChD,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,wBAAwB,CACtC;SACF;QACD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE;QAC7B,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,kBAAkB;QACrD,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc;QAC/C,8BAA8B,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACrE,uBAAuB,EAAE,EAAE;KAC5B,CAAC;AACJ,CAAC","sourcesContent":["import type {\n ContainerWriterProjectionResponse,\n DocumentCreateResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\n\n/**\n * Build the writer projection a document-create response establishes, from the\n * container projection the create was authored against plus the manifest,\n * content-key bundle, and KEK targets the server just returned. This is the\n * same material a cold `GET /documents/:id/writer-projection` would yield, so\n * seeding it lets the first read after a create resolve locally. Shared by the\n * plain document-create path and the container-with-metadata-document path,\n * whose response carries an equivalent `DocumentCreateResponse`.\n */\nexport function documentWriterProjectionFromCreateResponse(input: {\n containerProjection: ContainerWriterProjectionResponse;\n response: DocumentCreateResponse;\n}): DocumentWriterProjectionResponse {\n return {\n policyEvidence: input.containerProjection.policyEvidence,\n authorizingContainerPaths: [input.containerProjection],\n contentKeyBundle: input.response.contentKeyBundle,\n documentContainerManifestHistory: [\n ...input.containerProjection.path,\n ...input.containerProjection.containerKeks.flatMap(\n (kek) => kek.containerManifestHistory,\n ),\n ],\n documentId: input.response.id,\n documentKekTargets: input.response.documentKekTargets,\n documentManifest: input.response.accessManifest,\n documentManifestContainerPaths: [[...input.containerProjection.path]],\n documentManifestHistory: [],\n };\n}\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { acknowledgeDocumentMutation } from "../../data/documents/shared/mutationAcknowledgement.js";
|
|
2
|
+
import { assertDocumentWriterProjectionConsistent } from "../../data/documents/shared/projection.js";
|
|
3
|
+
import { persistedDocumentCreateStateFromResponse } from "../../data/documents/shared/responses.js";
|
|
4
|
+
import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
|
|
5
|
+
import { nullOnProjectionVerificationCancellation } from "../../data/keyingProjectionVerification/types.js";
|
|
6
|
+
import { adoptExistingRemoteDocument } from "./createAdoption.js";
|
|
7
|
+
import { documentWriterProjectionFromCreateResponse } from "./createProjection.js";
|
|
8
|
+
/** A matched acknowledgement remains committed if authorization evidence races. */
|
|
9
|
+
export async function acknowledgeRemoteDocumentCreate(input) {
|
|
10
|
+
const { materializedPlan, response } = input;
|
|
11
|
+
const persistedState = persistedDocumentCreateStateFromResponse(materializedPlan.plan, response);
|
|
12
|
+
await acknowledgeDocumentMutation({
|
|
13
|
+
execSql: input.execSql,
|
|
14
|
+
plan: materializedPlan.plan,
|
|
15
|
+
stillCurrent: input.stillCurrent,
|
|
16
|
+
});
|
|
17
|
+
if (input.stillCurrent?.() === false)
|
|
18
|
+
return null;
|
|
19
|
+
const writerProjection = documentWriterProjectionFromCreateResponse(input);
|
|
20
|
+
try {
|
|
21
|
+
const targets = await nullOnProjectionVerificationCancellation(() => assertDocumentWriterProjectionConsistent(writerProjection, input));
|
|
22
|
+
if (!targets || input.stillCurrent?.() === false)
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (!(error instanceof ProjectionDependencyUnavailableError))
|
|
27
|
+
throw error;
|
|
28
|
+
// A principal pin can advance while POST is in flight. Recover the already
|
|
29
|
+
// committed document from fresh evidence, without submitting another create.
|
|
30
|
+
// The adoption path still verifies its author, scope, chain and key binding.
|
|
31
|
+
return nullOnProjectionVerificationCancellation(() => adoptExistingRemoteDocument({
|
|
32
|
+
...input,
|
|
33
|
+
documentId: response.id,
|
|
34
|
+
expectedContainerId: input.containerProjection.containerId,
|
|
35
|
+
expectedOrganizationId: input.containerProjection.organizationId,
|
|
36
|
+
expectedSignerUserId: input.author.signerUserId,
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
input.apiClient.primeDocumentWriterProjection(response.id, writerProjection);
|
|
40
|
+
return {
|
|
41
|
+
contentKey: materializedPlan.contentKey,
|
|
42
|
+
documentId: response.id,
|
|
43
|
+
persistedState,
|
|
44
|
+
plan: materializedPlan.plan,
|
|
45
|
+
response,
|
|
46
|
+
writerProjection,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=createResponse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createResponse.js","sourceRoot":"","sources":["createResponse.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qDAAqD,CAAC;AAClG,OAAO,EAAE,wCAAwC,EAAE,MAAM,wCAAwC,CAAC;AAClG,OAAO,EAAE,wCAAwC,EAAE,MAAM,uCAAuC,CAAC;AASjG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,wCAAwC,EAAE,MAAM,+CAA+C,CAAC;AAEzG,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,0CAA0C,EAAE,MAAM,oBAAoB,CAAC;AAEhF,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,KASiC;IAEjC,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAC7C,MAAM,cAAc,GAAG,wCAAwC,CAC7D,gBAAgB,CAAC,IAAI,EACrB,QAAQ,CACT,CAAC;IACF,MAAM,2BAA2B,CAAC;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,gBAAgB,CAAC,IAAI;QAC3B,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,gBAAgB,GAAG,0CAA0C,CAAC,KAAK,CAAC,CAAC;IAC3E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,wCAAwC,CAAC,GAAG,EAAE,CAClE,wCAAwC,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAClE,CAAC;QACF,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;YAAE,OAAO,IAAI,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,oCAAoC,CAAC;YAAE,MAAM,KAAK,CAAC;QAC1E,2EAA2E;QAC3E,6EAA6E;QAC7E,6EAA6E;QAC7E,OAAO,wCAAwC,CAAC,GAAG,EAAE,CACnD,2BAA2B,CAAC;YAC1B,GAAG,KAAK;YACR,UAAU,EAAE,QAAQ,CAAC,EAAE;YACvB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,CAAC,WAAW;YAC1D,sBAAsB,EAAE,KAAK,CAAC,mBAAmB,CAAC,cAAc;YAChE,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY;SAChD,CAAC,CACH,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,SAAS,CAAC,6BAA6B,CAAC,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC7E,OAAO;QACL,UAAU,EAAE,gBAAgB,CAAC,UAAU;QACvC,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,cAAc;QACd,IAAI,EAAE,gBAAgB,CAAC,IAAI;QAC3B,QAAQ;QACR,gBAAgB;KACjB,CAAC;AACJ,CAAC","sourcesContent":["import type {\n ContainerWriterProjectionResponse,\n DocumentCreateResponse,\n} from \"@tearleads/validators/response\";\nimport { acknowledgeDocumentMutation } from \"../../data/documents/shared/mutationAcknowledgement\";\nimport { assertDocumentWriterProjectionConsistent } from \"../../data/documents/shared/projection\";\nimport { persistedDocumentCreateStateFromResponse } from \"../../data/documents/shared/responses\";\nimport type {\n CreateRemoteDocumentResult,\n DocumentCreateApi,\n DocumentCreateAuthor,\n MaterializedDocumentCreatePlan,\n ProjectionVerificationOptions,\n} from \"../../data/documents/shared/types\";\nimport type { ProjectionUserKeyResolver } from \"../../data/keyingProjectionVerification\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { nullOnProjectionVerificationCancellation } from \"../../data/keyingProjectionVerification/types\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { adoptExistingRemoteDocument } from \"./createAdoption\";\nimport { documentWriterProjectionFromCreateResponse } from \"./createProjection\";\n\n/** A matched acknowledgement remains committed if authorization evidence races. */\nexport async function acknowledgeRemoteDocumentCreate(\n input: {\n readonly apiClient: DocumentCreateApi;\n readonly author: DocumentCreateAuthor;\n readonly containerProjection: ContainerWriterProjectionResponse;\n readonly execSql: ExecSql;\n readonly materializedPlan: MaterializedDocumentCreatePlan;\n readonly resolveProjectionUserKey: ProjectionUserKeyResolver;\n readonly response: DocumentCreateResponse;\n readonly targetSecretKey: Uint8Array;\n } & ProjectionVerificationOptions,\n): Promise<CreateRemoteDocumentResult | null> {\n const { materializedPlan, response } = input;\n const persistedState = persistedDocumentCreateStateFromResponse(\n materializedPlan.plan,\n response,\n );\n await acknowledgeDocumentMutation({\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n });\n if (input.stillCurrent?.() === false) return null;\n const writerProjection = documentWriterProjectionFromCreateResponse(input);\n try {\n const targets = await nullOnProjectionVerificationCancellation(() =>\n assertDocumentWriterProjectionConsistent(writerProjection, input),\n );\n if (!targets || input.stillCurrent?.() === false) return null;\n } catch (error) {\n if (!(error instanceof ProjectionDependencyUnavailableError)) throw error;\n // A principal pin can advance while POST is in flight. Recover the already\n // committed document from fresh evidence, without submitting another create.\n // The adoption path still verifies its author, scope, chain and key binding.\n return nullOnProjectionVerificationCancellation(() =>\n adoptExistingRemoteDocument({\n ...input,\n documentId: response.id,\n expectedContainerId: input.containerProjection.containerId,\n expectedOrganizationId: input.containerProjection.organizationId,\n expectedSignerUserId: input.author.signerUserId,\n }),\n );\n }\n input.apiClient.primeDocumentWriterProjection(response.id, writerProjection);\n return {\n contentKey: materializedPlan.contentKey,\n documentId: response.id,\n persistedState,\n plan: materializedPlan.plan,\n response,\n writerProjection,\n };\n}\n"]}
|