@tearleads/client-sdk 0.1.116 → 0.1.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/keyingProjectionVerification/checkpoints/checkpointContext.d.ts +8 -1
- package/data/keyingProjectionVerification/checkpoints/checkpointContext.js +15 -0
- package/data/keyingProjectionVerification/checkpoints/checkpointContext.js.map +1 -1
- package/data/keyingProjectionVerification/container/containerProjectionVerification.js +3 -1
- package/data/keyingProjectionVerification/container/containerProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/document/documentProjectionVerification.js +2 -1
- package/data/keyingProjectionVerification/document/documentProjectionVerification.js.map +1 -1
- package/data/persistence/container-contents/containerContentsPersistence.js +14 -13
- package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
- package/data/persistence/documents/internal/ensureDocumentsSchema.js +10 -12
- package/data/persistence/documents/internal/ensureDocumentsSchema.js.map +1 -1
- package/data/persistence/verifiedCitations/citationScope.js +121 -0
- package/data/persistence/verifiedCitations/citationScope.js.map +1 -0
- package/data/persistence/verifiedCitations/kekLevelCitations.d.ts +33 -0
- package/data/persistence/verifiedCitations/kekLevelCitations.js +44 -0
- package/data/persistence/verifiedCitations/kekLevelCitations.js.map +1 -0
- package/data/persistence/verifiedManifestBundlePersistence.d.ts +17 -12
- package/data/persistence/verifiedManifestBundlePersistence.js +75 -104
- package/data/persistence/verifiedManifestBundlePersistence.js.map +1 -1
- package/data/sqlite/schema/containerSchema.d.ts +1 -0
- package/data/sqlite/schema/containerSchema.js +8 -1
- package/data/sqlite/schema/containerSchema.js.map +1 -1
- package/data/sqlite/schema/documentAttachmentSchema.d.ts +0 -2
- package/data/sqlite/schema/documentAttachmentSchema.js +0 -4
- package/data/sqlite/schema/documentAttachmentSchema.js.map +1 -1
- package/data/sqlite/schema/index.d.ts +2 -0
- package/data/sqlite/schema/index.js +10 -1
- package/data/sqlite/schema/index.js.map +1 -1
- package/data/sqlite/schema/principalPolicySchema.js +0 -1
- package/data/sqlite/schema/principalPolicySchema.js.map +1 -1
- package/data/sqlite/schema/verifiedManifestBundleSchema.d.ts +7 -2
- package/data/sqlite/schema/verifiedManifestBundleSchema.js +11 -4
- package/data/sqlite/schema/verifiedManifestBundleSchema.js.map +1 -1
- package/data/sqlite/sqlExec.d.ts +12 -0
- package/data/sqlite/sqlExec.js +47 -3
- package/data/sqlite/sqlExec.js.map +1 -1
- package/data/sqlite/sqlTableSchema.js +40 -15
- package/data/sqlite/sqlTableSchema.js.map +1 -1
- package/data/sqlite/sqlitePersistenceRuntime.js +18 -10
- package/data/sqlite/sqlitePersistenceRuntime.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +3 -2
- package/internal/api-client/ApiClient.js +3 -2
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/index.d.ts +1 -1
- package/internal/api-client/index.js.map +1 -1
- package/internal/api-client/types.d.ts +7 -0
- package/internal/api-client/types.js.map +1 -1
- package/internal/api-client/verifiedManifestCitations.d.ts +26 -9
- package/internal/api-client/verifiedManifestCitations.js +44 -25
- package/internal/api-client/verifiedManifestCitations.js.map +1 -1
- package/internal/api-client/writerProjectionRequests.js +21 -10
- package/internal/api-client/writerProjectionRequests.js.map +1 -1
- package/internal/crypto/index.d.ts +1 -1
- package/internal/crypto/index.js +1 -1
- package/internal/crypto/index.js.map +1 -1
- package/internal/crypto/keying/canonicalJsonGuard.d.ts +7 -0
- package/internal/crypto/keying/canonicalJsonGuard.js +20 -0
- package/internal/crypto/keying/canonicalJsonGuard.js.map +1 -1
- package/internal/crypto/keying/index.d.ts +1 -1
- package/internal/crypto/keying/index.js +1 -1
- package/internal/crypto/keying/index.js.map +1 -1
- package/internal/validators/knownManifestsRefinements.js +1 -1
- package/internal/validators/knownManifestsRefinements.js.map +1 -1
- package/internal/validators/operation/writerProjections.d.ts +42 -18
- package/internal/validators/response/container.d.ts +137 -16
- package/internal/validators/response/container.js +23 -2
- package/internal/validators/response/container.js.map +1 -1
- package/internal/validators/response/documentMutation.d.ts +20 -8
- package/internal/validators/response/index.d.ts +2 -2
- package/internal/validators/response/index.js +2 -2
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/writerProjectionWire.d.ts +19 -8
- package/internal/validators/response/writerProjectionWire.js +78 -20
- package/internal/validators/response/writerProjectionWire.js.map +1 -1
- package/internal/validators/util/index.d.ts +1 -1
- package/internal/validators/util/index.js +1 -1
- package/internal/validators/util/index.js.map +1 -1
- package/internal/validators/util/knownManifestWire.d.ts +13 -3
- package/internal/validators/util/knownManifestWire.js +37 -10
- package/internal/validators/util/knownManifestWire.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/remoteHydration/destination/destinationPrefetch.js +10 -5
- package/workflows/container-contents/remoteHydration/destination/destinationPrefetch.js.map +1 -1
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js +4 -6
- package/workflows/container-contents/remoteHydration/remoteContainers/remoteContainerPageHydration.js.map +1 -1
- package/workflows/container-contents/remoteHydration/types.d.ts +2 -2
- package/workflows/container-contents/remoteHydration/types.js.map +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AccessManifestCheckpoint, type VerifiedAccessManifestCheckpointEvidence, type VerifiedContainerAccessManifest, type VerifiedPrincipalPolicySelection } from "../../../internal/crypto/index.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type AccessManifestBundleWireResponse, type ContainerKeyingPathResponse } from "../../../internal/validators/response/index.js";
|
|
3
3
|
import type { DocumentPurgeCheckpoint } from "../../persistence/keyingCheckpoints/documentPurgeCheckpointPersistence.js";
|
|
4
4
|
import type { VerifiedManifestBundle } from "../../persistence/verifiedManifestBundlePersistence.js";
|
|
5
5
|
import type { PrincipalPolicyCheckpointEvidence } from "../../principals/principalPolicyEvidence.js";
|
|
@@ -32,6 +32,13 @@ export declare function observeAccessManifestCheckpoints(context: ProjectionChec
|
|
|
32
32
|
export declare function observeVerifiedProjectionBundles(context: ProjectionCheckpointContext, bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>, verifiedByHash: ReadonlyMap<string, {
|
|
33
33
|
readonly checkpoint: AccessManifestCheckpoint;
|
|
34
34
|
}>): void;
|
|
35
|
+
/**
|
|
36
|
+
* Records every KEK level of paths this verification accepted in full, so
|
|
37
|
+
* the finalizing transaction stores them for later citation by digest. A
|
|
38
|
+
* cited level is refilled from these bytes only when the API's current
|
|
39
|
+
* level has the same digest, and is verified again like a served one.
|
|
40
|
+
*/
|
|
41
|
+
export declare function observeVerifiedKekLevels(context: ProjectionCheckpointContext, paths: readonly ContainerKeyingPathResponse[]): void;
|
|
35
42
|
export declare function observePrincipalPolicy(context: ProjectionCheckpointContext, policy: PrincipalPolicyCheckpointEvidence, organizationId?: string | undefined): void;
|
|
36
43
|
export declare function commitProjectionCheckpoints(context: ProjectionCheckpointContext, input?: {
|
|
37
44
|
readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { containerKekWireLevel, } from "../../../internal/validators/response/index.js";
|
|
2
3
|
import { rememberVerifiedContainerHeads } from "../../containers/shared/heldContainerHeads.js";
|
|
3
4
|
import { PrincipalAuthorizationCheckpointUnavailableError } from "../../persistence/keyingCheckpoints/principalAuthorizationCheckpoints.js";
|
|
4
5
|
import { ProjectionDependencyUnavailableError } from "../dependencyUnavailable.js";
|
|
@@ -41,6 +42,20 @@ export function observeVerifiedProjectionBundles(context, bundlesByHash, verifie
|
|
|
41
42
|
context.verifiedBundles.push({ bundle, checkpoint: verified.checkpoint });
|
|
42
43
|
}
|
|
43
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Records every KEK level of paths this verification accepted in full, so
|
|
47
|
+
* the finalizing transaction stores them for later citation by digest. A
|
|
48
|
+
* cited level is refilled from these bytes only when the API's current
|
|
49
|
+
* level has the same digest, and is verified again like a served one.
|
|
50
|
+
*/
|
|
51
|
+
export function observeVerifiedKekLevels(context, paths) {
|
|
52
|
+
for (const path of paths)
|
|
53
|
+
for (const kek of path.containerKeks)
|
|
54
|
+
context.verifiedBundles.push({
|
|
55
|
+
kekLevel: containerKekWireLevel(kek),
|
|
56
|
+
organizationId: path.organizationId,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
44
59
|
export function observePrincipalPolicy(context, policy, organizationId) {
|
|
45
60
|
if (organizationId !== undefined &&
|
|
46
61
|
context.organizationId !== undefined &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpointContext.js","sourceRoot":"","sources":["checkpointContext.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedAccessManifestCheckpointEvidence,\n type VerifiedContainerAccessManifest,\n type VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport type { AccessManifestBundleWireResponse } from \"@tearleads/validators/response\";\nimport { rememberVerifiedContainerHeads } from \"../../containers/shared/heldContainerHeads\";\nimport type { DocumentPurgeCheckpoint } from \"../../persistence/keyingCheckpoints/documentPurgeCheckpointPersistence\";\nimport { PrincipalAuthorizationCheckpointUnavailableError } from \"../../persistence/keyingCheckpoints/principalAuthorizationCheckpoints\";\nimport type { VerifiedManifestBundle } from \"../../persistence/verifiedManifestBundlePersistence\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { ProjectionDependencyUnavailableError } from \"../dependencyUnavailable\";\nimport { projectionLifetimeGuard } from \"../projectionLifetimes\";\nimport { assertProjectionVerificationCurrent } from \"../types\";\nimport {\n enforceAccessManifestCheckpoints,\n validateAccessManifestCheckpoints,\n} from \"./accessManifestCheckpointEnforcement\";\nimport { matchesVerifiedBundleBytes } from \"./verifiedBundleBytes\";\n\nexport interface ProjectionCheckpointContext {\n readonly heldContainerHeads: VerifiedContainerAccessManifest[];\n readonly execSql: ExecSql;\n // Local checkpoints read during this verification, one read per object.\n readonly localCheckpoints: Map<string, AccessManifestCheckpoint | null>;\n organizationId?: string | undefined;\n readonly policies: PrincipalPolicyCheckpointEvidence[];\n readonly authorizationPolicies: VerifiedPrincipalPolicySelection[];\n // Served bundles whose manifests verified, stored at finalization.\n readonly verifiedBundles: VerifiedManifestBundle[];\n readonly verifiedHeads: VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: VerifiedAccessManifestCheckpointEvidence[];\n}\n\nexport function createProjectionCheckpointContext(input: {\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n}): ProjectionCheckpointContext {\n if (typeof input.execSql !== \"function\") {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection verification requires durable keying checkpoint storage\",\n );\n }\n\n return {\n heldContainerHeads: [],\n execSql: input.execSql,\n localCheckpoints: new Map(),\n organizationId: input.organizationId,\n policies: [],\n authorizationPolicies: [],\n verifiedBundles: [],\n verifiedHeads: [],\n verifiedManifests: [],\n };\n}\n\nexport function observeAccessManifestCheckpoints(\n context: ProjectionCheckpointContext,\n input: {\n readonly verifiedHeads: readonly VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: readonly VerifiedAccessManifestCheckpointEvidence[];\n },\n): void {\n context.verifiedHeads.push(...input.verifiedHeads);\n context.verifiedManifests.push(...input.verifiedManifests);\n}\n\n/**\n * Records each served bundle whose manifest this verification produced, so\n * the transaction finalizing the checkpoints also stores it for later\n * citation. A bundle the projection carried but verification never reached\n * is skipped.\n */\nexport function observeVerifiedProjectionBundles(\n context: ProjectionCheckpointContext,\n bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>,\n verifiedByHash: ReadonlyMap<\n string,\n { readonly checkpoint: AccessManifestCheckpoint }\n >,\n): void {\n for (const [manifestHash, bundle] of bundlesByHash) {\n const verified = verifiedByHash.get(manifestHash);\n // A cache hit verifies the hash, not these bytes: store only bytes that\n // a fresh verification accepted, so a citation never replays others.\n if (verified && matchesVerifiedBundleBytes(verified, bundle))\n context.verifiedBundles.push({ bundle, checkpoint: verified.checkpoint });\n }\n}\n\nexport function observePrincipalPolicy(\n context: ProjectionCheckpointContext,\n policy: PrincipalPolicyCheckpointEvidence,\n organizationId?: string | undefined,\n): void {\n if (\n organizationId !== undefined &&\n context.organizationId !== undefined &&\n context.organizationId !== organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"projection checkpoint batch crosses organization ownership\",\n );\n }\n context.organizationId ??= organizationId;\n context.policies.push(policy);\n}\n\nexport async function commitProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input?: {\n readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n input = {\n ...input,\n stillCurrent: projectionLifetimeGuard(context, input?.stillCurrent),\n };\n assertProjectionVerificationCurrent(input?.stillCurrent);\n await enforceAccessManifestCheckpoints({\n documentPurgeCheckpoint: input?.documentPurgeCheckpoint,\n execSql: input?.execSql ?? context.execSql,\n organizationId: context.organizationId,\n policies: context.policies,\n authorizationPolicies: context.authorizationPolicies,\n stillCurrent: input?.stillCurrent,\n verifiedBundles: context.verifiedBundles,\n verifiedHeads: context.verifiedHeads,\n verifiedManifests: context.verifiedManifests,\n }).catch((error: unknown) => {\n if (error instanceof PrincipalAuthorizationCheckpointUnavailableError)\n throw new ProjectionDependencyUnavailableError(error.message);\n throw error;\n });\n assertProjectionVerificationCurrent(input?.stillCurrent);\n}\n\n/** Validates against the latest durable pins without persisting new heads. */\nasync function validateProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input?: {\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n input = {\n ...input,\n stillCurrent: projectionLifetimeGuard(context, input?.stillCurrent),\n };\n assertProjectionVerificationCurrent(input?.stillCurrent);\n await validateAccessManifestCheckpoints({\n execSql: input?.execSql ?? context.execSql,\n policies: context.policies,\n authorizationPolicies: context.authorizationPolicies,\n stillCurrent: input?.stillCurrent,\n verifiedBundles: context.verifiedBundles,\n verifiedHeads: context.verifiedHeads,\n verifiedManifests: context.verifiedManifests,\n }).catch((error: unknown) => {\n if (error instanceof PrincipalAuthorizationCheckpointUnavailableError)\n throw new ProjectionDependencyUnavailableError(error.message);\n throw error;\n });\n assertProjectionVerificationCurrent(input?.stillCurrent);\n}\n\nexport async function finalizeProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input: {\n readonly execSql?: ExecSql | undefined;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n if (input.persistVerificationCheckpoints === false) {\n await validateProjectionCheckpoints(context, input);\n return;\n }\n await commitProjectionCheckpoints(context, input);\n if (input.stillCurrent?.() === false) return;\n const organizationId =\n context.organizationId ??\n context.heldContainerHeads[0]?.state.organizationId;\n if (organizationId === undefined) return;\n try {\n rememberVerifiedContainerHeads({\n organizationId,\n execSql: input.execSql ?? context.execSql,\n heads: context.heldContainerHeads,\n policies: context.policies,\n });\n } catch {\n // Checkpoints are already committed. Optional re-citation evidence must\n // never change successful verification into a caller-visible refusal.\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"checkpointContext.js","sourceRoot":"","sources":["checkpointContext.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n KeyingVerificationError,\n type VerifiedAccessManifestCheckpointEvidence,\n type VerifiedContainerAccessManifest,\n type VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport {\n type AccessManifestBundleWireResponse,\n type ContainerKeyingPathResponse,\n containerKekWireLevel,\n} from \"@tearleads/validators/response\";\nimport { rememberVerifiedContainerHeads } from \"../../containers/shared/heldContainerHeads\";\nimport type { DocumentPurgeCheckpoint } from \"../../persistence/keyingCheckpoints/documentPurgeCheckpointPersistence\";\nimport { PrincipalAuthorizationCheckpointUnavailableError } from \"../../persistence/keyingCheckpoints/principalAuthorizationCheckpoints\";\nimport type { VerifiedManifestBundle } from \"../../persistence/verifiedManifestBundlePersistence\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { ProjectionDependencyUnavailableError } from \"../dependencyUnavailable\";\nimport { projectionLifetimeGuard } from \"../projectionLifetimes\";\nimport { assertProjectionVerificationCurrent } from \"../types\";\nimport {\n enforceAccessManifestCheckpoints,\n validateAccessManifestCheckpoints,\n} from \"./accessManifestCheckpointEnforcement\";\nimport { matchesVerifiedBundleBytes } from \"./verifiedBundleBytes\";\n\nexport interface ProjectionCheckpointContext {\n readonly heldContainerHeads: VerifiedContainerAccessManifest[];\n readonly execSql: ExecSql;\n // Local checkpoints read during this verification, one read per object.\n readonly localCheckpoints: Map<string, AccessManifestCheckpoint | null>;\n organizationId?: string | undefined;\n readonly policies: PrincipalPolicyCheckpointEvidence[];\n readonly authorizationPolicies: VerifiedPrincipalPolicySelection[];\n // Served bundles whose manifests verified, and KEK levels of verified\n // paths, stored at finalization.\n readonly verifiedBundles: VerifiedManifestBundle[];\n readonly verifiedHeads: VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: VerifiedAccessManifestCheckpointEvidence[];\n}\n\nexport function createProjectionCheckpointContext(input: {\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n}): ProjectionCheckpointContext {\n if (typeof input.execSql !== \"function\") {\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection verification requires durable keying checkpoint storage\",\n );\n }\n\n return {\n heldContainerHeads: [],\n execSql: input.execSql,\n localCheckpoints: new Map(),\n organizationId: input.organizationId,\n policies: [],\n authorizationPolicies: [],\n verifiedBundles: [],\n verifiedHeads: [],\n verifiedManifests: [],\n };\n}\n\nexport function observeAccessManifestCheckpoints(\n context: ProjectionCheckpointContext,\n input: {\n readonly verifiedHeads: readonly VerifiedAccessManifestCheckpointEvidence[];\n readonly verifiedManifests: readonly VerifiedAccessManifestCheckpointEvidence[];\n },\n): void {\n context.verifiedHeads.push(...input.verifiedHeads);\n context.verifiedManifests.push(...input.verifiedManifests);\n}\n\n/**\n * Records each served bundle whose manifest this verification produced, so\n * the transaction finalizing the checkpoints also stores it for later\n * citation. A bundle the projection carried but verification never reached\n * is skipped.\n */\nexport function observeVerifiedProjectionBundles(\n context: ProjectionCheckpointContext,\n bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>,\n verifiedByHash: ReadonlyMap<\n string,\n { readonly checkpoint: AccessManifestCheckpoint }\n >,\n): void {\n for (const [manifestHash, bundle] of bundlesByHash) {\n const verified = verifiedByHash.get(manifestHash);\n // A cache hit verifies the hash, not these bytes: store only bytes that\n // a fresh verification accepted, so a citation never replays others.\n if (verified && matchesVerifiedBundleBytes(verified, bundle))\n context.verifiedBundles.push({ bundle, checkpoint: verified.checkpoint });\n }\n}\n\n/**\n * Records every KEK level of paths this verification accepted in full, so\n * the finalizing transaction stores them for later citation by digest. A\n * cited level is refilled from these bytes only when the API's current\n * level has the same digest, and is verified again like a served one.\n */\nexport function observeVerifiedKekLevels(\n context: ProjectionCheckpointContext,\n paths: readonly ContainerKeyingPathResponse[],\n): void {\n for (const path of paths)\n for (const kek of path.containerKeks)\n context.verifiedBundles.push({\n kekLevel: containerKekWireLevel(kek),\n organizationId: path.organizationId,\n });\n}\n\nexport function observePrincipalPolicy(\n context: ProjectionCheckpointContext,\n policy: PrincipalPolicyCheckpointEvidence,\n organizationId?: string | undefined,\n): void {\n if (\n organizationId !== undefined &&\n context.organizationId !== undefined &&\n context.organizationId !== organizationId\n ) {\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"projection checkpoint batch crosses organization ownership\",\n );\n }\n context.organizationId ??= organizationId;\n context.policies.push(policy);\n}\n\nexport async function commitProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input?: {\n readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n input = {\n ...input,\n stillCurrent: projectionLifetimeGuard(context, input?.stillCurrent),\n };\n assertProjectionVerificationCurrent(input?.stillCurrent);\n await enforceAccessManifestCheckpoints({\n documentPurgeCheckpoint: input?.documentPurgeCheckpoint,\n execSql: input?.execSql ?? context.execSql,\n organizationId: context.organizationId,\n policies: context.policies,\n authorizationPolicies: context.authorizationPolicies,\n stillCurrent: input?.stillCurrent,\n verifiedBundles: context.verifiedBundles,\n verifiedHeads: context.verifiedHeads,\n verifiedManifests: context.verifiedManifests,\n }).catch((error: unknown) => {\n if (error instanceof PrincipalAuthorizationCheckpointUnavailableError)\n throw new ProjectionDependencyUnavailableError(error.message);\n throw error;\n });\n assertProjectionVerificationCurrent(input?.stillCurrent);\n}\n\n/** Validates against the latest durable pins without persisting new heads. */\nasync function validateProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input?: {\n readonly execSql?: ExecSql | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n input = {\n ...input,\n stillCurrent: projectionLifetimeGuard(context, input?.stillCurrent),\n };\n assertProjectionVerificationCurrent(input?.stillCurrent);\n await validateAccessManifestCheckpoints({\n execSql: input?.execSql ?? context.execSql,\n policies: context.policies,\n authorizationPolicies: context.authorizationPolicies,\n stillCurrent: input?.stillCurrent,\n verifiedBundles: context.verifiedBundles,\n verifiedHeads: context.verifiedHeads,\n verifiedManifests: context.verifiedManifests,\n }).catch((error: unknown) => {\n if (error instanceof PrincipalAuthorizationCheckpointUnavailableError)\n throw new ProjectionDependencyUnavailableError(error.message);\n throw error;\n });\n assertProjectionVerificationCurrent(input?.stillCurrent);\n}\n\nexport async function finalizeProjectionCheckpoints(\n context: ProjectionCheckpointContext,\n input: {\n readonly execSql?: ExecSql | undefined;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n },\n): Promise<void> {\n if (input.persistVerificationCheckpoints === false) {\n await validateProjectionCheckpoints(context, input);\n return;\n }\n await commitProjectionCheckpoints(context, input);\n if (input.stillCurrent?.() === false) return;\n const organizationId =\n context.organizationId ??\n context.heldContainerHeads[0]?.state.organizationId;\n if (organizationId === undefined) return;\n try {\n rememberVerifiedContainerHeads({\n organizationId,\n execSql: input.execSql ?? context.execSql,\n heads: context.heldContainerHeads,\n policies: context.policies,\n });\n } catch {\n // Checkpoints are already committed. Optional re-citation evidence must\n // never change successful verification into a caller-visible refusal.\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { computeContainerKekRecipientTargetHash, computeContainerKeyEpochHash, toFingerprint, verifyContainerKekState, } from "../../../internal/crypto/index.js";
|
|
2
2
|
import { addBundleByHash } from "../checkpoints/bundleVerification.js";
|
|
3
|
-
import { createProjectionCheckpointContext, finalizeProjectionCheckpoints, observeAccessManifestCheckpoints, observeVerifiedProjectionBundles, } from "../checkpoints/checkpointContext.js";
|
|
3
|
+
import { createProjectionCheckpointContext, finalizeProjectionCheckpoints, observeAccessManifestCheckpoints, observeVerifiedKekLevels, observeVerifiedProjectionBundles, } from "../checkpoints/checkpointContext.js";
|
|
4
4
|
import { ProjectionDependencyUnavailableError } from "../dependencyUnavailable.js";
|
|
5
5
|
import { throwKeyingVerificationShapeFailure } from "../error.js";
|
|
6
6
|
import { collectReferencedPrincipalPolicies } from "../principalPolicy/principalPolicyVerification.js";
|
|
@@ -185,6 +185,7 @@ export async function verifyContainerWriterProjection(input) {
|
|
|
185
185
|
const verifiedPath = await verifyContainerWriterProjectionWithContext(guardedInput, checkpointContext);
|
|
186
186
|
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
187
187
|
observeVerifiedProjectionBundles(checkpointContext, collectContainerProjectionBundles(input.projection), verifiedByHash);
|
|
188
|
+
observeVerifiedKekLevels(checkpointContext, [input.projection]);
|
|
188
189
|
await finalizeProjectionCheckpoints(checkpointContext, input);
|
|
189
190
|
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
190
191
|
return verifiedPath;
|
|
@@ -222,6 +223,7 @@ export async function collectContainerWriterProjectionPrincipalPolicies(input) {
|
|
|
222
223
|
});
|
|
223
224
|
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
224
225
|
observeVerifiedProjectionBundles(checkpointContext, collectContainerProjectionBundles(input.projection), verifiedByHash);
|
|
226
|
+
observeVerifiedKekLevels(checkpointContext, [input.projection]);
|
|
225
227
|
await finalizeProjectionCheckpoints(checkpointContext, input);
|
|
226
228
|
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
227
229
|
return policies;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerProjectionVerification.js","sourceRoot":"","sources":["containerProjectionVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyAuthorization } from \"@tearleads/crypto\";\nimport {\n type ContainerUserRecipientKey,\n computeContainerKekRecipientTargetHash,\n computeContainerKeyEpochHash,\n toFingerprint,\n type VerifiedContainerAccessManifest,\n type VerifiedContainerKekState,\n verifyContainerKekState,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWireResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { addBundleByHash } from \"../checkpoints/bundleVerification\";\nimport {\n createProjectionCheckpointContext,\n finalizeProjectionCheckpoints,\n observeAccessManifestCheckpoints,\n observeVerifiedProjectionBundles,\n type ProjectionCheckpointContext,\n} from \"../checkpoints/checkpointContext\";\nimport { ProjectionDependencyUnavailableError } from \"../dependencyUnavailable\";\nimport { throwKeyingVerificationShapeFailure } from \"../error\";\nimport { collectReferencedPrincipalPolicies } from \"../principalPolicy/principalPolicyVerification\";\nimport { verifyProjectionAuthorizationEvidence } from \"../principalPolicy/projectionAuthorizationEvidence\";\nimport {\n readContainerKekRecipientTarget,\n readContainerKeyEpoch,\n readContainerKeyWrap,\n} from \"../readers\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../types\";\nimport {\n assertProjectionVerificationCurrent,\n generationGuardedPrincipalPolicyWarmer,\n withGenerationGuardedPolicyWarmer,\n} from \"../types\";\nimport { verifyContainerManifestBundle } from \"./containerManifestVerification\";\nimport { verifyContainerManifestPath } from \"./containerPathVerification\";\n\nasync function collectContainerUserRecipientKeys(input: {\n readonly containerManifest: VerifiedContainerAccessManifest;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n}): Promise<ContainerUserRecipientKey[]> {\n const userIds = [\n ...new Set(\n input.containerManifest.state.directGrants\n .filter((grant) => grant.subjectType === \"user\")\n .map((grant) => grant.subjectId),\n ),\n ].sort();\n const userRecipientKeys: ContainerUserRecipientKey[] = [];\n\n for (const userId of userIds) {\n const userKey = await input.resolveUserKey(userId);\n if (!userKey) {\n throw new ProjectionDependencyUnavailableError(\n `Container writer projection recipient key could not be resolved for ${userId}`,\n );\n }\n const recipientKeyFingerprint = await toFingerprint(\n userKey.encapsulationPublicKey,\n );\n userRecipientKeys.push({\n userId,\n recipientKeyEpochId: `user:${userId}:encapsulation:${recipientKeyFingerprint}`,\n recipientKeyFingerprint,\n });\n }\n\n return userRecipientKeys;\n}\n\nfunction containerKekManifestHistory(input: {\n readonly history: readonly VerifiedContainerAccessManifest[];\n readonly verifiedManifest: VerifiedContainerAccessManifest;\n}): VerifiedContainerAccessManifest[] {\n const historyByHash = new Map<string, VerifiedContainerAccessManifest>();\n\n for (const manifest of input.history) {\n if (\n manifest.state.containerId === input.verifiedManifest.state.containerId &&\n manifest.manifestHash !== input.verifiedManifest.manifestHash\n ) {\n historyByHash.set(manifest.manifestHash, manifest);\n }\n }\n\n return [...historyByHash.values()];\n}\n\nasync function verifyContainerKekProjection(input: {\n readonly authorizationEvidence: readonly PrincipalPolicyAuthorization[];\n readonly kek: ContainerWriterProjectionResponse[\"containerKeks\"][number];\n readonly label: string;\n readonly parentKekState: VerifiedContainerKekState | null;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly verifiedManifest: VerifiedContainerAccessManifest;\n readonly verifiedManifestHistory: readonly VerifiedContainerAccessManifest[];\n readonly parentManifestHistory: readonly VerifiedContainerAccessManifest[];\n}): Promise<VerifiedContainerKekState> {\n if (input.verifiedManifest.state.parentContainerId && !input.parentKekState) {\n throw new Error(`${input.label} requires verified parent KEK state`);\n }\n\n const keyEpoch = readContainerKeyEpoch(\n input.kek.keyEpoch,\n `${input.label} key epoch`,\n );\n const wraps = input.kek.wraps.map((wrap, index) =>\n readContainerKeyWrap(wrap, `${input.label} wrap[${index}]`),\n );\n const userRecipientKeys = await collectContainerUserRecipientKeys({\n containerManifest: input.verifiedManifest,\n resolveUserKey: input.resolveUserKey,\n });\n const verifiedKekManifestHistory = containerKekManifestHistory({\n history: input.verifiedManifestHistory,\n verifiedManifest: input.verifiedManifest,\n });\n const verified = await verifyContainerKekState({\n allowHistoricalParentEpoch: true,\n containerManifest: input.verifiedManifest,\n containerManifestHistory: verifiedKekManifestHistory,\n parentManifestHistory: input.parentManifestHistory,\n keyEpoch,\n parentKekState: input.parentKekState,\n principalPolicies: input.authorizationEvidence,\n userRecipientKeys,\n wraps,\n });\n if (!verified.ok) {\n throw new Error(`${input.label} KEK verification failed`);\n }\n\n const keyEpochHash = await computeContainerKeyEpochHash(keyEpoch);\n if (keyEpochHash !== input.kek.keyEpochHash) {\n throw new Error(`${input.label} key epoch hash mismatch`);\n }\n const recipientTargets = input.kek.recipientTargets.map((target, index) =>\n readContainerKekRecipientTarget(\n target,\n `${input.label} recipient target[${index}]`,\n ),\n );\n const keyTargetHash =\n await computeContainerKekRecipientTargetHash(recipientTargets);\n if (\n keyTargetHash !== input.kek.keyTargetHash ||\n keyTargetHash !== verified.value.keyTargetHash\n ) {\n throw new Error(`${input.label} target hash mismatch`);\n }\n if (\n verified.value.containerKeyEpochId !== input.kek.containerKeyEpochId ||\n verified.value.containerKeyEpoch !== input.kek.containerKeyEpoch ||\n verified.value.accessManifestHash !== input.kek.accessManifestHash ||\n verified.value.parentContainerKeyEpochId !==\n input.kek.parentContainerKeyEpochId\n ) {\n throw new Error(`${input.label} identity mismatch`);\n }\n\n return verified.value;\n}\n\ninterface ContainerWriterProjectionVerificationInput {\n readonly execSql: ExecSql;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly principalPolicyCache?: PrincipalPolicyCache | undefined;\n readonly projection: ContainerWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly verifiedByHash?:\n | Map<string, VerifiedContainerAccessManifest>\n | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\nexport function verifiedContainerManifestsForBundles(\n bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>,\n verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>,\n): VerifiedContainerAccessManifest[] {\n return [...bundlesByHash.keys()].flatMap((manifestHash) => {\n const verified = verifiedByHash.get(manifestHash);\n return verified ? [verified] : [];\n });\n}\n\nfunction collectContainerProjectionBundles(\n projection: ContainerWriterProjectionResponse,\n): Map<string, AccessManifestBundleWireResponse> {\n const bundlesByHash = new Map<string, AccessManifestBundleWireResponse>();\n addContainerWriterProjectionBundles(\n bundlesByHash,\n projection,\n \"Container writer projection\",\n );\n return bundlesByHash;\n}\n\nexport async function verifyContainerWriterProjectionWithContext(\n input: Omit<ContainerWriterProjectionVerificationInput, \"execSql\"> & {\n readonly authorizationEvidence?: readonly PrincipalPolicyAuthorization[];\n },\n checkpointContext: ProjectionCheckpointContext,\n): Promise<VerifiedContainerAccessManifest[]> {\n if (input.projection.path.length !== input.projection.containerKeks.length) {\n throw new Error(\n \"Container writer projection path and KEKs are inconsistent\",\n );\n }\n\n const bundlesByHash = collectContainerProjectionBundles(input.projection);\n\n const verifiedByHash =\n input.verifiedByHash ?? new Map<string, VerifiedContainerAccessManifest>();\n const principalPolicyCache: PrincipalPolicyCache =\n input.principalPolicyCache ?? new Map();\n const verification = {\n checkpointContext,\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n };\n const authorizationEvidence =\n input.authorizationEvidence ??\n (await verifyProjectionAuthorizationEvidence({\n ...verification,\n bundles: [...bundlesByHash.values()],\n policyEvidence: input.projection.policyEvidence,\n organizationId: input.projection.organizationId,\n stillCurrent: input.stillCurrent,\n }));\n const verifiedPath = await verifyContainerManifestPath({\n ...verification,\n authorizationEvidence,\n requireAuthorizationEvidence: true,\n servedAsCurrent: true,\n bundlesByHash,\n enforceLocalCheckpoints: true,\n label: \"Container writer projection path\",\n path: input.projection.path,\n verifiedByHash,\n });\n\n const verifiedKekStates: VerifiedContainerKekState[] = [];\n for (const [index, kek] of input.projection.containerKeks.entries()) {\n const verifiedManifest = verifiedPath[index];\n if (!verifiedManifest) {\n throw new Error(`Container writer projection KEK[${index}] is missing`);\n }\n const verifiedManifestHistory: VerifiedContainerAccessManifest[] = [];\n for (const [\n historyIndex,\n bundle,\n ] of kek.containerManifestHistory.entries()) {\n verifiedManifestHistory.push(\n await verifyContainerManifestBundle({\n ...verification,\n authorizationEvidence,\n requireAuthorizationEvidence: true,\n bundle,\n bundlesByHash,\n enforceLocalCheckpoint: false,\n label: `Container writer projection KEK[${index}] history[${historyIndex}]`,\n parentPath: verifiedPath.slice(0, index),\n verifiedByHash,\n }),\n );\n }\n\n const verifiedKekState = await verifyContainerKekProjection({\n authorizationEvidence,\n kek,\n label: `Container writer projection KEK[${index}]`,\n parentKekState: index > 0 ? (verifiedKekStates[index - 1] ?? null) : null,\n resolveUserKey: input.resolveUserKey,\n verifiedManifest,\n verifiedManifestHistory,\n parentManifestHistory: [...verifiedByHash.values()],\n });\n verifiedKekStates.push(verifiedKekState);\n }\n\n observeAccessManifestCheckpoints(checkpointContext, {\n verifiedHeads: verifiedPath,\n verifiedManifests: verifiedContainerManifestsForBundles(\n bundlesByHash,\n verifiedByHash,\n ),\n });\n\n checkpointContext.heldContainerHeads.push(...verifiedPath);\n return verifiedPath;\n}\n\nexport async function verifyContainerWriterProjection(\n input: ContainerWriterProjectionVerificationInput,\n): Promise<VerifiedContainerAccessManifest[]> {\n try {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const verifiedByHash =\n input.verifiedByHash ??\n new Map<string, VerifiedContainerAccessManifest>();\n const guardedInput = {\n ...withGenerationGuardedPolicyWarmer(input),\n verifiedByHash,\n };\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n organizationId: input.projection.organizationId,\n });\n const verifiedPath = await verifyContainerWriterProjectionWithContext(\n guardedInput,\n checkpointContext,\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n observeVerifiedProjectionBundles(\n checkpointContext,\n collectContainerProjectionBundles(input.projection),\n verifiedByHash,\n );\n await finalizeProjectionCheckpoints(checkpointContext, input);\n assertProjectionVerificationCurrent(input.stillCurrent);\n return verifiedPath;\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n\nexport async function collectContainerWriterProjectionPrincipalPolicies(\n input: ContainerWriterProjectionVerificationInput,\n): Promise<PrincipalPolicyCurrentEvidence[]> {\n try {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const warmReferencedPrincipalPolicies =\n generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n );\n const principalPolicyCache: PrincipalPolicyCache =\n input.principalPolicyCache ?? new Map();\n const verifiedByHash =\n input.verifiedByHash ??\n new Map<string, VerifiedContainerAccessManifest>();\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n organizationId: input.projection.organizationId,\n });\n const verifiedPath = await verifyContainerWriterProjectionWithContext(\n {\n principalPolicyCache,\n projection: input.projection,\n verifiedByHash,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies,\n },\n checkpointContext,\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n\n const policies = await collectPrincipalPoliciesForContainerPaths({\n checkpointContext,\n organizationId: input.projection.organizationId,\n paths: [verifiedPath],\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n observeVerifiedProjectionBundles(\n checkpointContext,\n collectContainerProjectionBundles(input.projection),\n verifiedByHash,\n );\n await finalizeProjectionCheckpoints(checkpointContext, input);\n assertProjectionVerificationCurrent(input.stillCurrent);\n return policies;\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n\nexport function addContainerWriterProjectionBundles(\n bundlesByHash: Map<string, AccessManifestBundleWireResponse>,\n projection: ContainerWriterProjectionResponse,\n label: string,\n): void {\n for (const [index, bundle] of projection.path.entries()) {\n addBundleByHash(bundlesByHash, bundle, `${label} path[${index}]`);\n }\n for (const [kekIndex, kek] of projection.containerKeks.entries()) {\n for (const [\n historyIndex,\n bundle,\n ] of kek.containerManifestHistory.entries()) {\n addBundleByHash(\n bundlesByHash,\n bundle,\n `${label} KEK[${kekIndex}] history[${historyIndex}]`,\n );\n }\n }\n}\n\nasync function collectPrincipalPoliciesForContainerPaths(input: {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n paths: readonly (readonly VerifiedContainerAccessManifest[] | undefined)[];\n principalPolicyCache: PrincipalPolicyCache;\n resolveUserKey: ProjectionUserKeyResolver;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<PrincipalPolicyCurrentEvidence[]> {\n const referencedPrincipalHeads = input.paths.flatMap((path) =>\n (path ?? []).flatMap((manifest) => manifest.state.referencedPrincipalHeads),\n );\n\n return collectReferencedPrincipalPolicies({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n references: referencedPrincipalHeads,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"containerProjectionVerification.js","sourceRoot":"","sources":["containerProjectionVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyAuthorization } from \"@tearleads/crypto\";\nimport {\n type ContainerUserRecipientKey,\n computeContainerKekRecipientTargetHash,\n computeContainerKeyEpochHash,\n toFingerprint,\n type VerifiedContainerAccessManifest,\n type VerifiedContainerKekState,\n verifyContainerKekState,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWireResponse,\n ContainerWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { addBundleByHash } from \"../checkpoints/bundleVerification\";\nimport {\n createProjectionCheckpointContext,\n finalizeProjectionCheckpoints,\n observeAccessManifestCheckpoints,\n observeVerifiedKekLevels,\n observeVerifiedProjectionBundles,\n type ProjectionCheckpointContext,\n} from \"../checkpoints/checkpointContext\";\nimport { ProjectionDependencyUnavailableError } from \"../dependencyUnavailable\";\nimport { throwKeyingVerificationShapeFailure } from \"../error\";\nimport { collectReferencedPrincipalPolicies } from \"../principalPolicy/principalPolicyVerification\";\nimport { verifyProjectionAuthorizationEvidence } from \"../principalPolicy/projectionAuthorizationEvidence\";\nimport {\n readContainerKekRecipientTarget,\n readContainerKeyEpoch,\n readContainerKeyWrap,\n} from \"../readers\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../types\";\nimport {\n assertProjectionVerificationCurrent,\n generationGuardedPrincipalPolicyWarmer,\n withGenerationGuardedPolicyWarmer,\n} from \"../types\";\nimport { verifyContainerManifestBundle } from \"./containerManifestVerification\";\nimport { verifyContainerManifestPath } from \"./containerPathVerification\";\n\nasync function collectContainerUserRecipientKeys(input: {\n readonly containerManifest: VerifiedContainerAccessManifest;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n}): Promise<ContainerUserRecipientKey[]> {\n const userIds = [\n ...new Set(\n input.containerManifest.state.directGrants\n .filter((grant) => grant.subjectType === \"user\")\n .map((grant) => grant.subjectId),\n ),\n ].sort();\n const userRecipientKeys: ContainerUserRecipientKey[] = [];\n\n for (const userId of userIds) {\n const userKey = await input.resolveUserKey(userId);\n if (!userKey) {\n throw new ProjectionDependencyUnavailableError(\n `Container writer projection recipient key could not be resolved for ${userId}`,\n );\n }\n const recipientKeyFingerprint = await toFingerprint(\n userKey.encapsulationPublicKey,\n );\n userRecipientKeys.push({\n userId,\n recipientKeyEpochId: `user:${userId}:encapsulation:${recipientKeyFingerprint}`,\n recipientKeyFingerprint,\n });\n }\n\n return userRecipientKeys;\n}\n\nfunction containerKekManifestHistory(input: {\n readonly history: readonly VerifiedContainerAccessManifest[];\n readonly verifiedManifest: VerifiedContainerAccessManifest;\n}): VerifiedContainerAccessManifest[] {\n const historyByHash = new Map<string, VerifiedContainerAccessManifest>();\n\n for (const manifest of input.history) {\n if (\n manifest.state.containerId === input.verifiedManifest.state.containerId &&\n manifest.manifestHash !== input.verifiedManifest.manifestHash\n ) {\n historyByHash.set(manifest.manifestHash, manifest);\n }\n }\n\n return [...historyByHash.values()];\n}\n\nasync function verifyContainerKekProjection(input: {\n readonly authorizationEvidence: readonly PrincipalPolicyAuthorization[];\n readonly kek: ContainerWriterProjectionResponse[\"containerKeks\"][number];\n readonly label: string;\n readonly parentKekState: VerifiedContainerKekState | null;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly verifiedManifest: VerifiedContainerAccessManifest;\n readonly verifiedManifestHistory: readonly VerifiedContainerAccessManifest[];\n readonly parentManifestHistory: readonly VerifiedContainerAccessManifest[];\n}): Promise<VerifiedContainerKekState> {\n if (input.verifiedManifest.state.parentContainerId && !input.parentKekState) {\n throw new Error(`${input.label} requires verified parent KEK state`);\n }\n\n const keyEpoch = readContainerKeyEpoch(\n input.kek.keyEpoch,\n `${input.label} key epoch`,\n );\n const wraps = input.kek.wraps.map((wrap, index) =>\n readContainerKeyWrap(wrap, `${input.label} wrap[${index}]`),\n );\n const userRecipientKeys = await collectContainerUserRecipientKeys({\n containerManifest: input.verifiedManifest,\n resolveUserKey: input.resolveUserKey,\n });\n const verifiedKekManifestHistory = containerKekManifestHistory({\n history: input.verifiedManifestHistory,\n verifiedManifest: input.verifiedManifest,\n });\n const verified = await verifyContainerKekState({\n allowHistoricalParentEpoch: true,\n containerManifest: input.verifiedManifest,\n containerManifestHistory: verifiedKekManifestHistory,\n parentManifestHistory: input.parentManifestHistory,\n keyEpoch,\n parentKekState: input.parentKekState,\n principalPolicies: input.authorizationEvidence,\n userRecipientKeys,\n wraps,\n });\n if (!verified.ok) {\n throw new Error(`${input.label} KEK verification failed`);\n }\n\n const keyEpochHash = await computeContainerKeyEpochHash(keyEpoch);\n if (keyEpochHash !== input.kek.keyEpochHash) {\n throw new Error(`${input.label} key epoch hash mismatch`);\n }\n const recipientTargets = input.kek.recipientTargets.map((target, index) =>\n readContainerKekRecipientTarget(\n target,\n `${input.label} recipient target[${index}]`,\n ),\n );\n const keyTargetHash =\n await computeContainerKekRecipientTargetHash(recipientTargets);\n if (\n keyTargetHash !== input.kek.keyTargetHash ||\n keyTargetHash !== verified.value.keyTargetHash\n ) {\n throw new Error(`${input.label} target hash mismatch`);\n }\n if (\n verified.value.containerKeyEpochId !== input.kek.containerKeyEpochId ||\n verified.value.containerKeyEpoch !== input.kek.containerKeyEpoch ||\n verified.value.accessManifestHash !== input.kek.accessManifestHash ||\n verified.value.parentContainerKeyEpochId !==\n input.kek.parentContainerKeyEpochId\n ) {\n throw new Error(`${input.label} identity mismatch`);\n }\n\n return verified.value;\n}\n\ninterface ContainerWriterProjectionVerificationInput {\n readonly execSql: ExecSql;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly principalPolicyCache?: PrincipalPolicyCache | undefined;\n readonly projection: ContainerWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly verifiedByHash?:\n | Map<string, VerifiedContainerAccessManifest>\n | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}\n\nexport function verifiedContainerManifestsForBundles(\n bundlesByHash: ReadonlyMap<string, AccessManifestBundleWireResponse>,\n verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>,\n): VerifiedContainerAccessManifest[] {\n return [...bundlesByHash.keys()].flatMap((manifestHash) => {\n const verified = verifiedByHash.get(manifestHash);\n return verified ? [verified] : [];\n });\n}\n\nfunction collectContainerProjectionBundles(\n projection: ContainerWriterProjectionResponse,\n): Map<string, AccessManifestBundleWireResponse> {\n const bundlesByHash = new Map<string, AccessManifestBundleWireResponse>();\n addContainerWriterProjectionBundles(\n bundlesByHash,\n projection,\n \"Container writer projection\",\n );\n return bundlesByHash;\n}\n\nexport async function verifyContainerWriterProjectionWithContext(\n input: Omit<ContainerWriterProjectionVerificationInput, \"execSql\"> & {\n readonly authorizationEvidence?: readonly PrincipalPolicyAuthorization[];\n },\n checkpointContext: ProjectionCheckpointContext,\n): Promise<VerifiedContainerAccessManifest[]> {\n if (input.projection.path.length !== input.projection.containerKeks.length) {\n throw new Error(\n \"Container writer projection path and KEKs are inconsistent\",\n );\n }\n\n const bundlesByHash = collectContainerProjectionBundles(input.projection);\n\n const verifiedByHash =\n input.verifiedByHash ?? new Map<string, VerifiedContainerAccessManifest>();\n const principalPolicyCache: PrincipalPolicyCache =\n input.principalPolicyCache ?? new Map();\n const verification = {\n checkpointContext,\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n };\n const authorizationEvidence =\n input.authorizationEvidence ??\n (await verifyProjectionAuthorizationEvidence({\n ...verification,\n bundles: [...bundlesByHash.values()],\n policyEvidence: input.projection.policyEvidence,\n organizationId: input.projection.organizationId,\n stillCurrent: input.stillCurrent,\n }));\n const verifiedPath = await verifyContainerManifestPath({\n ...verification,\n authorizationEvidence,\n requireAuthorizationEvidence: true,\n servedAsCurrent: true,\n bundlesByHash,\n enforceLocalCheckpoints: true,\n label: \"Container writer projection path\",\n path: input.projection.path,\n verifiedByHash,\n });\n\n const verifiedKekStates: VerifiedContainerKekState[] = [];\n for (const [index, kek] of input.projection.containerKeks.entries()) {\n const verifiedManifest = verifiedPath[index];\n if (!verifiedManifest) {\n throw new Error(`Container writer projection KEK[${index}] is missing`);\n }\n const verifiedManifestHistory: VerifiedContainerAccessManifest[] = [];\n for (const [\n historyIndex,\n bundle,\n ] of kek.containerManifestHistory.entries()) {\n verifiedManifestHistory.push(\n await verifyContainerManifestBundle({\n ...verification,\n authorizationEvidence,\n requireAuthorizationEvidence: true,\n bundle,\n bundlesByHash,\n enforceLocalCheckpoint: false,\n label: `Container writer projection KEK[${index}] history[${historyIndex}]`,\n parentPath: verifiedPath.slice(0, index),\n verifiedByHash,\n }),\n );\n }\n\n const verifiedKekState = await verifyContainerKekProjection({\n authorizationEvidence,\n kek,\n label: `Container writer projection KEK[${index}]`,\n parentKekState: index > 0 ? (verifiedKekStates[index - 1] ?? null) : null,\n resolveUserKey: input.resolveUserKey,\n verifiedManifest,\n verifiedManifestHistory,\n parentManifestHistory: [...verifiedByHash.values()],\n });\n verifiedKekStates.push(verifiedKekState);\n }\n\n observeAccessManifestCheckpoints(checkpointContext, {\n verifiedHeads: verifiedPath,\n verifiedManifests: verifiedContainerManifestsForBundles(\n bundlesByHash,\n verifiedByHash,\n ),\n });\n\n checkpointContext.heldContainerHeads.push(...verifiedPath);\n return verifiedPath;\n}\n\nexport async function verifyContainerWriterProjection(\n input: ContainerWriterProjectionVerificationInput,\n): Promise<VerifiedContainerAccessManifest[]> {\n try {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const verifiedByHash =\n input.verifiedByHash ??\n new Map<string, VerifiedContainerAccessManifest>();\n const guardedInput = {\n ...withGenerationGuardedPolicyWarmer(input),\n verifiedByHash,\n };\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n organizationId: input.projection.organizationId,\n });\n const verifiedPath = await verifyContainerWriterProjectionWithContext(\n guardedInput,\n checkpointContext,\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n observeVerifiedProjectionBundles(\n checkpointContext,\n collectContainerProjectionBundles(input.projection),\n verifiedByHash,\n );\n observeVerifiedKekLevels(checkpointContext, [input.projection]);\n await finalizeProjectionCheckpoints(checkpointContext, input);\n assertProjectionVerificationCurrent(input.stillCurrent);\n return verifiedPath;\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n\nexport async function collectContainerWriterProjectionPrincipalPolicies(\n input: ContainerWriterProjectionVerificationInput,\n): Promise<PrincipalPolicyCurrentEvidence[]> {\n try {\n assertProjectionVerificationCurrent(input.stillCurrent);\n const warmReferencedPrincipalPolicies =\n generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n );\n const principalPolicyCache: PrincipalPolicyCache =\n input.principalPolicyCache ?? new Map();\n const verifiedByHash =\n input.verifiedByHash ??\n new Map<string, VerifiedContainerAccessManifest>();\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n organizationId: input.projection.organizationId,\n });\n const verifiedPath = await verifyContainerWriterProjectionWithContext(\n {\n principalPolicyCache,\n projection: input.projection,\n verifiedByHash,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies,\n },\n checkpointContext,\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n\n const policies = await collectPrincipalPoliciesForContainerPaths({\n checkpointContext,\n organizationId: input.projection.organizationId,\n paths: [verifiedPath],\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n observeVerifiedProjectionBundles(\n checkpointContext,\n collectContainerProjectionBundles(input.projection),\n verifiedByHash,\n );\n observeVerifiedKekLevels(checkpointContext, [input.projection]);\n await finalizeProjectionCheckpoints(checkpointContext, input);\n assertProjectionVerificationCurrent(input.stillCurrent);\n return policies;\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n\nexport function addContainerWriterProjectionBundles(\n bundlesByHash: Map<string, AccessManifestBundleWireResponse>,\n projection: ContainerWriterProjectionResponse,\n label: string,\n): void {\n for (const [index, bundle] of projection.path.entries()) {\n addBundleByHash(bundlesByHash, bundle, `${label} path[${index}]`);\n }\n for (const [kekIndex, kek] of projection.containerKeks.entries()) {\n for (const [\n historyIndex,\n bundle,\n ] of kek.containerManifestHistory.entries()) {\n addBundleByHash(\n bundlesByHash,\n bundle,\n `${label} KEK[${kekIndex}] history[${historyIndex}]`,\n );\n }\n }\n}\n\nasync function collectPrincipalPoliciesForContainerPaths(input: {\n checkpointContext: ProjectionCheckpointContext;\n organizationId: string;\n paths: readonly (readonly VerifiedContainerAccessManifest[] | undefined)[];\n principalPolicyCache: PrincipalPolicyCache;\n resolveUserKey: ProjectionUserKeyResolver;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<PrincipalPolicyCurrentEvidence[]> {\n const referencedPrincipalHeads = input.paths.flatMap((path) =>\n (path ?? []).flatMap((manifest) => manifest.state.referencedPrincipalHeads),\n );\n\n return collectReferencedPrincipalPolicies({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n references: referencedPrincipalHeads,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { addBundleByHash } from "../checkpoints/bundleVerification.js";
|
|
2
|
-
import { createProjectionCheckpointContext, finalizeProjectionCheckpoints, observeAccessManifestCheckpoints, observeVerifiedProjectionBundles, } from "../checkpoints/checkpointContext.js";
|
|
2
|
+
import { createProjectionCheckpointContext, finalizeProjectionCheckpoints, observeAccessManifestCheckpoints, observeVerifiedKekLevels, observeVerifiedProjectionBundles, } from "../checkpoints/checkpointContext.js";
|
|
3
3
|
import { verifyContainerManifestPath } from "../container/containerPathVerification.js";
|
|
4
4
|
import { addContainerWriterProjectionBundles, verifiedContainerManifestsForBundles, verifyContainerWriterProjectionWithContext, } from "../container/containerProjectionVerification.js";
|
|
5
5
|
import { rejectPurgedDocumentProjection } from "../documentPurge/documentPurgeCheckpointEnforcement.js";
|
|
@@ -145,6 +145,7 @@ function observeVerifiedDocumentProjectionBundles(checkpointContext, projection,
|
|
|
145
145
|
observeVerifiedProjectionBundles(checkpointContext, collectDocumentProjectionContainerBundles(projection), new Map([...authorization.containerPathByManifestHash.values()]
|
|
146
146
|
.flat()
|
|
147
147
|
.map((manifest) => [manifest.manifestHash, manifest])));
|
|
148
|
+
observeVerifiedKekLevels(checkpointContext, projection.authorizingContainerPaths);
|
|
148
149
|
}
|
|
149
150
|
export async function verifyDocumentWriterProjection(input) {
|
|
150
151
|
const checkpointContext = createProjectionCheckpointContext({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documentProjectionVerification.js","sourceRoot":"","sources":["documentProjectionVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PrincipalPolicyAuthorization,\n VerifiedContainerAccessManifest,\n VerifiedDocumentLinkSetManifest,\n VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWireResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { addBundleByHash } from \"../checkpoints/bundleVerification\";\nimport {\n createProjectionCheckpointContext,\n finalizeProjectionCheckpoints,\n observeAccessManifestCheckpoints,\n observeVerifiedProjectionBundles,\n type ProjectionCheckpointContext,\n} from \"../checkpoints/checkpointContext\";\nimport { verifyContainerManifestPath } from \"../container/containerPathVerification\";\nimport {\n addContainerWriterProjectionBundles,\n verifiedContainerManifestsForBundles,\n verifyContainerWriterProjectionWithContext,\n} from \"../container/containerProjectionVerification\";\nimport { rejectPurgedDocumentProjection } from \"../documentPurge/documentPurgeCheckpointEnforcement\";\nimport { throwKeyingVerificationShapeFailure } from \"../error\";\nimport { verifyProjectionAuthorizationEvidence } from \"../principalPolicy/projectionAuthorizationEvidence\";\nimport { readAccessManifest } from \"../readers\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../types\";\nimport { withGenerationGuardedPolicyWarmer } from \"../types\";\nimport { documentContainerProjections } from \"./documentContainerProjections\";\nimport { verifyDocumentProjectionManifests } from \"./documentManifestVerification\";\n\ntype VerifiedManifestMap = Map<string, VerifiedContainerAccessManifest>;\ntype PolicyWarmer = ReferencedPrincipalPolicyWarmer | undefined;\n\nfunction readDocumentProjectionContainerPaths(\n projection: DocumentWriterProjectionResponse,\n): AccessManifestBundleWireResponse[][] {\n return [\n ...projection.documentManifestContainerPaths,\n ...projection.authorizingContainerPaths.map((path) => path.path),\n ];\n}\n\nfunction collectDocumentProjectionContainerBundles(\n projection: DocumentWriterProjectionResponse,\n): Map<string, AccessManifestBundleWireResponse> {\n const bundlesByHash = new Map<string, AccessManifestBundleWireResponse>();\n for (const [index, authorizing] of documentContainerProjections(\n projection,\n ).entries()) {\n addContainerWriterProjectionBundles(\n bundlesByHash,\n authorizing,\n `Document writer projection authorizing path[${index}]`,\n );\n }\n for (const [index, path] of readDocumentProjectionContainerPaths(\n projection,\n ).entries()) {\n for (const [pathIndex, bundle] of path.entries()) {\n addBundleByHash(\n bundlesByHash,\n bundle,\n `Document writer projection dependency path[${index}][${pathIndex}]`,\n );\n }\n }\n for (const [\n index,\n bundle,\n ] of projection.documentContainerManifestHistory.entries()) {\n addBundleByHash(\n bundlesByHash,\n bundle,\n `Document writer projection container history[${index}]`,\n );\n }\n return bundlesByHash;\n}\n\nasync function verifyProjectionContainerPaths(input: {\n readonly authorizationEvidence: readonly PrincipalPolicyAuthorization[];\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly projection: DocumentWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly verifiedByHash?: VerifiedManifestMap | undefined;\n readonly warmReferencedPrincipalPolicies?: PolicyWarmer;\n}): Promise<Map<string, readonly VerifiedContainerAccessManifest[]>> {\n const bundlesByHash = collectDocumentProjectionContainerBundles(\n input.projection,\n );\n const containerPathByManifestHash = new Map<\n string,\n readonly VerifiedContainerAccessManifest[]\n >();\n // Reuse a caller-supplied cache when provided so a later unwrap pass over the\n // same authorizing container paths does not re-verify identical manifests.\n const verifiedByHash =\n input.verifiedByHash ?? new Map<string, VerifiedContainerAccessManifest>();\n for (const projection of documentContainerProjections(input.projection)) {\n const path = await verifyContainerWriterProjectionWithContext(\n {\n authorizationEvidence: input.authorizationEvidence,\n principalPolicyCache: input.principalPolicyCache,\n projection,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n },\n input.checkpointContext,\n );\n const leaf = path.at(-1);\n if (leaf) {\n containerPathByManifestHash.set(leaf.manifestHash, path);\n }\n for (const manifest of path) {\n verifiedByHash.set(manifest.manifestHash, manifest);\n }\n }\n // Grouping supplies evidence only; each signed artifact selects its citations.\n for (const [\n index,\n path,\n ] of input.projection.documentManifestContainerPaths.entries()) {\n // Historical dependency evidence is verified without current checkpoint\n // enforcement. Its grouping cannot substitute an uncited ancestor into\n // document or content-write authorization.\n const verifiedPath = await verifyContainerManifestPath({\n authorizationEvidence: input.authorizationEvidence,\n requireAuthorizationEvidence: true,\n servedAsCurrent: false,\n authorizationMembership: \"referenced\",\n bundlesByHash,\n checkpointContext: input.checkpointContext,\n enforceLocalCheckpoints: false,\n label: `Document writer projection dependency path[${index}]`,\n path,\n principalPolicyCache: input.principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // The authorizing path recorded for the same leaf takes precedence.\n const leaf = verifiedPath.at(-1);\n if (leaf && !containerPathByManifestHash.has(leaf.manifestHash)) {\n containerPathByManifestHash.set(leaf.manifestHash, verifiedPath);\n }\n }\n\n // Keep every verified head as evidence. Events and content headers select\n // their own signed paths through resolveEventContainerPaths.\n for (const [hash, manifest] of verifiedByHash) {\n if (!containerPathByManifestHash.has(hash))\n containerPathByManifestHash.set(hash, [manifest]);\n }\n\n observeAccessManifestCheckpoints(input.checkpointContext, {\n verifiedHeads: [],\n verifiedManifests: verifiedContainerManifestsForBundles(\n bundlesByHash,\n verifiedByHash,\n ),\n });\n\n return containerPathByManifestHash;\n}\n\ninterface DocumentWriterProjectionVerificationInput {\n readonly execSql: ExecSql;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly principalPolicyCache?: PrincipalPolicyCache | undefined;\n readonly projection: DocumentWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly verifiedByHash?: VerifiedManifestMap | undefined;\n readonly warmReferencedPrincipalPolicies?: PolicyWarmer;\n}\nexport interface DocumentWriterProjectionAuthorization {\n readonly containerPathByManifestHash: ReadonlyMap<\n string,\n readonly VerifiedContainerAccessManifest[]\n >;\n readonly documentManifestByHash: ReadonlyMap<\n string,\n VerifiedDocumentLinkSetManifest\n >;\n readonly principalPolicies: readonly PrincipalPolicyAuthorization[];\n}\n\ninterface VerifiedDocumentWriterProjectionResult {\n readonly authorization: DocumentWriterProjectionAuthorization;\n readonly headManifest: VerifiedDocumentLinkSetManifest;\n}\n\nasync function verifyDocumentWriterProjectionWithContext(\n input: Omit<DocumentWriterProjectionVerificationInput, \"execSql\">,\n checkpointContext: ProjectionCheckpointContext,\n): Promise<VerifiedDocumentWriterProjectionResult> {\n const principalPolicyCache =\n input.principalPolicyCache ?? new Map<string, VerifiedPrincipalPolicy>();\n const authorizationEvidence = await verifyProjectionAuthorizationEvidence({\n bundles: [\n input.projection.documentManifest,\n ...input.projection.documentManifestHistory,\n ...collectDocumentProjectionContainerBundles(input.projection).values(),\n ],\n checkpointContext,\n policyEvidence: input.projection.policyEvidence,\n organizationId: readAccessManifest(\n input.projection.documentManifest.manifest,\n \"Document projection manifest\",\n ).organizationId,\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const containerPathByManifestHash = await verifyProjectionContainerPaths({\n authorizationEvidence,\n checkpointContext,\n principalPolicyCache,\n projection: input.projection,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash: input.verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const { headManifest, verifiedByHash } =\n await verifyDocumentProjectionManifests({\n authorizationEvidence,\n checkpointContext,\n containerPathByManifestHash,\n principalPolicyCache,\n projection: input.projection,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await rejectPurgedDocumentProjection(\n headManifest.state.documentId,\n checkpointContext.execSql,\n );\n\n observeAccessManifestCheckpoints(checkpointContext, {\n verifiedHeads: [headManifest],\n verifiedManifests: [...verifiedByHash.values()],\n });\n\n return {\n authorization: {\n containerPathByManifestHash,\n documentManifestByHash: verifiedByHash,\n principalPolicies: authorizationEvidence,\n },\n headManifest,\n };\n}\n\n/** Each served bundle, document and container, whose manifest verified. */\nfunction observeVerifiedDocumentProjectionBundles(\n checkpointContext: ProjectionCheckpointContext,\n projection: DocumentWriterProjectionResponse,\n authorization: DocumentWriterProjectionAuthorization,\n): void {\n observeVerifiedProjectionBundles(\n checkpointContext,\n new Map(\n [projection.documentManifest, ...projection.documentManifestHistory].map(\n (bundle) => [bundle.manifestHash, bundle],\n ),\n ),\n authorization.documentManifestByHash,\n );\n observeVerifiedProjectionBundles(\n checkpointContext,\n collectDocumentProjectionContainerBundles(projection),\n new Map(\n [...authorization.containerPathByManifestHash.values()]\n .flat()\n .map((manifest) => [manifest.manifestHash, manifest]),\n ),\n );\n}\n\nexport async function verifyDocumentWriterProjection(\n input: DocumentWriterProjectionVerificationInput,\n): Promise<VerifiedDocumentLinkSetManifest> {\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n });\n const verified = await verifyDocumentWriterProjectionWithContext(\n withGenerationGuardedPolicyWarmer(input),\n checkpointContext,\n );\n observeVerifiedDocumentProjectionBundles(\n checkpointContext,\n input.projection,\n verified.authorization,\n );\n await finalizeProjectionCheckpoints(checkpointContext, input);\n return verified.headManifest;\n}\n\nexport async function verifyDocumentWriterProjectionAuthorization(\n input: DocumentWriterProjectionVerificationInput,\n): Promise<DocumentWriterProjectionAuthorization> {\n try {\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n });\n const verified = await verifyDocumentWriterProjectionWithContext(\n withGenerationGuardedPolicyWarmer(input),\n checkpointContext,\n );\n observeVerifiedDocumentProjectionBundles(\n checkpointContext,\n input.projection,\n verified.authorization,\n );\n await finalizeProjectionCheckpoints(checkpointContext, input);\n return verified.authorization;\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"documentProjectionVerification.js","sourceRoot":"","sources":["documentProjectionVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PrincipalPolicyAuthorization,\n VerifiedContainerAccessManifest,\n VerifiedDocumentLinkSetManifest,\n VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWireResponse,\n DocumentWriterProjectionResponse,\n} from \"@tearleads/validators/response\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport { addBundleByHash } from \"../checkpoints/bundleVerification\";\nimport {\n createProjectionCheckpointContext,\n finalizeProjectionCheckpoints,\n observeAccessManifestCheckpoints,\n observeVerifiedKekLevels,\n observeVerifiedProjectionBundles,\n type ProjectionCheckpointContext,\n} from \"../checkpoints/checkpointContext\";\nimport { verifyContainerManifestPath } from \"../container/containerPathVerification\";\nimport {\n addContainerWriterProjectionBundles,\n verifiedContainerManifestsForBundles,\n verifyContainerWriterProjectionWithContext,\n} from \"../container/containerProjectionVerification\";\nimport { rejectPurgedDocumentProjection } from \"../documentPurge/documentPurgeCheckpointEnforcement\";\nimport { throwKeyingVerificationShapeFailure } from \"../error\";\nimport { verifyProjectionAuthorizationEvidence } from \"../principalPolicy/projectionAuthorizationEvidence\";\nimport { readAccessManifest } from \"../readers\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"../types\";\nimport { withGenerationGuardedPolicyWarmer } from \"../types\";\nimport { documentContainerProjections } from \"./documentContainerProjections\";\nimport { verifyDocumentProjectionManifests } from \"./documentManifestVerification\";\n\ntype VerifiedManifestMap = Map<string, VerifiedContainerAccessManifest>;\ntype PolicyWarmer = ReferencedPrincipalPolicyWarmer | undefined;\n\nfunction readDocumentProjectionContainerPaths(\n projection: DocumentWriterProjectionResponse,\n): AccessManifestBundleWireResponse[][] {\n return [\n ...projection.documentManifestContainerPaths,\n ...projection.authorizingContainerPaths.map((path) => path.path),\n ];\n}\n\nfunction collectDocumentProjectionContainerBundles(\n projection: DocumentWriterProjectionResponse,\n): Map<string, AccessManifestBundleWireResponse> {\n const bundlesByHash = new Map<string, AccessManifestBundleWireResponse>();\n for (const [index, authorizing] of documentContainerProjections(\n projection,\n ).entries()) {\n addContainerWriterProjectionBundles(\n bundlesByHash,\n authorizing,\n `Document writer projection authorizing path[${index}]`,\n );\n }\n for (const [index, path] of readDocumentProjectionContainerPaths(\n projection,\n ).entries()) {\n for (const [pathIndex, bundle] of path.entries()) {\n addBundleByHash(\n bundlesByHash,\n bundle,\n `Document writer projection dependency path[${index}][${pathIndex}]`,\n );\n }\n }\n for (const [\n index,\n bundle,\n ] of projection.documentContainerManifestHistory.entries()) {\n addBundleByHash(\n bundlesByHash,\n bundle,\n `Document writer projection container history[${index}]`,\n );\n }\n return bundlesByHash;\n}\n\nasync function verifyProjectionContainerPaths(input: {\n readonly authorizationEvidence: readonly PrincipalPolicyAuthorization[];\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly projection: DocumentWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly verifiedByHash?: VerifiedManifestMap | undefined;\n readonly warmReferencedPrincipalPolicies?: PolicyWarmer;\n}): Promise<Map<string, readonly VerifiedContainerAccessManifest[]>> {\n const bundlesByHash = collectDocumentProjectionContainerBundles(\n input.projection,\n );\n const containerPathByManifestHash = new Map<\n string,\n readonly VerifiedContainerAccessManifest[]\n >();\n // Reuse a caller-supplied cache when provided so a later unwrap pass over the\n // same authorizing container paths does not re-verify identical manifests.\n const verifiedByHash =\n input.verifiedByHash ?? new Map<string, VerifiedContainerAccessManifest>();\n for (const projection of documentContainerProjections(input.projection)) {\n const path = await verifyContainerWriterProjectionWithContext(\n {\n authorizationEvidence: input.authorizationEvidence,\n principalPolicyCache: input.principalPolicyCache,\n projection,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n },\n input.checkpointContext,\n );\n const leaf = path.at(-1);\n if (leaf) {\n containerPathByManifestHash.set(leaf.manifestHash, path);\n }\n for (const manifest of path) {\n verifiedByHash.set(manifest.manifestHash, manifest);\n }\n }\n // Grouping supplies evidence only; each signed artifact selects its citations.\n for (const [\n index,\n path,\n ] of input.projection.documentManifestContainerPaths.entries()) {\n // Historical dependency evidence is verified without current checkpoint\n // enforcement. Its grouping cannot substitute an uncited ancestor into\n // document or content-write authorization.\n const verifiedPath = await verifyContainerManifestPath({\n authorizationEvidence: input.authorizationEvidence,\n requireAuthorizationEvidence: true,\n servedAsCurrent: false,\n authorizationMembership: \"referenced\",\n bundlesByHash,\n checkpointContext: input.checkpointContext,\n enforceLocalCheckpoints: false,\n label: `Document writer projection dependency path[${index}]`,\n path,\n principalPolicyCache: input.principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n // The authorizing path recorded for the same leaf takes precedence.\n const leaf = verifiedPath.at(-1);\n if (leaf && !containerPathByManifestHash.has(leaf.manifestHash)) {\n containerPathByManifestHash.set(leaf.manifestHash, verifiedPath);\n }\n }\n\n // Keep every verified head as evidence. Events and content headers select\n // their own signed paths through resolveEventContainerPaths.\n for (const [hash, manifest] of verifiedByHash) {\n if (!containerPathByManifestHash.has(hash))\n containerPathByManifestHash.set(hash, [manifest]);\n }\n\n observeAccessManifestCheckpoints(input.checkpointContext, {\n verifiedHeads: [],\n verifiedManifests: verifiedContainerManifestsForBundles(\n bundlesByHash,\n verifiedByHash,\n ),\n });\n\n return containerPathByManifestHash;\n}\n\ninterface DocumentWriterProjectionVerificationInput {\n readonly execSql: ExecSql;\n readonly persistVerificationCheckpoints?: boolean | undefined;\n readonly principalPolicyCache?: PrincipalPolicyCache | undefined;\n readonly projection: DocumentWriterProjectionResponse;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly verifiedByHash?: VerifiedManifestMap | undefined;\n readonly warmReferencedPrincipalPolicies?: PolicyWarmer;\n}\nexport interface DocumentWriterProjectionAuthorization {\n readonly containerPathByManifestHash: ReadonlyMap<\n string,\n readonly VerifiedContainerAccessManifest[]\n >;\n readonly documentManifestByHash: ReadonlyMap<\n string,\n VerifiedDocumentLinkSetManifest\n >;\n readonly principalPolicies: readonly PrincipalPolicyAuthorization[];\n}\n\ninterface VerifiedDocumentWriterProjectionResult {\n readonly authorization: DocumentWriterProjectionAuthorization;\n readonly headManifest: VerifiedDocumentLinkSetManifest;\n}\n\nasync function verifyDocumentWriterProjectionWithContext(\n input: Omit<DocumentWriterProjectionVerificationInput, \"execSql\">,\n checkpointContext: ProjectionCheckpointContext,\n): Promise<VerifiedDocumentWriterProjectionResult> {\n const principalPolicyCache =\n input.principalPolicyCache ?? new Map<string, VerifiedPrincipalPolicy>();\n const authorizationEvidence = await verifyProjectionAuthorizationEvidence({\n bundles: [\n input.projection.documentManifest,\n ...input.projection.documentManifestHistory,\n ...collectDocumentProjectionContainerBundles(input.projection).values(),\n ],\n checkpointContext,\n policyEvidence: input.projection.policyEvidence,\n organizationId: readAccessManifest(\n input.projection.documentManifest.manifest,\n \"Document projection manifest\",\n ).organizationId,\n principalPolicyCache,\n resolveUserKey: input.resolveUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const containerPathByManifestHash = await verifyProjectionContainerPaths({\n authorizationEvidence,\n checkpointContext,\n principalPolicyCache,\n projection: input.projection,\n resolveUserKey: input.resolveUserKey,\n verifiedByHash: input.verifiedByHash,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n const { headManifest, verifiedByHash } =\n await verifyDocumentProjectionManifests({\n authorizationEvidence,\n checkpointContext,\n containerPathByManifestHash,\n principalPolicyCache,\n projection: input.projection,\n resolveUserKey: input.resolveUserKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n await rejectPurgedDocumentProjection(\n headManifest.state.documentId,\n checkpointContext.execSql,\n );\n\n observeAccessManifestCheckpoints(checkpointContext, {\n verifiedHeads: [headManifest],\n verifiedManifests: [...verifiedByHash.values()],\n });\n\n return {\n authorization: {\n containerPathByManifestHash,\n documentManifestByHash: verifiedByHash,\n principalPolicies: authorizationEvidence,\n },\n headManifest,\n };\n}\n\n/** Each served bundle, document and container, whose manifest verified. */\nfunction observeVerifiedDocumentProjectionBundles(\n checkpointContext: ProjectionCheckpointContext,\n projection: DocumentWriterProjectionResponse,\n authorization: DocumentWriterProjectionAuthorization,\n): void {\n observeVerifiedProjectionBundles(\n checkpointContext,\n new Map(\n [projection.documentManifest, ...projection.documentManifestHistory].map(\n (bundle) => [bundle.manifestHash, bundle],\n ),\n ),\n authorization.documentManifestByHash,\n );\n observeVerifiedProjectionBundles(\n checkpointContext,\n collectDocumentProjectionContainerBundles(projection),\n new Map(\n [...authorization.containerPathByManifestHash.values()]\n .flat()\n .map((manifest) => [manifest.manifestHash, manifest]),\n ),\n );\n observeVerifiedKekLevels(\n checkpointContext,\n projection.authorizingContainerPaths,\n );\n}\n\nexport async function verifyDocumentWriterProjection(\n input: DocumentWriterProjectionVerificationInput,\n): Promise<VerifiedDocumentLinkSetManifest> {\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n });\n const verified = await verifyDocumentWriterProjectionWithContext(\n withGenerationGuardedPolicyWarmer(input),\n checkpointContext,\n );\n observeVerifiedDocumentProjectionBundles(\n checkpointContext,\n input.projection,\n verified.authorization,\n );\n await finalizeProjectionCheckpoints(checkpointContext, input);\n return verified.headManifest;\n}\n\nexport async function verifyDocumentWriterProjectionAuthorization(\n input: DocumentWriterProjectionVerificationInput,\n): Promise<DocumentWriterProjectionAuthorization> {\n try {\n const checkpointContext = createProjectionCheckpointContext({\n execSql: input.execSql,\n });\n const verified = await verifyDocumentWriterProjectionWithContext(\n withGenerationGuardedPolicyWarmer(input),\n checkpointContext,\n );\n observeVerifiedDocumentProjectionBundles(\n checkpointContext,\n input.projection,\n verified.authorization,\n );\n await finalizeProjectionCheckpoints(checkpointContext, input);\n return verified.authorization;\n } catch (error) {\n throwKeyingVerificationShapeFailure(error);\n }\n}\n"]}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { eq } from "drizzle-orm";
|
|
2
|
-
import { containerHydrationTombstones, containers, documentContainerProjectionTables, keyingCheckpointTables, localIntentTables, } from "../../sqlite/schema/index.js";
|
|
2
|
+
import { containerHydrationTombstones, containerSyncWatermarkTables, containers, containerTables, documentContainerProjectionTables, documentProjectionTables, documentTables, keyingCheckpointTables, localIntentTables, } from "../../sqlite/schema/index.js";
|
|
3
3
|
import { getClientSQLitePersistenceRuntime, } from "../../sqlite/sqlitePersistenceRuntime.js";
|
|
4
4
|
import { ensureSqlTables, runOncePerConnection, runSerializedSqlMutation, } from "../../sqlite/sqlSchema.js";
|
|
5
|
-
import { enqueueDocumentPendingUpdate
|
|
5
|
+
import { enqueueDocumentPendingUpdate } from "../documents/records/index.js";
|
|
6
6
|
import { hasQueuedDocumentUpdates, settleQueuedDocumentUpdatesInTransaction, } from "../documents/records/documentPendingUpdatePersistence.js";
|
|
7
7
|
import { getLatestTimestamp } from "../latestTimestamp.js";
|
|
8
|
-
import {
|
|
9
|
-
import { sqlContainerSyncWatermarkPersistence } from "./containerSyncWatermarkPersistence.js";
|
|
8
|
+
import { loadContainerById } from "./containerPersistence.js";
|
|
10
9
|
import { claimDormantMetadataSweepAttempt, completeDormantMetadataSweepRequest, listDormantMetadataSweepRequests, } from "./dormantMetadataSweep.js";
|
|
11
10
|
export { CONTAINER_METADATA_APP_KIND } from "./dormantContainerMetadata.js";
|
|
12
11
|
import { deleteStoredContainers } from "./containerDeletionPersistence.js";
|
|
@@ -86,16 +85,18 @@ export const sqlContainerContentsPersistence = {
|
|
|
86
85
|
// Once ensured on this connection, skip the outer mutation lock entirely:
|
|
87
86
|
// ensureSchema runs on every query path, and re-acquiring the lock just to
|
|
88
87
|
// no-op would queue reads behind unrelated writes.
|
|
89
|
-
await runOncePerConnection(execSql, "ensure:container-contents", () =>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
await runOncePerConnection(execSql, "ensure:container-contents", () =>
|
|
89
|
+
// One ensure, so a cold connection sends three DDL messages in total.
|
|
90
|
+
ensureSqlTables(execSql, [
|
|
91
|
+
...containerTables,
|
|
92
|
+
...documentTables,
|
|
93
|
+
...localIntentTables,
|
|
93
94
|
// Metadata rows consult document purge checkpoints before writing.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
...keyingCheckpointTables,
|
|
96
|
+
...documentContainerProjectionTables,
|
|
97
|
+
...documentProjectionTables,
|
|
98
|
+
...containerSyncWatermarkTables,
|
|
99
|
+
]));
|
|
99
100
|
},
|
|
100
101
|
async loadHeldContainerBinding(execSql, containerId) {
|
|
101
102
|
await sqlContainerContentsPersistence.ensureSchema(execSql);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"containerContentsPersistence.js","sourceRoot":"","sources":["containerContentsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport {\n containerHydrationTombstones,\n containers,\n documentContainerProjectionTables,\n keyingCheckpointTables,\n localIntentTables,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport {\n ensureSqlTables,\n runOncePerConnection,\n runSerializedSqlMutation,\n} from \"../../sqlite/sqlSchema\";\nimport {\n enqueueDocumentPendingUpdate,\n ensureDocumentProjectionTables,\n ensureDocumentTables,\n} from \"../documents/records\";\nimport {\n hasQueuedDocumentUpdates,\n settleQueuedDocumentUpdatesInTransaction,\n} from \"../documents/records/documentPendingUpdatePersistence\";\nimport { getLatestTimestamp } from \"../latestTimestamp\";\nimport {\n ensureContainerTables,\n loadContainerById,\n} from \"./containerPersistence\";\nimport { sqlContainerSyncWatermarkPersistence } from \"./containerSyncWatermarkPersistence\";\nimport {\n claimDormantMetadataSweepAttempt,\n completeDormantMetadataSweepRequest,\n listDormantMetadataSweepRequests,\n} from \"./dormantMetadataSweep\";\n\nexport type {\n ContainerContentsPersistence,\n ContainerCreateIntentRecord,\n ContainerHydrationTombstone,\n ContainerMetadataRecord,\n ContainerMoveIntentRecord,\n LocalRootDescendantReparentInput,\n StoredContainerState,\n} from \"./containerContentsPersistenceTypes\";\nexport { CONTAINER_METADATA_APP_KIND } from \"./dormantContainerMetadata\";\n\nimport type {\n ContainerContentsPersistence,\n ContainerMetadataRecord,\n SaveContainerOptions,\n SaveContainerWithPendingUpdateOptions,\n} from \"./containerContentsPersistenceTypes\";\nimport { deleteStoredContainers } from \"./containerDeletionPersistence\";\nimport {\n commitStoredHydratedContainer,\n loadStoredHeldContainerBinding,\n} from \"./containerHydrationPersistence\";\nimport { containerIntentPersistence } from \"./containerIntentPersistence\";\nimport {\n commitStoredMetadataMutation,\n settleStoredMetadataPendingUpdates,\n} from \"./containerMetadataMutationPersistence\";\nimport { containerMetadataPullContinuationPersistence } from \"./containerMetadataPullContinuationPersistence\";\nimport {\n getContainerMetadataScope,\n saveContainerContentsContainerRows,\n selectContainerMetadataRecord,\n selectContainersWithMetadataRecords,\n} from \"./containerMetadataRows\";\nimport { abandonStoredMoveIntentRevision } from \"./containerMoveAbandonPersistence\";\nimport { containerPendingUpdatePersistence } from \"./containerPendingUpdatePersistence\";\nimport { rebindStoredHeldContainer } from \"./containerRebindPersistence\";\nimport { containerReconcilePersistence } from \"./containerReconcilePersistence\";\nimport { isSupersededContainerBinding } from \"./supersededContainerBindings\";\n\nasync function saveStoredContainer(\n execSql: Parameters<ContainerContentsPersistence[\"saveContainer\"]>[0],\n container: Parameters<ContainerContentsPersistence[\"saveContainer\"]>[1],\n record: ContainerMetadataRecord | null,\n options?:\n | SaveContainerOptions\n | SaveContainerWithPendingUpdateOptions\n | undefined,\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const localUpdatedAt =\n options?.localUpdatedAt ?? options?.updatedAt ?? new Date().toISOString();\n const runtime = getClientSQLitePersistenceRuntime(lockedExecSql);\n const save = async (tx: ClientSQLiteTransactionScope) => {\n const saved = await saveContainerContentsContainerRows({\n container,\n createIntent: options?.createIntent,\n moveIntent: options?.moveIntent,\n record,\n serverTimestamps: options?.serverTimestamps,\n tx,\n localUpdatedAt,\n });\n if (options && \"pendingUpdate\" in options) {\n await enqueueDocumentPendingUpdate(\n lockedExecSql,\n getContainerMetadataScope(container.id),\n options.pendingUpdate,\n );\n }\n return saved;\n };\n if (!options?.stillCurrent) {\n return runtime.transaction(save);\n }\n const outcome = await runtime.guardedTransaction(\n save,\n options.stillCurrent,\n { behavior: \"immediate\" },\n );\n // Guarded callers recheck the same monotonic generation immediately after\n // this await. Returning the untouched candidate keeps the long-standing\n // non-null save contract while the transaction itself remains rolled back.\n return outcome.result ?? container;\n });\n}\n\nexport const sqlContainerContentsPersistence: ContainerContentsPersistence = {\n ...containerIntentPersistence,\n ...containerMetadataPullContinuationPersistence,\n commitHydratedContainer: commitStoredHydratedContainer,\n commitMetadataMutation: commitStoredMetadataMutation,\n settleAcceptedMetadataPendingUpdates: settleStoredMetadataPendingUpdates,\n listDormantMetadataSweepRequests,\n ...containerPendingUpdatePersistence,\n ...containerReconcilePersistence,\n claimDormantMetadataSweepAttempt,\n completeDormantMetadataSweepRequest,\n async containerExists(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ id: containers.id })\n .from(containers)\n .where(eq(containers.id, containerId))\n .limit(1);\n return rows.length > 0;\n },\n async deleteContainer(execSql, containerId, options) {\n await sqlContainerContentsPersistence.deleteContainers(execSql, [\n {\n containerId,\n reason: options?.reason ?? \"deleted\",\n updatedAt: options?.updatedAt ?? new Date().toISOString(),\n },\n ]);\n },\n async deleteContainers(execSql, removals, options) {\n return deleteStoredContainers(execSql, removals, options);\n },\n async ensureSchema(execSql) {\n // Once ensured on this connection, skip the outer mutation lock entirely:\n // ensureSchema runs on every query path, and re-acquiring the lock just to\n // no-op would queue reads behind unrelated writes.\n await runOncePerConnection(execSql, \"ensure:container-contents\", () =>\n runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n await ensureContainerTables(lockedExecSql);\n await ensureDocumentTables(lockedExecSql);\n await ensureSqlTables(lockedExecSql, localIntentTables);\n // Metadata rows consult document purge checkpoints before writing.\n await ensureSqlTables(lockedExecSql, keyingCheckpointTables);\n await ensureSqlTables(lockedExecSql, documentContainerProjectionTables);\n await ensureDocumentProjectionTables(lockedExecSql);\n await sqlContainerSyncWatermarkPersistence.ensureSchema(lockedExecSql);\n }),\n );\n },\n async loadHeldContainerBinding(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return loadStoredHeldContainerBinding(execSql, containerId);\n },\n async isSupersededContainerBinding(execSql, input) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return isSupersededContainerBinding(execSql, input);\n },\n async abandonMoveIntentRevision(execSql, input) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return abandonStoredMoveIntentRevision(execSql, input);\n },\n async rebindHeldContainer(execSql, input) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return rebindStoredHeldContainer(execSql, input);\n },\n async loadContainerMetadataRecord(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return selectContainerMetadataRecord(execSql, containerId);\n },\n async loadContainerHydrationTombstones(execSql) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({\n containerId: containerHydrationTombstones.containerId,\n generation: containerHydrationTombstones.generation,\n reason: containerHydrationTombstones.reason,\n updatedAt: containerHydrationTombstones.updatedAt,\n })\n .from(containerHydrationTombstones)\n .where(eq(containerHydrationTombstones.cleared, false));\n return rows.flatMap((row) =>\n row.reason === \"access_revoked\" || row.reason === \"deleted\"\n ? [{ ...row, reason: row.reason }]\n : [],\n );\n },\n async loadContainers(execSql) {\n return selectContainersWithMetadataRecords(execSql);\n },\n async loadContainerMetadataState(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const container = await loadContainerById(execSql, containerId);\n if (!container) {\n return null;\n }\n return {\n container,\n record: await selectContainerMetadataRecord(execSql, containerId),\n };\n },\n async saveContainer(execSql, container, record, options) {\n return saveStoredContainer(execSql, container, record, options);\n },\n async saveContainerWithPendingUpdate(execSql, container, record, options) {\n return saveStoredContainer(execSql, container, record, options);\n },\n async saveContainerAndDeletePendingUpdates(\n execSql,\n container,\n record,\n pendingUpdateIds,\n ) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const localUpdatedAt = new Date().toISOString();\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const scope = getContainerMetadataScope(container.id);\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n scope,\n pendingUpdateIds,\n );\n const hasRemainingPendingUpdates = await hasQueuedDocumentUpdates(\n tx,\n scope,\n );\n const containerToSave = hasRemainingPendingUpdates\n ? container\n : {\n ...container,\n serverUpdatedAt: getLatestTimestamp(\n container.serverUpdatedAt,\n localUpdatedAt,\n ),\n };\n\n return saveContainerContentsContainerRows({\n container: containerToSave,\n record,\n tx,\n localUpdatedAt,\n });\n },\n );\n });\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"containerContentsPersistence.js","sourceRoot":"","sources":["containerContentsPersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import { eq } from \"drizzle-orm\";\nimport {\n containerHydrationTombstones,\n containerSyncWatermarkTables,\n containers,\n containerTables,\n documentContainerProjectionTables,\n documentProjectionTables,\n documentTables,\n keyingCheckpointTables,\n localIntentTables,\n} from \"../../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../../sqlite/sqlitePersistenceRuntime\";\nimport {\n ensureSqlTables,\n runOncePerConnection,\n runSerializedSqlMutation,\n} from \"../../sqlite/sqlSchema\";\nimport { enqueueDocumentPendingUpdate } from \"../documents/records\";\nimport {\n hasQueuedDocumentUpdates,\n settleQueuedDocumentUpdatesInTransaction,\n} from \"../documents/records/documentPendingUpdatePersistence\";\nimport { getLatestTimestamp } from \"../latestTimestamp\";\nimport { loadContainerById } from \"./containerPersistence\";\nimport {\n claimDormantMetadataSweepAttempt,\n completeDormantMetadataSweepRequest,\n listDormantMetadataSweepRequests,\n} from \"./dormantMetadataSweep\";\n\nexport type {\n ContainerContentsPersistence,\n ContainerCreateIntentRecord,\n ContainerHydrationTombstone,\n ContainerMetadataRecord,\n ContainerMoveIntentRecord,\n LocalRootDescendantReparentInput,\n StoredContainerState,\n} from \"./containerContentsPersistenceTypes\";\nexport { CONTAINER_METADATA_APP_KIND } from \"./dormantContainerMetadata\";\n\nimport type {\n ContainerContentsPersistence,\n ContainerMetadataRecord,\n SaveContainerOptions,\n SaveContainerWithPendingUpdateOptions,\n} from \"./containerContentsPersistenceTypes\";\nimport { deleteStoredContainers } from \"./containerDeletionPersistence\";\nimport {\n commitStoredHydratedContainer,\n loadStoredHeldContainerBinding,\n} from \"./containerHydrationPersistence\";\nimport { containerIntentPersistence } from \"./containerIntentPersistence\";\nimport {\n commitStoredMetadataMutation,\n settleStoredMetadataPendingUpdates,\n} from \"./containerMetadataMutationPersistence\";\nimport { containerMetadataPullContinuationPersistence } from \"./containerMetadataPullContinuationPersistence\";\nimport {\n getContainerMetadataScope,\n saveContainerContentsContainerRows,\n selectContainerMetadataRecord,\n selectContainersWithMetadataRecords,\n} from \"./containerMetadataRows\";\nimport { abandonStoredMoveIntentRevision } from \"./containerMoveAbandonPersistence\";\nimport { containerPendingUpdatePersistence } from \"./containerPendingUpdatePersistence\";\nimport { rebindStoredHeldContainer } from \"./containerRebindPersistence\";\nimport { containerReconcilePersistence } from \"./containerReconcilePersistence\";\nimport { isSupersededContainerBinding } from \"./supersededContainerBindings\";\n\nasync function saveStoredContainer(\n execSql: Parameters<ContainerContentsPersistence[\"saveContainer\"]>[0],\n container: Parameters<ContainerContentsPersistence[\"saveContainer\"]>[1],\n record: ContainerMetadataRecord | null,\n options?:\n | SaveContainerOptions\n | SaveContainerWithPendingUpdateOptions\n | undefined,\n) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const localUpdatedAt =\n options?.localUpdatedAt ?? options?.updatedAt ?? new Date().toISOString();\n const runtime = getClientSQLitePersistenceRuntime(lockedExecSql);\n const save = async (tx: ClientSQLiteTransactionScope) => {\n const saved = await saveContainerContentsContainerRows({\n container,\n createIntent: options?.createIntent,\n moveIntent: options?.moveIntent,\n record,\n serverTimestamps: options?.serverTimestamps,\n tx,\n localUpdatedAt,\n });\n if (options && \"pendingUpdate\" in options) {\n await enqueueDocumentPendingUpdate(\n lockedExecSql,\n getContainerMetadataScope(container.id),\n options.pendingUpdate,\n );\n }\n return saved;\n };\n if (!options?.stillCurrent) {\n return runtime.transaction(save);\n }\n const outcome = await runtime.guardedTransaction(\n save,\n options.stillCurrent,\n { behavior: \"immediate\" },\n );\n // Guarded callers recheck the same monotonic generation immediately after\n // this await. Returning the untouched candidate keeps the long-standing\n // non-null save contract while the transaction itself remains rolled back.\n return outcome.result ?? container;\n });\n}\n\nexport const sqlContainerContentsPersistence: ContainerContentsPersistence = {\n ...containerIntentPersistence,\n ...containerMetadataPullContinuationPersistence,\n commitHydratedContainer: commitStoredHydratedContainer,\n commitMetadataMutation: commitStoredMetadataMutation,\n settleAcceptedMetadataPendingUpdates: settleStoredMetadataPendingUpdates,\n listDormantMetadataSweepRequests,\n ...containerPendingUpdatePersistence,\n ...containerReconcilePersistence,\n claimDormantMetadataSweepAttempt,\n completeDormantMetadataSweepRequest,\n async containerExists(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({ id: containers.id })\n .from(containers)\n .where(eq(containers.id, containerId))\n .limit(1);\n return rows.length > 0;\n },\n async deleteContainer(execSql, containerId, options) {\n await sqlContainerContentsPersistence.deleteContainers(execSql, [\n {\n containerId,\n reason: options?.reason ?? \"deleted\",\n updatedAt: options?.updatedAt ?? new Date().toISOString(),\n },\n ]);\n },\n async deleteContainers(execSql, removals, options) {\n return deleteStoredContainers(execSql, removals, options);\n },\n async ensureSchema(execSql) {\n // Once ensured on this connection, skip the outer mutation lock entirely:\n // ensureSchema runs on every query path, and re-acquiring the lock just to\n // no-op would queue reads behind unrelated writes.\n await runOncePerConnection(execSql, \"ensure:container-contents\", () =>\n // One ensure, so a cold connection sends three DDL messages in total.\n ensureSqlTables(execSql, [\n ...containerTables,\n ...documentTables,\n ...localIntentTables,\n // Metadata rows consult document purge checkpoints before writing.\n ...keyingCheckpointTables,\n ...documentContainerProjectionTables,\n ...documentProjectionTables,\n ...containerSyncWatermarkTables,\n ]),\n );\n },\n async loadHeldContainerBinding(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return loadStoredHeldContainerBinding(execSql, containerId);\n },\n async isSupersededContainerBinding(execSql, input) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return isSupersededContainerBinding(execSql, input);\n },\n async abandonMoveIntentRevision(execSql, input) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return abandonStoredMoveIntentRevision(execSql, input);\n },\n async rebindHeldContainer(execSql, input) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return rebindStoredHeldContainer(execSql, input);\n },\n async loadContainerMetadataRecord(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n return selectContainerMetadataRecord(execSql, containerId);\n },\n async loadContainerHydrationTombstones(execSql) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const { db } = getClientSQLitePersistenceRuntime(execSql);\n const rows = await db\n .select({\n containerId: containerHydrationTombstones.containerId,\n generation: containerHydrationTombstones.generation,\n reason: containerHydrationTombstones.reason,\n updatedAt: containerHydrationTombstones.updatedAt,\n })\n .from(containerHydrationTombstones)\n .where(eq(containerHydrationTombstones.cleared, false));\n return rows.flatMap((row) =>\n row.reason === \"access_revoked\" || row.reason === \"deleted\"\n ? [{ ...row, reason: row.reason }]\n : [],\n );\n },\n async loadContainers(execSql) {\n return selectContainersWithMetadataRecords(execSql);\n },\n async loadContainerMetadataState(execSql, containerId) {\n await sqlContainerContentsPersistence.ensureSchema(execSql);\n const container = await loadContainerById(execSql, containerId);\n if (!container) {\n return null;\n }\n return {\n container,\n record: await selectContainerMetadataRecord(execSql, containerId),\n };\n },\n async saveContainer(execSql, container, record, options) {\n return saveStoredContainer(execSql, container, record, options);\n },\n async saveContainerWithPendingUpdate(execSql, container, record, options) {\n return saveStoredContainer(execSql, container, record, options);\n },\n async saveContainerAndDeletePendingUpdates(\n execSql,\n container,\n record,\n pendingUpdateIds,\n ) {\n return runSerializedSqlMutation(execSql, async (lockedExecSql) => {\n const localUpdatedAt = new Date().toISOString();\n return getClientSQLitePersistenceRuntime(lockedExecSql).transaction(\n async (tx) => {\n const scope = getContainerMetadataScope(container.id);\n await settleQueuedDocumentUpdatesInTransaction(\n tx,\n scope,\n pendingUpdateIds,\n );\n const hasRemainingPendingUpdates = await hasQueuedDocumentUpdates(\n tx,\n scope,\n );\n const containerToSave = hasRemainingPendingUpdates\n ? container\n : {\n ...container,\n serverUpdatedAt: getLatestTimestamp(\n container.serverUpdatedAt,\n localUpdatedAt,\n ),\n };\n\n return saveContainerContentsContainerRows({\n container: containerToSave,\n record,\n tx,\n localUpdatedAt,\n });\n },\n );\n });\n },\n};\n"]}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { documentContainerProjectionTables, documentPlacementIntentTables, keyingCheckpointTables, } from "../../../sqlite/schema/index.js";
|
|
2
|
-
import { ensureSqlTables, runOncePerConnection,
|
|
3
|
-
|
|
1
|
+
import { documentContainerProjectionTables, documentPlacementIntentTables, documentProjectionTables, documentTables, keyingCheckpointTables, } from "../../../sqlite/schema/index.js";
|
|
2
|
+
import { ensureSqlTables, runOncePerConnection, } from "../../../sqlite/sqlSchema.js";
|
|
3
|
+
// One ensure, so a cold connection sends three DDL messages in total.
|
|
4
4
|
export async function ensureDocumentsSchema(execSql) {
|
|
5
|
-
await runOncePerConnection(execSql, "ensure:documents", () =>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
]);
|
|
13
|
-
}));
|
|
5
|
+
await runOncePerConnection(execSql, "ensure:documents", () => ensureSqlTables(execSql, [
|
|
6
|
+
...documentTables,
|
|
7
|
+
...documentProjectionTables,
|
|
8
|
+
...documentContainerProjectionTables,
|
|
9
|
+
...documentPlacementIntentTables,
|
|
10
|
+
...keyingCheckpointTables,
|
|
11
|
+
]));
|
|
14
12
|
}
|
|
15
13
|
//# sourceMappingURL=ensureDocumentsSchema.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensureDocumentsSchema.js","sourceRoot":"","sources":["ensureDocumentsSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,eAAe,EACf,oBAAoB,
|
|
1
|
+
{"version":3,"file":"ensureDocumentsSchema.js","sourceRoot":"","sources":["ensureDocumentsSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,6BAA6B,EAC7B,wBAAwB,EACxB,cAAc,EACd,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,eAAe,EACf,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AAEnC,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAgB;IAC1D,MAAM,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAC3D,eAAe,CAAC,OAAO,EAAE;QACvB,GAAG,cAAc;QACjB,GAAG,wBAAwB;QAC3B,GAAG,iCAAiC;QACpC,GAAG,6BAA6B;QAChC,GAAG,sBAAsB;KAC1B,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import {\n documentContainerProjectionTables,\n documentPlacementIntentTables,\n documentProjectionTables,\n documentTables,\n keyingCheckpointTables,\n} from \"../../../sqlite/schema\";\nimport {\n type ExecSql,\n ensureSqlTables,\n runOncePerConnection,\n} from \"../../../sqlite/sqlSchema\";\n\n// One ensure, so a cold connection sends three DDL messages in total.\nexport async function ensureDocumentsSchema(execSql: ExecSql): Promise<void> {\n await runOncePerConnection(execSql, \"ensure:documents\", () =>\n ensureSqlTables(execSql, [\n ...documentTables,\n ...documentProjectionTables,\n ...documentContainerProjectionTables,\n ...documentPlacementIntentTables,\n ...keyingCheckpointTables,\n ]),\n );\n}\n"]}
|