@tearleads/client-sdk 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -7
- package/client/containerContents.js +2 -1
- package/client/containerContents.js.map +1 -1
- package/data/documents/blob/shared/types.d.ts +4 -0
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js +2 -0
- package/data/keyingProjectionVerification/accessManifestCheckpointEnforcement.js.map +1 -1
- package/data/keyingProjectionVerification/checkpointContext.d.ts +2 -1
- package/data/keyingProjectionVerification/checkpointContext.js +22 -0
- package/data/keyingProjectionVerification/checkpointContext.js.map +1 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js +11 -1
- package/data/keyingProjectionVerification/containerDestinationVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerPathVerification.js.map +1 -1
- package/data/keyingProjectionVerification/containerProjectionVerification.d.ts +3 -2
- package/data/keyingProjectionVerification/containerProjectionVerification.js +10 -11
- package/data/keyingProjectionVerification/containerProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestPolicies.js.map +1 -1
- package/data/keyingProjectionVerification/documentManifestVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentProjectionVerification.d.ts +2 -3
- package/data/keyingProjectionVerification/documentProjectionVerification.js +4 -0
- package/data/keyingProjectionVerification/documentProjectionVerification.js.map +1 -1
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js +14 -12
- package/data/keyingProjectionVerification/mergeProjectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/organizationFounderBinding.js.map +1 -1
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js +33 -6
- package/data/keyingProjectionVerification/projectionAuthorizationEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/projectionLifetimes.js +13 -0
- package/data/keyingProjectionVerification/projectionLifetimes.js.map +1 -0
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js +19 -66
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/types.d.ts +13 -2
- package/data/keyingProjectionVerification/types.js +15 -0
- package/data/keyingProjectionVerification/types.js.map +1 -1
- package/data/persistence/keyingCheckpointAdvancePersistence.js +4 -1
- package/data/persistence/keyingCheckpointAdvancePersistence.js.map +1 -1
- package/data/persistence/organizationFounderPersistence.js +2 -2
- package/data/persistence/organizationFounderPersistence.js.map +1 -1
- package/data/persistence/principalAuthorizationCheckpoints.js +29 -0
- package/data/persistence/principalAuthorizationCheckpoints.js.map +1 -0
- package/data/persistence/principalHistoryEvidencePersistence.d.ts +30 -0
- package/data/persistence/principalHistoryPrefixPersistence.d.ts +24 -0
- package/data/persistence/principalHistoryPrefixPersistence.js +6 -2
- package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
- package/data/persistence/principalHistoryStagePersistence.d.ts +21 -0
- package/data/principals/principalHistoryRuntime.js +12 -0
- package/data/principals/principalHistoryRuntime.js.map +1 -0
- package/data/principals/principalHistoryStageProtection.js +2 -12
- package/data/principals/principalHistoryStageProtection.js.map +1 -1
- package/data/principals/principalPolicyEvidence.d.ts +2 -2
- package/data/principals/principalPolicyEvidence.js.map +1 -1
- package/data/sqlite/principalHistoryEvidenceSchema.d.ts +308 -0
- package/data/sqlite/principalHistoryStageSchema.d.ts +119 -0
- package/index.d.ts +2 -2
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/internal/api-client/ApiCache.d.ts +54 -0
- package/internal/api-client/ApiClient.d.ts +255 -309
- package/internal/api-client/ApiClient.js +15 -6
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/index.d.ts +1 -0
- package/internal/api-client/index.js.map +1 -1
- package/internal/api-client/principalHistoryDeadline.js +20 -0
- package/internal/api-client/principalHistoryDeadline.js.map +1 -0
- package/internal/api-client/principalHistoryRequest.js +59 -22
- package/internal/api-client/principalHistoryRequest.js.map +1 -1
- package/internal/api-client/principalHistoryRequestContext.js +18 -5
- package/internal/api-client/principalHistoryRequestContext.js.map +1 -1
- package/internal/api-client/principalPolicyRequests.d.ts +799 -0
- package/internal/api-client/principalPolicyRequests.js +9 -4
- package/internal/api-client/principalPolicyRequests.js.map +1 -1
- package/internal/api-client/projectionPolicyHistoryPages.d.ts +9 -0
- package/internal/api-client/projectionPolicyHistoryPages.js +88 -0
- package/internal/api-client/projectionPolicyHistoryPages.js.map +1 -0
- package/internal/api-client/writerProjectionRequests.js +26 -0
- package/internal/api-client/writerProjectionRequests.js.map +1 -0
- package/internal/crypto/keying/principalPolicyHistory.js +4 -0
- package/internal/crypto/keying/principalPolicyHistory.js.map +1 -1
- package/internal/crypto/keying/principalPolicyHistoryTypes.d.ts +2 -0
- package/internal/crypto/keying/principalPolicyHistoryTypes.js.map +1 -1
- package/internal/crypto/projectionHistorySlots.js +0 -4
- package/internal/crypto/projectionHistorySlots.js.map +1 -1
- package/internal/validators/operation/index.d.ts +1 -0
- package/internal/validators/operation/index.js +1 -0
- package/internal/validators/operation/index.js.map +1 -1
- package/internal/validators/operation/principals.d.ts +38 -16
- package/internal/validators/operation/principals.js +11 -5
- package/internal/validators/operation/principals.js.map +1 -1
- package/internal/validators/operation/projectionPolicyHistory.d.ts +512 -0
- package/internal/validators/operation/projectionPolicyHistory.js +37 -0
- package/internal/validators/operation/projectionPolicyHistory.js.map +1 -0
- package/internal/validators/operation/registry.d.ts +2 -0
- package/internal/validators/operation/registry.js +2 -0
- package/internal/validators/operation/registry.js.map +1 -1
- package/internal/validators/operation/writerProjections.d.ts +178 -1224
- package/internal/validators/operation/writerProjections.js +9 -2
- package/internal/validators/operation/writerProjections.js.map +1 -1
- package/internal/validators/response/container.d.ts +84 -612
- package/internal/validators/response/documentMutation.d.ts +84 -612
- package/internal/validators/response/index.d.ts +1 -0
- package/internal/validators/response/index.js +1 -0
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationBilling.d.ts +1 -0
- package/internal/validators/response/organizationBilling.js +1 -1
- package/internal/validators/response/organizationBilling.js.map +1 -1
- package/internal/validators/response/principalHistoryPreparation.js +28 -1
- package/internal/validators/response/principalHistoryPreparation.js.map +1 -1
- package/internal/validators/response/principalPolicySnapshotPage.d.ts +388 -0
- package/internal/validators/response/principalPolicySnapshotPage.js +24 -0
- package/internal/validators/response/principalPolicySnapshotPage.js.map +1 -0
- package/internal/validators/response/projectionPolicyEvidence.d.ts +85 -613
- package/internal/validators/response/projectionPolicyEvidence.js +10 -5
- package/internal/validators/response/projectionPolicyEvidence.js.map +1 -1
- package/package.json +4 -1
- package/sqlite/sqlite3-licenses.md +38 -0
- package/sqlite/sqlite3.wasm +0 -0
- package/sqlite/worker.js +4 -0
- package/stores/documents/documentStore/attachmentHydration.js +3 -0
- package/stores/documents/documentStore/attachmentHydration.js.map +1 -1
- package/stores/documents/documentStore/syncDetachedAttachments.js +3 -0
- package/stores/documents/documentStore/syncDetachedAttachments.js.map +1 -1
- package/workflows/blobs/decrypt.d.ts +1 -1
- package/workflows/blobs/decrypt.js +3 -1
- package/workflows/blobs/decrypt.js.map +1 -1
- package/workflows/blobs/detach.js +6 -1
- package/workflows/blobs/detach.js.map +1 -1
- package/workflows/blobs/hydrate.d.ts +3 -1
- package/workflows/blobs/hydrate.js +2 -0
- package/workflows/blobs/hydrate.js.map +1 -1
- package/workflows/blobs/retainedAttachmentVerification.js +2 -0
- package/workflows/blobs/retainedAttachmentVerification.js.map +1 -1
- package/workflows/container-contents/container-state/createAdoption.js +2 -0
- package/workflows/container-contents/container-state/createAdoption.js.map +1 -1
- package/workflows/container-contents/container-state/createWithMetadata.js +7 -39
- package/workflows/container-contents/container-state/createWithMetadata.js.map +1 -1
- package/workflows/container-contents/container-state/createWithMetadataPlan.js +68 -0
- package/workflows/container-contents/container-state/createWithMetadataPlan.js.map +1 -0
- package/workflows/container-contents/remoteContainerState.js +3 -1
- package/workflows/container-contents/remoteContainerState.js.map +1 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js +3 -0
- package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +1 -1
- package/workflows/container-contents/runtime.d.ts +3 -0
- package/workflows/container-contents/runtime.js +7 -6
- package/workflows/container-contents/runtime.js.map +1 -1
- package/workflows/documents/create.d.ts +2 -15
- package/workflows/documents/create.js +9 -64
- package/workflows/documents/create.js.map +1 -1
- package/workflows/documents/createProjection.d.ts +14 -0
- package/workflows/documents/createProjection.js +26 -0
- package/workflows/documents/createProjection.js.map +1 -0
- package/workflows/documents/createResponse.js +49 -0
- package/workflows/documents/createResponse.js.map +1 -0
- package/workflows/documents/linkSetBlobRewraps.js +2 -0
- package/workflows/documents/linkSetBlobRewraps.js.map +1 -1
- package/workflows/documents/runtime.d.ts +3 -0
- package/workflows/documents/runtime.js +3 -2
- package/workflows/documents/runtime.js.map +1 -1
- package/workflows/documents/syncFailureClassification.js +3 -1
- package/workflows/documents/syncFailureClassification.js.map +1 -1
- package/workflows/principals/index.d.ts +2 -0
- package/workflows/principals/index.js +1 -0
- package/workflows/principals/index.js.map +1 -1
- package/workflows/principals/policyVerification.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryAuthority.js +20 -0
- package/workflows/principals/principalHistoryRecoveryAuthority.js.map +1 -0
- package/workflows/principals/principalHistoryRecoveryStage.js +1 -1
- package/workflows/principals/principalHistoryRecoveryStage.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryTypes.d.ts +3 -3
- package/workflows/principals/principalHistoryRecoveryTypes.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryVerification.js +6 -1
- package/workflows/principals/principalHistoryRecoveryVerification.js.map +1 -1
- package/workflows/principals/principalRecoveryOutage.js +1 -1
- package/workflows/principals/principalRecoveryOutage.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryAuthority.js +60 -0
- package/workflows/principals/publicPrincipalHistoryAuthority.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryPage.js +87 -0
- package/workflows/principals/publicPrincipalHistoryPage.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js +178 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js.map +1 -0
- package/workflows/principals/publicPrincipalHistoryTypes.d.ts +39 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js +2 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -0
- package/workflows/principals/publicProjectionDirectory.js +40 -0
- package/workflows/principals/publicProjectionDirectory.js.map +1 -0
- package/workflows/principals/publicProjectionPrincipal.js +53 -0
- package/workflows/principals/publicProjectionPrincipal.js.map +1 -0
- package/workflows/principals/recoverPrincipalPolicyHistory.js +4 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/recoverProjectionPolicyHistory.d.ts +9 -0
- package/workflows/principals/recoverProjectionPolicyHistory.js +98 -0
- package/workflows/principals/recoverProjectionPolicyHistory.js.map +1 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js +176 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -0
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +2 -5
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js +2 -1
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimePolicyWarmer.js +2 -0
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
- package/workflows/principals/runtimeProjectionPolicyRecovery.js +56 -0
- package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -0
- package/workflows/principals/selectPublicPrincipalHistory.js +90 -0
- package/workflows/principals/selectPublicPrincipalHistory.js.map +1 -0
- package/workflows/registration/provisioningBootstrapBuilders.d.ts +21 -153
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { KeyingVerificationError } from "../../internal/crypto/index.js";
|
|
2
|
+
import { principalHeadMatchesReference } from "../principals/organizationAuthorityDescriptor.js";
|
|
2
3
|
function newer(previous, next) {
|
|
3
4
|
if (!previous)
|
|
4
5
|
return true;
|
|
5
|
-
if (previous.
|
|
6
|
+
if (previous.head.principalId !== next.head.principalId)
|
|
6
7
|
throw new KeyingVerificationError("object_mismatch", "Projection evidence crosses principals");
|
|
7
|
-
if (previous.
|
|
8
|
-
previous.
|
|
8
|
+
if (previous.head.version === next.head.version &&
|
|
9
|
+
!principalHeadMatchesReference(previous.head, next.head))
|
|
9
10
|
throw new KeyingVerificationError("hash_mismatch", "Projection evidence contains conflicting heads");
|
|
10
|
-
return previous.
|
|
11
|
+
return previous.head.version < next.head.version;
|
|
11
12
|
}
|
|
12
13
|
/** Combine proof material when locally composing projections; verification follows. */
|
|
13
14
|
export function mergeProjectionPolicyEvidence(evidence) {
|
|
@@ -19,19 +20,20 @@ export function mergeProjectionPolicyEvidence(evidence) {
|
|
|
19
20
|
if (organization && newer(directory?.organization, organization))
|
|
20
21
|
directory = proof;
|
|
21
22
|
for (const payload of proof.organizationPayloads) {
|
|
22
|
-
const previous = payloads.get(payload.stateHash);
|
|
23
|
+
const previous = payloads.get(payload.reference.stateHash);
|
|
23
24
|
if (previous &&
|
|
24
|
-
(previous.
|
|
25
|
-
previous.
|
|
26
|
-
previous.
|
|
27
|
-
previous.
|
|
25
|
+
(!principalHeadMatchesReference(previous.reference, payload.reference) ||
|
|
26
|
+
previous.payload.principalId !== payload.payload.principalId ||
|
|
27
|
+
previous.payload.principalType !== payload.payload.principalType ||
|
|
28
|
+
previous.payload.ciphertext !== payload.payload.ciphertext ||
|
|
29
|
+
previous.payload.ciphertextHash !== payload.payload.ciphertextHash))
|
|
28
30
|
throw new KeyingVerificationError("hash_mismatch", "Projection evidence contains conflicting directory payloads");
|
|
29
|
-
payloads.set(payload.stateHash, payload);
|
|
31
|
+
payloads.set(payload.reference.stateHash, payload);
|
|
30
32
|
}
|
|
31
33
|
for (const group of proof.groups) {
|
|
32
|
-
const prior = groups.get(group.
|
|
34
|
+
const prior = groups.get(group.head.principalId);
|
|
33
35
|
if (newer(prior, group))
|
|
34
|
-
groups.set(group.
|
|
36
|
+
groups.set(group.head.principalId, group);
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mergeProjectionPolicyEvidence.js","sourceRoot":"","sources":["mergeProjectionPolicyEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"mergeProjectionPolicyEvidence.js","sourceRoot":"","sources":["mergeProjectionPolicyEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAK5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,+CAA+C,CAAC;AAE9F,SAAS,KAAK,CACZ,QAAiE,EACjE,IAA0C;IAE1C,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,QAAQ,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,IAAI,CAAC,WAAW;QACrD,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,wCAAwC,CACzC,CAAC;IACJ,IACE,QAAQ,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO;QAC3C,CAAC,6BAA6B,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;QAExD,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,gDAAgD,CACjD,CAAC;IACJ,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;AACnD,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,6BAA6B,CAC3C,QAAqD;IAErD,IAAI,SAAuD,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgD,CAAC;IACvE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAGrB,CAAC;IACJ,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,YAAY,IAAI,KAAK,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC;YAC9D,SAAS,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAC3D,IACE,QAAQ;gBACR,CAAC,CAAC,6BAA6B,CAC7B,QAAQ,CAAC,SAAS,EAClB,OAAO,CAAC,SAAS,CAClB;oBACC,QAAQ,CAAC,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,WAAW;oBAC5D,QAAQ,CAAC,OAAO,CAAC,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,aAAa;oBAChE,QAAQ,CAAC,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,UAAU;oBAC1D,QAAQ,CAAC,OAAO,CAAC,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;gBAErE,MAAM,IAAI,uBAAuB,CAC/B,eAAe,EACf,6DAA6D,CAC9D,CAAC;YACJ,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACjD,IAAI,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC;gBAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IACD,OAAO;QACL,YAAY,EAAE,SAAS,EAAE,YAAY,IAAI,IAAI;QAC7C,oBAAoB,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;KAC7B,CAAC;AACJ,CAAC","sourcesContent":["import { KeyingVerificationError } from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyHistorySourceResponse,\n ProjectionPolicyEvidenceResponse,\n} from \"@tearleads/validators/response\";\nimport { principalHeadMatchesReference } from \"../principals/organizationAuthorityDescriptor\";\n\nfunction newer(\n previous: PrincipalPolicyHistorySourceResponse | null | undefined,\n next: PrincipalPolicyHistorySourceResponse,\n): boolean {\n if (!previous) return true;\n if (previous.head.principalId !== next.head.principalId)\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Projection evidence crosses principals\",\n );\n if (\n previous.head.version === next.head.version &&\n !principalHeadMatchesReference(previous.head, next.head)\n )\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n \"Projection evidence contains conflicting heads\",\n );\n return previous.head.version < next.head.version;\n}\n\n/** Combine proof material when locally composing projections; verification follows. */\nexport function mergeProjectionPolicyEvidence(\n evidence: readonly ProjectionPolicyEvidenceResponse[],\n): ProjectionPolicyEvidenceResponse {\n let directory: ProjectionPolicyEvidenceResponse | undefined;\n const groups = new Map<string, PrincipalPolicyHistorySourceResponse>();\n const payloads = new Map<\n string,\n ProjectionPolicyEvidenceResponse[\"organizationPayloads\"][number]\n >();\n for (const proof of evidence) {\n const organization = proof.organization;\n if (organization && newer(directory?.organization, organization))\n directory = proof;\n for (const payload of proof.organizationPayloads) {\n const previous = payloads.get(payload.reference.stateHash);\n if (\n previous &&\n (!principalHeadMatchesReference(\n previous.reference,\n payload.reference,\n ) ||\n previous.payload.principalId !== payload.payload.principalId ||\n previous.payload.principalType !== payload.payload.principalType ||\n previous.payload.ciphertext !== payload.payload.ciphertext ||\n previous.payload.ciphertextHash !== payload.payload.ciphertextHash)\n )\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n \"Projection evidence contains conflicting directory payloads\",\n );\n payloads.set(payload.reference.stateHash, payload);\n }\n for (const group of proof.groups) {\n const prior = groups.get(group.head.principalId);\n if (newer(prior, group)) groups.set(group.head.principalId, group);\n }\n }\n return {\n organization: directory?.organization ?? null,\n organizationPayloads: [...payloads.values()],\n groups: [...groups.values()],\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationFounderBinding.js","sourceRoot":"","sources":["organizationFounderBinding.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"organizationFounderBinding.js","sourceRoot":"","sources":["organizationFounderBinding.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,GAExB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,2BAA2B,EAAE,MAAM,+CAA+C,CAAC;AAE5F,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAK1D;IACC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO;IACpD,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,CACvC,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,aAAa,KAAK,cAAc;QACvC,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC,KAAK,CAAC,cAAc,CACnD,CAAC;IACF,IAAI,CAAC,YAAY;QAAE,OAAO;IAC1B,MAAM,OAAO,GACX,iBAAiB,IAAI,YAAY;QAC/B,CAAC,CAAC,YAAY,CAAC,eAAe;QAC9B,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;IACxE,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,uBAAuB,CAC/B,oBAAoB,EACpB,gDAAgD,CACjD,CAAC;IACJ,MAAM,OAAO,GAAG,+BAA+B,CAAC;QAC9C,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,2BAA2B;QAClC,cAAc,EAAE,KAAK,CAAC,cAAc;KACrC,CAAC,CAAC;IACH,IACE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY;QAC1D,OAAO,CAAC,wBAAwB;YAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB;QAE1C,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,0EAA0E,CAC3E,CAAC;IACJ,MAAM,2BAA2B,CAAC;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,YAAY;KACb,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { PrincipalPolicyAuthorization } from \"@tearleads/crypto\";\nimport {\n KeyingVerificationError,\n type VerifiedContainerAccessManifest,\n} from \"@tearleads/crypto\";\nimport { rememberOrganizationFounder } from \"../persistence/organizationFounderPersistence\";\nimport type { ExecSql } from \"../sqlite/sqlSchema\";\nimport { verifiedContainerCreateManifest } from \"./containerCreateManifest\";\n\n/**\n * A directory can cite someone else's public policies. Bind its founder to the\n * verified personal root's creator before trusting it to authorize a rehome.\n * Metadata roots can be created by later admins and cannot establish this pin.\n * This immutable identity anchor survives read-only verification and canceled\n * views; it neither advances nor replaces a current-policy checkpoint.\n */\nexport async function rememberRootBoundOrganizationFounder(input: {\n readonly execSql: ExecSql;\n readonly policies: readonly PrincipalPolicyAuthorization[] | undefined;\n readonly root: VerifiedContainerAccessManifest | undefined;\n readonly verifiedByHash: ReadonlyMap<string, VerifiedContainerAccessManifest>;\n}): Promise<void> {\n const { root } = input;\n if (!root || root.state.systemSlot !== null) return;\n const organization = input.policies?.find(\n (policy) =>\n policy.principalType === \"organization\" &&\n policy.principalId === root.state.organizationId,\n );\n if (!organization) return;\n const entries =\n \"retainedHistory\" in organization\n ? organization.retainedHistory\n : organization.history;\n if (!entries) return;\n const genesis = entries.find(({ state }) => state.version === 1)?.state;\n if (!genesis)\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Organization founder requires verified genesis\",\n );\n const created = verifiedContainerCreateManifest({\n head: root,\n label: \"Organization founder root\",\n verifiedByHash: input.verifiedByHash,\n });\n if (\n genesis?.signerUserId !== created.event.event.signerUserId ||\n genesis.signerUserKeyFingerprint !==\n created.event.event.signerKeyFingerprint\n )\n throw new KeyingVerificationError(\n \"signer_mismatch\",\n \"Organization founder does not match its verified personal root's creator\",\n );\n await rememberOrganizationFounder({\n execSql: input.execSql,\n organization,\n });\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { KeyingVerificationError, principalPolicyMatchesReference, } from "../../internal/crypto/index.js";
|
|
2
2
|
import { collectReferencedPrincipalPolicies } from "./principalPolicyVerification.js";
|
|
3
|
+
import { observeProjectionLifetime } from "./projectionLifetimes.js";
|
|
3
4
|
import { verifyProjectionPolicyEvidence } from "./projectionPolicyEvidence.js";
|
|
4
5
|
import { readAccessManifest } from "./readers.js";
|
|
5
6
|
/** Locally planned successors may cite an already verified, uncommitted policy. */
|
|
@@ -19,18 +20,44 @@ async function resolveProjectionAuthorizationEvidence(input) {
|
|
|
19
20
|
principalPolicyCache: input.principalPolicyCache,
|
|
20
21
|
references,
|
|
21
22
|
resolveUserKey: input.resolveUserKey,
|
|
23
|
+
stillCurrent: input.stillCurrent,
|
|
24
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
22
25
|
})),
|
|
23
26
|
];
|
|
24
27
|
}
|
|
25
28
|
export async function verifyProjectionAuthorizationEvidence(input) {
|
|
29
|
+
const sources = [
|
|
30
|
+
input.policyEvidence.organization,
|
|
31
|
+
...input.policyEvidence.groups,
|
|
32
|
+
];
|
|
33
|
+
const known = [...input.principalPolicyCache.values()];
|
|
34
|
+
const references = input.bundles
|
|
35
|
+
.flatMap((bundle) => readAccessManifest(bundle.manifest, "Projection manifest")
|
|
36
|
+
.referencedPrincipalHeads)
|
|
37
|
+
.filter((reference) => {
|
|
38
|
+
if (sources.some((source) => source &&
|
|
39
|
+
source.head.principalType === reference.principalType &&
|
|
40
|
+
source.head.principalId === reference.principalId &&
|
|
41
|
+
source.head.version >= reference.version))
|
|
42
|
+
return true;
|
|
43
|
+
// Locally planned successors are verified below through the current-policy path.
|
|
44
|
+
if (known.some((policy) => principalPolicyMatchesReference({ policy, reference })))
|
|
45
|
+
return false;
|
|
46
|
+
throw new KeyingVerificationError("missing_dependency", "Projection omits required principal policy evidence");
|
|
47
|
+
});
|
|
48
|
+
const recovered = await verifyProjectionPolicyEvidence({
|
|
49
|
+
evidence: input.policyEvidence,
|
|
50
|
+
organizationId: input.organizationId,
|
|
51
|
+
references,
|
|
52
|
+
stillCurrent: input.stillCurrent,
|
|
53
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
54
|
+
});
|
|
55
|
+
if (input.policyEvidence.organization)
|
|
56
|
+
observeProjectionLifetime(input.checkpointContext, recovered.stillCurrent);
|
|
57
|
+
input.checkpointContext.authorizationPolicies.push(...recovered.policies);
|
|
26
58
|
return resolveProjectionAuthorizationEvidence({
|
|
27
59
|
...input,
|
|
28
|
-
evidence:
|
|
29
|
-
evidence: input.policyEvidence,
|
|
30
|
-
execSql: input.checkpointContext.execSql,
|
|
31
|
-
organizationId: input.organizationId,
|
|
32
|
-
resolveUserKey: input.resolveUserKey,
|
|
33
|
-
}),
|
|
60
|
+
evidence: recovered.policies,
|
|
34
61
|
});
|
|
35
62
|
}
|
|
36
63
|
//# sourceMappingURL=projectionAuthorizationEvidence.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectionAuthorizationEvidence.js","sourceRoot":"","sources":["projectionAuthorizationEvidence.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"projectionAuthorizationEvidence.js","sourceRoot":"","sources":["projectionAuthorizationEvidence.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PrincipalPolicyAuthorization } from \"@tearleads/crypto\";\nimport {\n KeyingVerificationError,\n principalPolicyMatchesReference,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWireResponse,\n ProjectionPolicyEvidenceResponse,\n} from \"@tearleads/validators/response\";\nimport type { ProjectionCheckpointContext } from \"./checkpointContext\";\nimport { collectReferencedPrincipalPolicies } from \"./principalPolicyVerification\";\nimport { observeProjectionLifetime } from \"./projectionLifetimes\";\nimport { verifyProjectionPolicyEvidence } from \"./projectionPolicyEvidence\";\nimport { readAccessManifest } from \"./readers\";\nimport type {\n PrincipalPolicyCache,\n ProjectionUserKeyResolver,\n ReferencedPrincipalPolicyWarmer,\n} from \"./types\";\n\n/** Locally planned successors may cite an already verified, uncommitted policy. */\nasync function resolveProjectionAuthorizationEvidence(input: {\n readonly bundles: readonly AccessManifestBundleWireResponse[];\n readonly checkpointContext: ProjectionCheckpointContext;\n readonly evidence: readonly PrincipalPolicyAuthorization[];\n readonly organizationId: string;\n readonly principalPolicyCache: PrincipalPolicyCache;\n readonly resolveUserKey: ProjectionUserKeyResolver;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<PrincipalPolicyAuthorization[]> {\n const references = input.bundles\n .flatMap(\n (bundle) =>\n readAccessManifest(bundle.manifest, \"Projection manifest\")\n .referencedPrincipalHeads,\n )\n .filter(\n (reference) =>\n !input.evidence.some((policy) =>\n principalPolicyMatchesReference({ policy, reference }),\n ),\n );\n const known = [...input.principalPolicyCache.values()];\n if (\n references.some(\n (reference) =>\n !known.some((policy) =>\n principalPolicyMatchesReference({ policy, reference }),\n ),\n )\n )\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection omits required principal policy evidence\",\n );\n return [\n ...input.evidence,\n ...(await collectReferencedPrincipalPolicies({\n checkpointContext: input.checkpointContext,\n organizationId: input.organizationId,\n principalPolicyCache: input.principalPolicyCache,\n references,\n resolveUserKey: input.resolveUserKey,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n })),\n ];\n}\n\nexport async function verifyProjectionAuthorizationEvidence(\n input: Omit<\n Parameters<typeof resolveProjectionAuthorizationEvidence>[0],\n \"evidence\"\n > & { readonly policyEvidence: ProjectionPolicyEvidenceResponse },\n) {\n const sources = [\n input.policyEvidence.organization,\n ...input.policyEvidence.groups,\n ];\n const known = [...input.principalPolicyCache.values()];\n const references = input.bundles\n .flatMap(\n (bundle) =>\n readAccessManifest(bundle.manifest, \"Projection manifest\")\n .referencedPrincipalHeads,\n )\n .filter((reference) => {\n if (\n sources.some(\n (source) =>\n source &&\n source.head.principalType === reference.principalType &&\n source.head.principalId === reference.principalId &&\n source.head.version >= reference.version,\n )\n )\n return true;\n // Locally planned successors are verified below through the current-policy path.\n if (\n known.some((policy) =>\n principalPolicyMatchesReference({ policy, reference }),\n )\n )\n return false;\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection omits required principal policy evidence\",\n );\n });\n const recovered = await verifyProjectionPolicyEvidence({\n evidence: input.policyEvidence,\n organizationId: input.organizationId,\n references,\n stillCurrent: input.stillCurrent,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (input.policyEvidence.organization)\n observeProjectionLifetime(input.checkpointContext, recovered.stillCurrent);\n input.checkpointContext.authorizationPolicies.push(...recovered.policies);\n return resolveProjectionAuthorizationEvidence({\n ...input,\n evidence: recovered.policies,\n });\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const lifetimes = new WeakMap();
|
|
2
|
+
export function observeProjectionLifetime(context, current) {
|
|
3
|
+
const guards = lifetimes.get(context) ?? [];
|
|
4
|
+
guards.push(current);
|
|
5
|
+
lifetimes.set(context, guards);
|
|
6
|
+
}
|
|
7
|
+
export function projectionLifetimeGuard(context, current) {
|
|
8
|
+
if (!lifetimes.has(context))
|
|
9
|
+
return current;
|
|
10
|
+
return () => current?.() !== false &&
|
|
11
|
+
(lifetimes.get(context)?.every((guard) => guard()) ?? true);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=projectionLifetimes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectionLifetimes.js","sourceRoot":"","sources":["projectionLifetimes.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,IAAI,OAAO,EAA6B,CAAC;AAE3D,MAAM,UAAU,yBAAyB,CACvC,OAAe,EACf,OAAsB;IAEtB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,OAAqC;IAErC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC5C,OAAO,GAAG,EAAE,CACV,OAAO,EAAE,EAAE,KAAK,KAAK;QACrB,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC;AAChE,CAAC","sourcesContent":["const lifetimes = new WeakMap<object, (() => boolean)[]>();\n\nexport function observeProjectionLifetime(\n context: object,\n current: () => boolean,\n): void {\n const guards = lifetimes.get(context) ?? [];\n guards.push(current);\n lifetimes.set(context, guards);\n}\n\nexport function projectionLifetimeGuard(\n context: object,\n current?: (() => boolean) | undefined,\n): (() => boolean) | undefined {\n if (!lifetimes.has(context)) return current;\n return () =>\n current?.() !== false &&\n (lifetimes.get(context)?.every((guard) => guard()) ?? true);\n}\n"]}
|
|
@@ -1,70 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
throw new KeyingVerificationError("object_mismatch", `Projection policy evidence: ${message}`);
|
|
6
|
-
}
|
|
7
|
-
async function verifyDirectories(input) {
|
|
8
|
-
const states = new Map(input.organization.history.map(({ state }) => [state.stateHash, state]));
|
|
9
|
-
const descriptors = [];
|
|
10
|
-
for (const payload of input.evidence.organizationPayloads) {
|
|
11
|
-
const state = states.get(payload.stateHash);
|
|
12
|
-
if (!state ||
|
|
13
|
-
payload.principalType !== "organization" ||
|
|
14
|
-
payload.principalId !== input.organizationId)
|
|
15
|
-
reject("directory payload scope is invalid");
|
|
16
|
-
const hash = await computePrincipalStatePayloadCiphertextHash(payload.ciphertext);
|
|
17
|
-
if (hash !== state.payloadCiphertextHash || hash !== payload.ciphertextHash)
|
|
18
|
-
reject("directory payload does not match its signed hash");
|
|
19
|
-
const descriptor = parseOrganizationAuthorityDescriptor(payload.ciphertext);
|
|
20
|
-
if (descriptor.organizationId !== input.organizationId)
|
|
21
|
-
reject("directory belongs to another organization");
|
|
22
|
-
descriptors.push(descriptor);
|
|
23
|
-
states.delete(payload.stateHash);
|
|
24
|
-
}
|
|
25
|
-
// Only directory payloads needed to bind the supplied group heads are
|
|
26
|
-
// required. The organization's complete signed state chain is verified above;
|
|
27
|
-
// unrelated payload bodies add no authority and need not be disclosed.
|
|
28
|
-
return descriptors;
|
|
29
|
-
}
|
|
30
|
-
/** Evidence authenticates signed citations only; it never becomes current policy. */
|
|
1
|
+
import { KeyingVerificationError, } from "../../internal/crypto/index.js";
|
|
2
|
+
import { ProjectionDependencyUnavailableError } from "./dependencyUnavailable.js";
|
|
3
|
+
import { assertProjectionVerificationCurrent, } from "./types.js";
|
|
4
|
+
/** Recover public authorization without admitting historical heads as current policy. */
|
|
31
5
|
export async function verifyProjectionPolicyEvidence(input) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
evidence.groups.some((group) => group.currentState.principalType !== "group"))
|
|
41
|
-
reject("principal scope is invalid");
|
|
42
|
-
const policies = await verifyPrincipalPolicySnapshots({
|
|
43
|
-
resolveUserKey: input.resolveUserKey,
|
|
44
|
-
snapshots: [evidence.organization, ...evidence.groups],
|
|
45
|
-
});
|
|
46
|
-
const organization = policies.find((policy) => policy.principalType === "organization");
|
|
47
|
-
if (!organization)
|
|
48
|
-
reject("organization snapshot is missing");
|
|
49
|
-
const directories = await verifyDirectories({ ...input, organization });
|
|
50
|
-
for (const group of policies.filter((policy) => policy.principalType === "group")) {
|
|
51
|
-
const directory = directories.find((candidate) => candidate.groupHeads.some((reference) => principalHeadMatchesReference(group.state, reference)));
|
|
52
|
-
if (!directory)
|
|
53
|
-
reject("group state is absent from signed directory history");
|
|
54
|
-
// The snapshot's authenticated predecessor chain supplies older states;
|
|
55
|
-
// only its bound head needs to appear in a directory payload.
|
|
56
|
-
for (const { state } of group.history) {
|
|
57
|
-
if (state.externalAuthority &&
|
|
58
|
-
state.externalAuthority.principalId !== directory.adminGroupId)
|
|
59
|
-
reject("group authority is not the organization's Admins group");
|
|
60
|
-
}
|
|
6
|
+
const stillCurrent = () => input.stillCurrent?.() !== false;
|
|
7
|
+
assertProjectionVerificationCurrent(stillCurrent);
|
|
8
|
+
if (!input.evidence.organization) {
|
|
9
|
+
if (input.evidence.groups.length ||
|
|
10
|
+
input.evidence.organizationPayloads.length ||
|
|
11
|
+
input.references.length)
|
|
12
|
+
throw new KeyingVerificationError("missing_dependency", "Projection omits required organization history");
|
|
13
|
+
return { policies: [], stillCurrent };
|
|
61
14
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return
|
|
15
|
+
const resolve = input.warmReferencedPrincipalPolicies?.resolveProjectionHistory;
|
|
16
|
+
if (!resolve)
|
|
17
|
+
throw new ProjectionDependencyUnavailableError("Private projection history recovery is unavailable");
|
|
18
|
+
const result = await resolve({ ...input, stillCurrent });
|
|
19
|
+
assertProjectionVerificationCurrent(stillCurrent);
|
|
20
|
+
assertProjectionVerificationCurrent(result.stillCurrent);
|
|
21
|
+
return result;
|
|
69
22
|
}
|
|
70
23
|
//# sourceMappingURL=projectionPolicyEvidence.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectionPolicyEvidence.js","sourceRoot":"","sources":["projectionPolicyEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"projectionPolicyEvidence.js","sourceRoot":"","sources":["projectionPolicyEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GAExB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,oCAAoC,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,mCAAmC,GAGpC,MAAM,SAAS,CAAC;AAEjB,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAQpD;IACC,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,CAAC;IAC5D,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;QACjC,IACE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM;YAC5B,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC,MAAM;YAC1C,KAAK,CAAC,UAAU,CAAC,MAAM;YAEvB,MAAM,IAAI,uBAAuB,CAC/B,oBAAoB,EACpB,gDAAgD,CACjD,CAAC;QACJ,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,OAAO,GACX,KAAK,CAAC,+BAA+B,EAAE,wBAAwB,CAAC;IAClE,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,oCAAoC,CAC5C,oDAAoD,CACrD,CAAC;IACJ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IACzD,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,mCAAmC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport type { ProjectionPolicyEvidenceResponse } from \"@tearleads/validators/response\";\nimport { ProjectionDependencyUnavailableError } from \"./dependencyUnavailable\";\nimport {\n assertProjectionVerificationCurrent,\n type ReferencedPrincipalPolicyWarmer,\n type ResolvedProjectionPolicyHistory,\n} from \"./types\";\n\n/** Recover public authorization without admitting historical heads as current policy. */\nexport async function verifyProjectionPolicyEvidence(input: {\n readonly evidence: ProjectionPolicyEvidenceResponse;\n readonly organizationId: string;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n}): Promise<ResolvedProjectionPolicyHistory> {\n const stillCurrent = () => input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(stillCurrent);\n if (!input.evidence.organization) {\n if (\n input.evidence.groups.length ||\n input.evidence.organizationPayloads.length ||\n input.references.length\n )\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Projection omits required organization history\",\n );\n return { policies: [], stillCurrent };\n }\n const resolve =\n input.warmReferencedPrincipalPolicies?.resolveProjectionHistory;\n if (!resolve)\n throw new ProjectionDependencyUnavailableError(\n \"Private projection history recovery is unavailable\",\n );\n const result = await resolve({ ...input, stillCurrent });\n assertProjectionVerificationCurrent(stillCurrent);\n assertProjectionVerificationCurrent(result.stillCurrent);\n return result;\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReferencedPrincipalHead, VerifiedPrincipalPolicyCurrent } from "../../internal/crypto/index.js";
|
|
2
|
-
import type { PrincipalPolicyBundleResponse } from "../../internal/validators/response/index.js";
|
|
1
|
+
import type { ReferencedPrincipalHead, VerifiedPrincipalPolicyCurrent, VerifiedPrincipalPolicySelection } from "../../internal/crypto/index.js";
|
|
2
|
+
import type { PrincipalPolicyBundleResponse, ProjectionPolicyEvidenceResponse } from "../../internal/validators/response/index.js";
|
|
3
3
|
import type { PrincipalPolicyCurrentEvidence } from "../principals/principalPolicyEvidence.js";
|
|
4
4
|
import type { TrustedUserIdentity } from "../trustedUserIdentity/index.js";
|
|
5
5
|
export type ProjectionUserKey = TrustedUserIdentity;
|
|
@@ -28,9 +28,20 @@ export interface PrincipalPolicyBundleCacheRequest {
|
|
|
28
28
|
readonly organizationId: string;
|
|
29
29
|
readonly stillCurrent?: (() => boolean) | undefined;
|
|
30
30
|
}
|
|
31
|
+
export interface ProjectionPolicyHistoryResolveRequest {
|
|
32
|
+
readonly organizationId: string;
|
|
33
|
+
readonly evidence: ProjectionPolicyEvidenceResponse;
|
|
34
|
+
readonly references: readonly ReferencedPrincipalHead[];
|
|
35
|
+
readonly stillCurrent?: (() => boolean) | undefined;
|
|
36
|
+
}
|
|
37
|
+
export interface ResolvedProjectionPolicyHistory {
|
|
38
|
+
readonly policies: readonly VerifiedPrincipalPolicySelection[];
|
|
39
|
+
readonly stillCurrent: () => boolean;
|
|
40
|
+
}
|
|
31
41
|
export type PrincipalPolicyBundleCacher = (input: PrincipalPolicyBundleCacheRequest) => Promise<void>;
|
|
32
42
|
export type ReferencedPrincipalPolicyWarmer = ((input: ReferencedPrincipalPolicyWarmRequest) => Promise<void>) & {
|
|
33
43
|
readonly cacheBundles?: PrincipalPolicyBundleCacher | undefined;
|
|
44
|
+
readonly resolveProjectionHistory?: ((input: ProjectionPolicyHistoryResolveRequest) => Promise<ResolvedProjectionPolicyHistory>) | undefined;
|
|
34
45
|
readonly resolveReference?: ((input: PrincipalPolicyResolveRequest) => Promise<ResolvedPrincipalPolicyEvidence>) | undefined;
|
|
35
46
|
};
|
|
36
47
|
export declare class ProjectionVerificationCancelledError extends Error {
|
|
@@ -38,7 +38,22 @@ export function generationGuardedPrincipalPolicyWarmer(warmer, stillCurrent) {
|
|
|
38
38
|
const guardWithCapabilities = (operation) => {
|
|
39
39
|
const guarded = guard(operation);
|
|
40
40
|
const resolve = operation.resolveReference;
|
|
41
|
+
const resolveProjectionHistory = operation.resolveProjectionHistory;
|
|
41
42
|
return Object.assign(guarded, {
|
|
43
|
+
...(resolveProjectionHistory
|
|
44
|
+
? {
|
|
45
|
+
resolveProjectionHistory: async (input) => {
|
|
46
|
+
const current = () => stillCurrent() && input.stillCurrent?.() !== false;
|
|
47
|
+
assertProjectionVerificationCurrent(current);
|
|
48
|
+
const result = await resolveProjectionHistory({
|
|
49
|
+
...input,
|
|
50
|
+
stillCurrent: current,
|
|
51
|
+
});
|
|
52
|
+
assertProjectionVerificationCurrent(current);
|
|
53
|
+
return result;
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
: {}),
|
|
42
57
|
...(resolve
|
|
43
58
|
? {
|
|
44
59
|
resolveReference: async (input) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ReferencedPrincipalHead,\n VerifiedPrincipalPolicyCurrent,\n VerifiedPrincipalPolicySelection,\n} from \"@tearleads/crypto\";\nimport type {\n PrincipalPolicyBundleResponse,\n ProjectionPolicyEvidenceResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../principals/principalPolicyEvidence\";\nimport type { TrustedUserIdentity } from \"../trustedUserIdentity\";\n\nexport type ProjectionUserKey = TrustedUserIdentity;\n\nexport type ProjectionUserKeyResolver = (\n userId: string,\n) => Promise<ProjectionUserKey | null>;\n\nexport type PrincipalPolicyCache = Map<string, PrincipalPolicyCurrentEvidence>;\n\nexport interface PrincipalPolicyResolveRequest {\n /** Identity of one projection collection, never caller-supplied evidence. */\n readonly recoveryBatch?: object | undefined;\n readonly organizationId: string;\n readonly reference: ReferencedPrincipalHead;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ResolvedPrincipalPolicyEvidence {\n readonly stillCurrent: () => boolean;\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicyCurrent;\n readonly dependencies: readonly VerifiedPrincipalPolicyCurrent[];\n}\n\nexport interface ReferencedPrincipalPolicyWarmRequest {\n readonly organizationId: string;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface PrincipalPolicyBundleCacheRequest {\n readonly bundles: readonly PrincipalPolicyBundleResponse[];\n readonly organizationId: string;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ProjectionPolicyHistoryResolveRequest {\n readonly organizationId: string;\n readonly evidence: ProjectionPolicyEvidenceResponse;\n readonly references: readonly ReferencedPrincipalHead[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\nexport interface ResolvedProjectionPolicyHistory {\n readonly policies: readonly VerifiedPrincipalPolicySelection[];\n readonly stillCurrent: () => boolean;\n}\n\nexport type PrincipalPolicyBundleCacher = (\n input: PrincipalPolicyBundleCacheRequest,\n) => Promise<void>;\n\nexport type ReferencedPrincipalPolicyWarmer = ((\n input: ReferencedPrincipalPolicyWarmRequest,\n) => Promise<void>) & {\n readonly cacheBundles?: PrincipalPolicyBundleCacher | undefined;\n readonly resolveProjectionHistory?:\n | ((\n input: ProjectionPolicyHistoryResolveRequest,\n ) => Promise<ResolvedProjectionPolicyHistory>)\n | undefined;\n readonly resolveReference?:\n | ((\n input: PrincipalPolicyResolveRequest,\n ) => Promise<ResolvedPrincipalPolicyEvidence>)\n | undefined;\n};\n\nexport class ProjectionVerificationCancelledError extends Error {\n constructor() {\n super(\"Projection verification generation expired\");\n this.name = \"ProjectionVerificationCancelledError\";\n }\n}\n\nconst projectionVerificationCancellation =\n new ProjectionVerificationCancelledError();\n\nexport function isProjectionVerificationCancelledError(\n error: unknown,\n): error is ProjectionVerificationCancelledError {\n return error === projectionVerificationCancellation;\n}\n\nexport function rethrowProjectionVerificationCancelled(error: unknown): void {\n if (isProjectionVerificationCancelledError(error)) throw error;\n}\n\nexport async function nullOnProjectionVerificationCancellation<T>(\n operation: () => Promise<T>,\n): Promise<T | null> {\n try {\n return await operation();\n } catch (error) {\n if (isProjectionVerificationCancelledError(error)) return null;\n throw error;\n }\n}\n\nexport function assertProjectionVerificationCurrent(\n stillCurrent: (() => boolean) | undefined,\n): void {\n if (stillCurrent?.() === false) {\n throw projectionVerificationCancellation;\n }\n}\n\nexport function generationGuardedPrincipalPolicyWarmer(\n warmer: ReferencedPrincipalPolicyWarmer | undefined,\n stillCurrent: (() => boolean) | undefined,\n): ReferencedPrincipalPolicyWarmer | undefined {\n if (!warmer || !stillCurrent) return warmer;\n const guard =\n (operation: ReferencedPrincipalPolicyWarmer) =>\n async (input: ReferencedPrincipalPolicyWarmRequest) => {\n assertProjectionVerificationCurrent(stillCurrent);\n await operation({ ...input, stillCurrent });\n assertProjectionVerificationCurrent(stillCurrent);\n };\n const guardWithCapabilities = (\n operation: ReferencedPrincipalPolicyWarmer,\n ): ReferencedPrincipalPolicyWarmer => {\n const guarded = guard(operation);\n const resolve = operation.resolveReference;\n const resolveProjectionHistory = operation.resolveProjectionHistory;\n return Object.assign(guarded, {\n ...(resolveProjectionHistory\n ? {\n resolveProjectionHistory: async (\n input: ProjectionPolicyHistoryResolveRequest,\n ) => {\n const current = () =>\n stillCurrent() && input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(current);\n const result = await resolveProjectionHistory({\n ...input,\n stillCurrent: current,\n });\n assertProjectionVerificationCurrent(current);\n return result;\n },\n }\n : {}),\n ...(resolve\n ? {\n resolveReference: async (input: PrincipalPolicyResolveRequest) => {\n const current = () =>\n stillCurrent() && input.stillCurrent?.() !== false;\n assertProjectionVerificationCurrent(current);\n const result = await resolve({ ...input, stillCurrent: current });\n assertProjectionVerificationCurrent(current);\n return result;\n },\n }\n : {}),\n ...(operation.cacheBundles\n ? {\n cacheBundles: async (input: PrincipalPolicyBundleCacheRequest) => {\n assertProjectionVerificationCurrent(stillCurrent);\n await operation.cacheBundles?.({ ...input, stillCurrent });\n assertProjectionVerificationCurrent(stillCurrent);\n },\n }\n : {}),\n });\n };\n return guardWithCapabilities(warmer);\n}\n\nexport function withGenerationGuardedPolicyWarmer<\n Input extends {\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly warmReferencedPrincipalPolicies?:\n | ReferencedPrincipalPolicyWarmer\n | undefined;\n },\n>(input: Input): Input {\n return {\n ...input,\n warmReferencedPrincipalPolicies: generationGuardedPrincipalPolicyWarmer(\n input.warmReferencedPrincipalPolicies,\n input.stillCurrent,\n ),\n };\n}\n"]}
|
|
@@ -5,6 +5,7 @@ import { ensureSqlTables } from "../sqlite/sqlSchema.js";
|
|
|
5
5
|
import { storeDocumentPurgeCheckpointInTransaction, } from "./documentPurgeCheckpointPersistence.js";
|
|
6
6
|
import { validateAccessManifestCheckpointEvidence } from "./keyingCheckpointEvidence.js";
|
|
7
7
|
import { accessManifestObjectKey, loadStoredAccessManifestCheckpoint, loadStoredPrincipalPolicyCheckpoint, principalPolicyKey, upsertAccessManifestCheckpointInTransaction, upsertPrincipalPolicyCheckpointInTransaction, } from "./keyingCheckpointPersistence.js";
|
|
8
|
+
import { validatePrincipalAuthorizationCheckpoints } from "./principalAuthorizationCheckpoints.js";
|
|
8
9
|
import { assertContainerNotRetired } from "./principalGrantRetirementPersistence.js";
|
|
9
10
|
import { assertPrincipalPolicyBundleStoredInTransaction, writePrincipalPolicyBundleInTransaction, } from "./principalPolicyPersistence.js";
|
|
10
11
|
import { assertBundleMatchesVerifiedPolicy } from "./verifiedPrincipalPolicyBundle.js";
|
|
@@ -106,7 +107,7 @@ async function writePolicyCheckpoints(tx, pending, updatedAt, organizationId) {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
async function ensureKeyingCheckpointValidationTables(input) {
|
|
109
|
-
await ensureSqlTables(input.execSql, input.policies.length > 0
|
|
110
|
+
await ensureSqlTables(input.execSql, input.policies.length > 0 || (input.authorizationPolicies?.length ?? 0) > 0
|
|
110
111
|
? [...principalPolicyTables, ...keyingCheckpointTables]
|
|
111
112
|
: keyingCheckpointTables);
|
|
112
113
|
}
|
|
@@ -116,6 +117,7 @@ export async function validateKeyingCheckpointsAtomically(input) {
|
|
|
116
117
|
const validate = async (tx) => {
|
|
117
118
|
await validateAccessAdvances(tx, input.access);
|
|
118
119
|
await validatePolicyAdvances(tx, input.policies);
|
|
120
|
+
await validatePrincipalAuthorizationCheckpoints(tx, input.authorizationPolicies ?? []);
|
|
119
121
|
};
|
|
120
122
|
const runtime = getClientSQLitePersistenceRuntime(input.execSql);
|
|
121
123
|
if (input.stillCurrent) {
|
|
@@ -139,6 +141,7 @@ export async function advanceKeyingCheckpointsAtomically(input) {
|
|
|
139
141
|
const advance = async (tx) => {
|
|
140
142
|
const access = await validateAccessAdvances(tx, input.access);
|
|
141
143
|
const policies = await validatePolicyAdvances(tx, input.policies);
|
|
144
|
+
await validatePrincipalAuthorizationCheckpoints(tx, input.authorizationPolicies ?? []);
|
|
142
145
|
await writeAccessCheckpoints(tx, access, updatedAt);
|
|
143
146
|
await writePolicyCheckpoints(tx, policies, updatedAt, input.organizationId);
|
|
144
147
|
if (input.documentPurgeCheckpoint) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyingCheckpointAdvancePersistence.js","sourceRoot":"","sources":["keyingCheckpointAdvancePersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AccessManifestCheckpoint,\n type AnyVerifiedPrincipalPolicy,\n KeyingVerificationError,\n type VerifiedAccessManifestCheckpointEvidence,\n type VerifiedPrincipalPolicy,\n type VerifiedPrincipalPolicyCurrent,\n verifyAccessManifestLocalCheckpoint,\n verifyPrincipalPolicyCheckpoint,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport {\n keyingCheckpointTables,\n principalPolicyTables,\n} from \"../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../sqlite/sqlSchema\";\nimport {\n type DocumentPurgeCheckpoint,\n storeDocumentPurgeCheckpointInTransaction,\n} from \"./documentPurgeCheckpointPersistence\";\nimport { validateAccessManifestCheckpointEvidence } from \"./keyingCheckpointEvidence\";\nimport {\n accessManifestObjectKey,\n loadStoredAccessManifestCheckpoint,\n loadStoredPrincipalPolicyCheckpoint,\n principalPolicyKey,\n upsertAccessManifestCheckpointInTransaction,\n upsertPrincipalPolicyCheckpointInTransaction,\n} from \"./keyingCheckpointPersistence\";\nimport { assertContainerNotRetired } from \"./principalGrantRetirementPersistence\";\nimport {\n assertPrincipalPolicyBundleStoredInTransaction,\n writePrincipalPolicyBundleInTransaction,\n} from \"./principalPolicyPersistence\";\nimport { assertBundleMatchesVerifiedPolicy } from \"./verifiedPrincipalPolicyBundle\";\n\nexport interface AccessManifestCheckpointAdvance {\n readonly head: VerifiedAccessManifestCheckpointEvidence;\n readonly predecessors: readonly VerifiedAccessManifestCheckpointEvidence[];\n}\n\ntype CheckpointPolicy =\n | AnyVerifiedPrincipalPolicy\n | VerifiedPrincipalPolicyCurrent;\n\ninterface KeyingCheckpointValidationInput {\n readonly access: readonly AccessManifestCheckpointAdvance[];\n readonly execSql: ExecSql;\n readonly policies: readonly CheckpointPolicy[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\ninterface VerifiedPrincipalPolicyBundleEntry {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly policy: VerifiedPrincipalPolicy;\n}\n\ninterface PendingAccessCheckpoint {\n readonly checkpoint: AccessManifestCheckpoint;\n}\n\nfunction validateAccessAdvance(\n advance: AccessManifestCheckpointAdvance,\n localCheckpoint: AccessManifestCheckpoint | null,\n): PendingAccessCheckpoint {\n const current = {\n ...advance.head.checkpoint,\n previousManifestHash: advance.head.manifest.previousManifestHash,\n };\n const predecessors = [...advance.predecessors].sort(\n (left, right) => left.checkpoint.epoch - right.checkpoint.epoch,\n );\n\n if (localCheckpoint && current.epoch <= localCheckpoint.epoch) {\n verifyAccessManifestLocalCheckpoint({\n current,\n localCheckpoint,\n checkpointPredecessors: undefined,\n });\n }\n\n validateAccessManifestCheckpointEvidence({\n head: advance.head,\n predecessors,\n localCheckpoint,\n });\n\n verifyAccessManifestLocalCheckpoint({\n current,\n localCheckpoint,\n checkpointPredecessors: predecessors.filter(\n (manifest) =>\n localCheckpoint !== null &&\n manifest.checkpoint.epoch > localCheckpoint.epoch &&\n manifest.checkpoint.epoch < current.epoch,\n ),\n });\n\n return {\n checkpoint: advance.head.checkpoint,\n };\n}\n\nasync function validateAccessAdvances(\n tx: ClientSQLiteTransactionScope,\n advances: readonly AccessManifestCheckpointAdvance[],\n): Promise<Map<string, PendingAccessCheckpoint>> {\n const pending = new Map<string, PendingAccessCheckpoint>();\n\n for (const advance of advances) {\n await assertContainerNotRetired(tx, advance.head.checkpoint);\n const key = accessManifestObjectKey(advance.head.checkpoint);\n if (pending.has(key)) {\n throw new KeyingVerificationError(\n \"equivocation\",\n `projection declares multiple access checkpoint heads for ${key}`,\n );\n }\n const localCheckpoint = await loadStoredAccessManifestCheckpoint(\n tx,\n advance.head.checkpoint,\n );\n pending.set(key, validateAccessAdvance(advance, localCheckpoint));\n }\n\n return pending;\n}\n\nfunction extendsObservedPolicy(\n head: CheckpointPolicy,\n candidate: CheckpointPolicy,\n): boolean {\n const history =\n \"retainedHistory\" in head ? head.retainedHistory : head.history;\n return (\n history?.some(\n ({ state }) =>\n state.principalType === candidate.principalType &&\n state.principalId === candidate.principalId &&\n state.version === candidate.version &&\n state.stateHash === candidate.stateHash,\n ) ?? false\n );\n}\n\nasync function validatePolicyAdvances(\n tx: ClientSQLiteTransactionScope,\n policies: readonly CheckpointPolicy[],\n): Promise<Map<string, CheckpointPolicy>> {\n const policiesByPrincipal = new Map<string, CheckpointPolicy[]>();\n for (const policy of policies) {\n const key = principalPolicyKey(policy);\n const candidates = policiesByPrincipal.get(key) ?? [];\n candidates.push(policy);\n policiesByPrincipal.set(key, candidates);\n }\n\n const pending = new Map<string, CheckpointPolicy>();\n for (const key of [...policiesByPrincipal.keys()].sort()) {\n const candidates = policiesByPrincipal.get(key) ?? [];\n const maxVersion = Math.max(...candidates.map((policy) => policy.version));\n const heads = candidates.filter((policy) => policy.version === maxVersion);\n const head = heads[0];\n if (!head) {\n continue;\n }\n if (heads.some((candidate) => candidate.stateHash !== head.stateHash)) {\n throw new KeyingVerificationError(\n \"equivocation\",\n `principal policy declares conflicting heads for ${key}`,\n );\n }\n for (const candidate of candidates) {\n if (candidate.version === head.version) {\n continue;\n }\n if (!extendsObservedPolicy(head, candidate)) {\n throw new KeyingVerificationError(\n \"stale_predecessor\",\n `principal policy head does not extend observed state for ${key}`,\n );\n }\n }\n\n const localCheckpoint = await loadStoredPrincipalPolicyCheckpoint(tx, head);\n verifyPrincipalPolicyCheckpoint({\n chain:\n \"retainedHistory\" in head ? head.retainedHistory : (head.history ?? []),\n currentState: head.state,\n localCheckpoint,\n });\n pending.set(key, head);\n }\n\n return pending;\n}\n\nasync function writeAccessCheckpoints(\n tx: ClientSQLiteTransactionScope,\n pending: ReadonlyMap<string, PendingAccessCheckpoint>,\n updatedAt: string,\n): Promise<void> {\n for (const { checkpoint } of pending.values()) {\n await upsertAccessManifestCheckpointInTransaction(\n tx,\n checkpoint,\n updatedAt,\n );\n }\n}\n\nasync function writePolicyCheckpoints(\n tx: ClientSQLiteTransactionScope,\n pending: ReadonlyMap<string, CheckpointPolicy>,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n for (const policy of pending.values()) {\n await upsertPrincipalPolicyCheckpointInTransaction(\n tx,\n policy.checkpoint,\n updatedAt,\n organizationId,\n );\n }\n}\n\nasync function ensureKeyingCheckpointValidationTables(\n input: KeyingCheckpointValidationInput,\n): Promise<void> {\n await ensureSqlTables(\n input.execSql,\n input.policies.length > 0\n ? [...principalPolicyTables, ...keyingCheckpointTables]\n : keyingCheckpointTables,\n );\n}\n\n/** Re-checks verified candidates against durable pins without advancing them. */\nexport async function validateKeyingCheckpointsAtomically(\n input: KeyingCheckpointValidationInput,\n): Promise<void> {\n await ensureKeyingCheckpointValidationTables(input);\n const validate = async (tx: ClientSQLiteTransactionScope) => {\n await validateAccessAdvances(tx, input.access);\n await validatePolicyAdvances(tx, input.policies);\n };\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n if (input.stillCurrent) {\n await runtime.guardedTransaction(validate, input.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(validate, { behavior: \"immediate\" });\n}\n\n/**\n * Re-check every verified projection candidate against the latest durable pins\n * and advance the complete batch atomically. Signature verification and remote\n * fetching happen before this short transaction; only checkpoint comparison\n * and persistence are serialized here.\n */\nexport async function advanceKeyingCheckpointsAtomically(input: {\n readonly access: readonly AccessManifestCheckpointAdvance[];\n readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n readonly policies: readonly CheckpointPolicy[];\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n await ensureKeyingCheckpointValidationTables(input);\n const updatedAt = new Date().toISOString();\n\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const advance = async (tx: ClientSQLiteTransactionScope) => {\n const access = await validateAccessAdvances(tx, input.access);\n const policies = await validatePolicyAdvances(tx, input.policies);\n\n await writeAccessCheckpoints(tx, access, updatedAt);\n await writePolicyCheckpoints(tx, policies, updatedAt, input.organizationId);\n if (input.documentPurgeCheckpoint) {\n await storeDocumentPurgeCheckpointInTransaction(\n tx,\n input.documentPurgeCheckpoint,\n updatedAt,\n );\n }\n };\n if (input.stillCurrent) {\n await runtime.guardedTransaction(advance, input.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(advance, { behavior: \"immediate\" });\n}\n\n/**\n * Persists each verified full policy bundle together with its durable head.\n * This prevents a crash or bundle-write failure from leaving a checkpoint\n * without the exact same-head payload and member-envelope evidence.\n */\nexport async function persistVerifiedPrincipalPolicyBundlesAtomically(input: {\n readonly entries: readonly VerifiedPrincipalPolicyBundleEntry[];\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly updatedAt: string;\n}): Promise<void> {\n const seen = new Set<string>();\n for (const entry of input.entries) {\n const key = principalPolicyKey(entry.policy);\n if (seen.has(key)) {\n throw new KeyingVerificationError(\n \"duplicate_entry\",\n `verified policy bundle batch repeats ${key}`,\n );\n }\n seen.add(key);\n }\n await Promise.all(\n input.entries.map((entry) => assertBundleMatchesVerifiedPolicy(entry)),\n );\n await ensureSqlTables(input.execSql, [\n ...principalPolicyTables,\n ...keyingCheckpointTables,\n ]);\n\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const persist = async (tx: ClientSQLiteTransactionScope) => {\n const policies = await validatePolicyAdvances(\n tx,\n input.entries.map((entry) => entry.policy),\n );\n for (const entry of input.entries) {\n await writePrincipalPolicyBundleInTransaction(\n tx,\n entry.bundle,\n input.updatedAt,\n input.organizationId,\n );\n await assertPrincipalPolicyBundleStoredInTransaction(tx, entry.bundle);\n }\n await writePolicyCheckpoints(\n tx,\n policies,\n input.updatedAt,\n input.organizationId,\n );\n for (const policy of policies.values()) {\n const checkpoint = await loadStoredPrincipalPolicyCheckpoint(tx, policy);\n if (\n !checkpoint ||\n checkpoint.version !== policy.version ||\n checkpoint.stateHash !== policy.stateHash\n ) {\n throw new Error(\n \"Verified principal policy checkpoint was not persisted\",\n );\n }\n }\n };\n if (input.stillCurrent) {\n await runtime.guardedTransaction(persist, input.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(persist, { behavior: \"immediate\" });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"keyingCheckpointAdvancePersistence.js","sourceRoot":"","sources":["keyingCheckpointAdvancePersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,uBAAuB,EAKvB,mCAAmC,EACnC,+BAA+B,GAChC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,iCAAiC,GAClC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAgB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAEL,yCAAyC,GAC1C,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,wCAAwC,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EACL,uBAAuB,EACvB,kCAAkC,EAClC,mCAAmC,EACnC,kBAAkB,EAClB,2CAA2C,EAC3C,4CAA4C,GAC7C,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,yCAAyC,EAAE,MAAM,qCAAqC,CAAC;AAChG,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EACL,8CAA8C,EAC9C,uCAAuC,GACxC,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AA8BpF,SAAS,qBAAqB,CAC5B,OAAwC,EACxC,eAAgD;IAEhD,MAAM,OAAO,GAAG;QACd,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU;QAC1B,oBAAoB,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB;KACjE,CAAC;IACF,MAAM,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI,CACjD,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAChE,CAAC;IAEF,IAAI,eAAe,IAAI,OAAO,CAAC,KAAK,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;QAC9D,mCAAmC,CAAC;YAClC,OAAO;YACP,eAAe;YACf,sBAAsB,EAAE,SAAS;SAClC,CAAC,CAAC;IACL,CAAC;IAED,wCAAwC,CAAC;QACvC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY;QACZ,eAAe;KAChB,CAAC,CAAC;IAEH,mCAAmC,CAAC;QAClC,OAAO;QACP,eAAe;QACf,sBAAsB,EAAE,YAAY,CAAC,MAAM,CACzC,CAAC,QAAQ,EAAE,EAAE,CACX,eAAe,KAAK,IAAI;YACxB,QAAQ,CAAC,UAAU,CAAC,KAAK,GAAG,eAAe,CAAC,KAAK;YACjD,QAAQ,CAAC,UAAU,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAC5C;KACF,CAAC,CAAC;IAEH,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU;KACpC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,EAAgC,EAChC,QAAoD;IAEpD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmC,CAAC;IAE3D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,yBAAyB,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,uBAAuB,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,4DAA4D,GAAG,EAAE,CAClE,CAAC;QACJ,CAAC;QACD,MAAM,eAAe,GAAG,MAAM,kCAAkC,CAC9D,EAAE,EACF,OAAO,CAAC,IAAI,CAAC,UAAU,CACxB,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,qBAAqB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAsB,EACtB,SAA2B;IAE3B,MAAM,OAAO,GACX,iBAAiB,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;IAClE,OAAO,CACL,OAAO,EAAE,IAAI,CACX,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CACZ,KAAK,CAAC,aAAa,KAAK,SAAS,CAAC,aAAa;QAC/C,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW;QAC3C,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO;QACnC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAC1C,IAAI,KAAK,CACX,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,EAAgC,EAChC,QAAqC;IAErC,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAA8B,CAAC;IAClE,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtD,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4B,CAAC;IACpD,KAAK,MAAM,GAAG,IAAI,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACzD,MAAM,UAAU,GAAG,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACtD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC;QAC3E,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACtE,MAAM,IAAI,uBAAuB,CAC/B,cAAc,EACd,mDAAmD,GAAG,EAAE,CACzD,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,SAAS,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YACD,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;gBAC5C,MAAM,IAAI,uBAAuB,CAC/B,mBAAmB,EACnB,4DAA4D,GAAG,EAAE,CAClE,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,eAAe,GAAG,MAAM,mCAAmC,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC5E,+BAA+B,CAAC;YAC9B,KAAK,EACH,iBAAiB,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;YACzE,YAAY,EAAE,IAAI,CAAC,KAAK;YACxB,eAAe;SAChB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,EAAgC,EAChC,OAAqD,EACrD,SAAiB;IAEjB,KAAK,MAAM,EAAE,UAAU,EAAE,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9C,MAAM,2CAA2C,CAC/C,EAAE,EACF,UAAU,EACV,SAAS,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,EAAgC,EAChC,OAA8C,EAC9C,SAAiB,EACjB,cAAmC;IAEnC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,MAAM,4CAA4C,CAChD,EAAE,EACF,MAAM,CAAC,UAAU,EACjB,SAAS,EACT,cAAc,CACf,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sCAAsC,CACnD,KAAsC;IAEtC,MAAM,eAAe,CACnB,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QACzE,CAAC,CAAC,CAAC,GAAG,qBAAqB,EAAE,GAAG,sBAAsB,CAAC;QACvD,CAAC,CAAC,sBAAsB,CAC3B,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACvD,KAAsC;IAEtC,MAAM,sCAAsC,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,KAAK,EAAE,EAAgC,EAAE,EAAE;QAC1D,MAAM,sBAAsB,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,sBAAsB,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,yCAAyC,CAC7C,EAAE,EACF,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAClC,CAAC;IACJ,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjE,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,EAAE;YAC7D,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kCAAkC,CAAC,KAUxD;IACC,MAAM,sCAAsC,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE3C,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,KAAK,EAAE,EAAgC,EAAE,EAAE;QACzD,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,yCAAyC,CAC7C,EAAE,EACF,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAClC,CAAC;QAEF,MAAM,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACpD,MAAM,sBAAsB,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;QAC5E,IAAI,KAAK,CAAC,uBAAuB,EAAE,CAAC;YAClC,MAAM,yCAAyC,CAC7C,EAAE,EACF,KAAK,CAAC,uBAAuB,EAC7B,SAAS,CACV,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IACF,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE;YAC5D,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,+CAA+C,CAAC,KAMrE;IACC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,uBAAuB,CAC/B,iBAAiB,EACjB,wCAAwC,GAAG,EAAE,CAC9C,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,iCAAiC,CAAC,KAAK,CAAC,CAAC,CACvE,CAAC;IACF,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE;QACnC,GAAG,qBAAqB;QACxB,GAAG,sBAAsB;KAC1B,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,iCAAiC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,KAAK,EAAE,EAAgC,EAAE,EAAE;QACzD,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAC3C,EAAE,EACF,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAC3C,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClC,MAAM,uCAAuC,CAC3C,EAAE,EACF,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,cAAc,CACrB,CAAC;YACF,MAAM,8CAA8C,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,sBAAsB,CAC1B,EAAE,EACF,QAAQ,EACR,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,cAAc,CACrB,CAAC;QACF,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,MAAM,mCAAmC,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACzE,IACE,CAAC,UAAU;gBACX,UAAU,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO;gBACrC,UAAU,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,EACzC,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,wDAAwD,CACzD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE;YAC5D,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,MAAM,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import {\n type AccessManifestCheckpoint,\n type AnyVerifiedPrincipalPolicy,\n KeyingVerificationError,\n type VerifiedAccessManifestCheckpointEvidence,\n type VerifiedPrincipalPolicy,\n type VerifiedPrincipalPolicyCurrent,\n type VerifiedPrincipalPolicySelection,\n verifyAccessManifestLocalCheckpoint,\n verifyPrincipalPolicyCheckpoint,\n} from \"@tearleads/crypto\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport {\n keyingCheckpointTables,\n principalPolicyTables,\n} from \"../sqlite/schema\";\nimport {\n type ClientSQLiteTransactionScope,\n getClientSQLitePersistenceRuntime,\n} from \"../sqlite/sqlitePersistenceRuntime\";\nimport { type ExecSql, ensureSqlTables } from \"../sqlite/sqlSchema\";\nimport {\n type DocumentPurgeCheckpoint,\n storeDocumentPurgeCheckpointInTransaction,\n} from \"./documentPurgeCheckpointPersistence\";\nimport { validateAccessManifestCheckpointEvidence } from \"./keyingCheckpointEvidence\";\nimport {\n accessManifestObjectKey,\n loadStoredAccessManifestCheckpoint,\n loadStoredPrincipalPolicyCheckpoint,\n principalPolicyKey,\n upsertAccessManifestCheckpointInTransaction,\n upsertPrincipalPolicyCheckpointInTransaction,\n} from \"./keyingCheckpointPersistence\";\nimport { validatePrincipalAuthorizationCheckpoints } from \"./principalAuthorizationCheckpoints\";\nimport { assertContainerNotRetired } from \"./principalGrantRetirementPersistence\";\nimport {\n assertPrincipalPolicyBundleStoredInTransaction,\n writePrincipalPolicyBundleInTransaction,\n} from \"./principalPolicyPersistence\";\nimport { assertBundleMatchesVerifiedPolicy } from \"./verifiedPrincipalPolicyBundle\";\n\nexport interface AccessManifestCheckpointAdvance {\n readonly head: VerifiedAccessManifestCheckpointEvidence;\n readonly predecessors: readonly VerifiedAccessManifestCheckpointEvidence[];\n}\n\ntype CheckpointPolicy =\n | AnyVerifiedPrincipalPolicy\n | VerifiedPrincipalPolicyCurrent;\n\ninterface KeyingCheckpointValidationInput {\n readonly access: readonly AccessManifestCheckpointAdvance[];\n readonly execSql: ExecSql;\n readonly policies: readonly CheckpointPolicy[];\n readonly authorizationPolicies?:\n | readonly VerifiedPrincipalPolicySelection[]\n | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}\n\ninterface VerifiedPrincipalPolicyBundleEntry {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly policy: VerifiedPrincipalPolicy;\n}\n\ninterface PendingAccessCheckpoint {\n readonly checkpoint: AccessManifestCheckpoint;\n}\n\nfunction validateAccessAdvance(\n advance: AccessManifestCheckpointAdvance,\n localCheckpoint: AccessManifestCheckpoint | null,\n): PendingAccessCheckpoint {\n const current = {\n ...advance.head.checkpoint,\n previousManifestHash: advance.head.manifest.previousManifestHash,\n };\n const predecessors = [...advance.predecessors].sort(\n (left, right) => left.checkpoint.epoch - right.checkpoint.epoch,\n );\n\n if (localCheckpoint && current.epoch <= localCheckpoint.epoch) {\n verifyAccessManifestLocalCheckpoint({\n current,\n localCheckpoint,\n checkpointPredecessors: undefined,\n });\n }\n\n validateAccessManifestCheckpointEvidence({\n head: advance.head,\n predecessors,\n localCheckpoint,\n });\n\n verifyAccessManifestLocalCheckpoint({\n current,\n localCheckpoint,\n checkpointPredecessors: predecessors.filter(\n (manifest) =>\n localCheckpoint !== null &&\n manifest.checkpoint.epoch > localCheckpoint.epoch &&\n manifest.checkpoint.epoch < current.epoch,\n ),\n });\n\n return {\n checkpoint: advance.head.checkpoint,\n };\n}\n\nasync function validateAccessAdvances(\n tx: ClientSQLiteTransactionScope,\n advances: readonly AccessManifestCheckpointAdvance[],\n): Promise<Map<string, PendingAccessCheckpoint>> {\n const pending = new Map<string, PendingAccessCheckpoint>();\n\n for (const advance of advances) {\n await assertContainerNotRetired(tx, advance.head.checkpoint);\n const key = accessManifestObjectKey(advance.head.checkpoint);\n if (pending.has(key)) {\n throw new KeyingVerificationError(\n \"equivocation\",\n `projection declares multiple access checkpoint heads for ${key}`,\n );\n }\n const localCheckpoint = await loadStoredAccessManifestCheckpoint(\n tx,\n advance.head.checkpoint,\n );\n pending.set(key, validateAccessAdvance(advance, localCheckpoint));\n }\n\n return pending;\n}\n\nfunction extendsObservedPolicy(\n head: CheckpointPolicy,\n candidate: CheckpointPolicy,\n): boolean {\n const history =\n \"retainedHistory\" in head ? head.retainedHistory : head.history;\n return (\n history?.some(\n ({ state }) =>\n state.principalType === candidate.principalType &&\n state.principalId === candidate.principalId &&\n state.version === candidate.version &&\n state.stateHash === candidate.stateHash,\n ) ?? false\n );\n}\n\nasync function validatePolicyAdvances(\n tx: ClientSQLiteTransactionScope,\n policies: readonly CheckpointPolicy[],\n): Promise<Map<string, CheckpointPolicy>> {\n const policiesByPrincipal = new Map<string, CheckpointPolicy[]>();\n for (const policy of policies) {\n const key = principalPolicyKey(policy);\n const candidates = policiesByPrincipal.get(key) ?? [];\n candidates.push(policy);\n policiesByPrincipal.set(key, candidates);\n }\n\n const pending = new Map<string, CheckpointPolicy>();\n for (const key of [...policiesByPrincipal.keys()].sort()) {\n const candidates = policiesByPrincipal.get(key) ?? [];\n const maxVersion = Math.max(...candidates.map((policy) => policy.version));\n const heads = candidates.filter((policy) => policy.version === maxVersion);\n const head = heads[0];\n if (!head) {\n continue;\n }\n if (heads.some((candidate) => candidate.stateHash !== head.stateHash)) {\n throw new KeyingVerificationError(\n \"equivocation\",\n `principal policy declares conflicting heads for ${key}`,\n );\n }\n for (const candidate of candidates) {\n if (candidate.version === head.version) {\n continue;\n }\n if (!extendsObservedPolicy(head, candidate)) {\n throw new KeyingVerificationError(\n \"stale_predecessor\",\n `principal policy head does not extend observed state for ${key}`,\n );\n }\n }\n\n const localCheckpoint = await loadStoredPrincipalPolicyCheckpoint(tx, head);\n verifyPrincipalPolicyCheckpoint({\n chain:\n \"retainedHistory\" in head ? head.retainedHistory : (head.history ?? []),\n currentState: head.state,\n localCheckpoint,\n });\n pending.set(key, head);\n }\n\n return pending;\n}\n\nasync function writeAccessCheckpoints(\n tx: ClientSQLiteTransactionScope,\n pending: ReadonlyMap<string, PendingAccessCheckpoint>,\n updatedAt: string,\n): Promise<void> {\n for (const { checkpoint } of pending.values()) {\n await upsertAccessManifestCheckpointInTransaction(\n tx,\n checkpoint,\n updatedAt,\n );\n }\n}\n\nasync function writePolicyCheckpoints(\n tx: ClientSQLiteTransactionScope,\n pending: ReadonlyMap<string, CheckpointPolicy>,\n updatedAt: string,\n organizationId?: string | undefined,\n): Promise<void> {\n for (const policy of pending.values()) {\n await upsertPrincipalPolicyCheckpointInTransaction(\n tx,\n policy.checkpoint,\n updatedAt,\n organizationId,\n );\n }\n}\n\nasync function ensureKeyingCheckpointValidationTables(\n input: KeyingCheckpointValidationInput,\n): Promise<void> {\n await ensureSqlTables(\n input.execSql,\n input.policies.length > 0 || (input.authorizationPolicies?.length ?? 0) > 0\n ? [...principalPolicyTables, ...keyingCheckpointTables]\n : keyingCheckpointTables,\n );\n}\n\n/** Re-checks verified candidates against durable pins without advancing them. */\nexport async function validateKeyingCheckpointsAtomically(\n input: KeyingCheckpointValidationInput,\n): Promise<void> {\n await ensureKeyingCheckpointValidationTables(input);\n const validate = async (tx: ClientSQLiteTransactionScope) => {\n await validateAccessAdvances(tx, input.access);\n await validatePolicyAdvances(tx, input.policies);\n await validatePrincipalAuthorizationCheckpoints(\n tx,\n input.authorizationPolicies ?? [],\n );\n };\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n if (input.stillCurrent) {\n await runtime.guardedTransaction(validate, input.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(validate, { behavior: \"immediate\" });\n}\n\n/**\n * Re-check every verified projection candidate against the latest durable pins\n * and advance the complete batch atomically. Signature verification and remote\n * fetching happen before this short transaction; only checkpoint comparison\n * and persistence are serialized here.\n */\nexport async function advanceKeyingCheckpointsAtomically(input: {\n readonly access: readonly AccessManifestCheckpointAdvance[];\n readonly documentPurgeCheckpoint?: DocumentPurgeCheckpoint | undefined;\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n readonly policies: readonly CheckpointPolicy[];\n readonly authorizationPolicies?:\n | readonly VerifiedPrincipalPolicySelection[]\n | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<void> {\n await ensureKeyingCheckpointValidationTables(input);\n const updatedAt = new Date().toISOString();\n\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const advance = async (tx: ClientSQLiteTransactionScope) => {\n const access = await validateAccessAdvances(tx, input.access);\n const policies = await validatePolicyAdvances(tx, input.policies);\n await validatePrincipalAuthorizationCheckpoints(\n tx,\n input.authorizationPolicies ?? [],\n );\n\n await writeAccessCheckpoints(tx, access, updatedAt);\n await writePolicyCheckpoints(tx, policies, updatedAt, input.organizationId);\n if (input.documentPurgeCheckpoint) {\n await storeDocumentPurgeCheckpointInTransaction(\n tx,\n input.documentPurgeCheckpoint,\n updatedAt,\n );\n }\n };\n if (input.stillCurrent) {\n await runtime.guardedTransaction(advance, input.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(advance, { behavior: \"immediate\" });\n}\n\n/**\n * Persists each verified full policy bundle together with its durable head.\n * This prevents a crash or bundle-write failure from leaving a checkpoint\n * without the exact same-head payload and member-envelope evidence.\n */\nexport async function persistVerifiedPrincipalPolicyBundlesAtomically(input: {\n readonly entries: readonly VerifiedPrincipalPolicyBundleEntry[];\n readonly execSql: ExecSql;\n readonly organizationId?: string | undefined;\n readonly stillCurrent?: (() => boolean) | undefined;\n readonly updatedAt: string;\n}): Promise<void> {\n const seen = new Set<string>();\n for (const entry of input.entries) {\n const key = principalPolicyKey(entry.policy);\n if (seen.has(key)) {\n throw new KeyingVerificationError(\n \"duplicate_entry\",\n `verified policy bundle batch repeats ${key}`,\n );\n }\n seen.add(key);\n }\n await Promise.all(\n input.entries.map((entry) => assertBundleMatchesVerifiedPolicy(entry)),\n );\n await ensureSqlTables(input.execSql, [\n ...principalPolicyTables,\n ...keyingCheckpointTables,\n ]);\n\n const runtime = getClientSQLitePersistenceRuntime(input.execSql);\n const persist = async (tx: ClientSQLiteTransactionScope) => {\n const policies = await validatePolicyAdvances(\n tx,\n input.entries.map((entry) => entry.policy),\n );\n for (const entry of input.entries) {\n await writePrincipalPolicyBundleInTransaction(\n tx,\n entry.bundle,\n input.updatedAt,\n input.organizationId,\n );\n await assertPrincipalPolicyBundleStoredInTransaction(tx, entry.bundle);\n }\n await writePolicyCheckpoints(\n tx,\n policies,\n input.updatedAt,\n input.organizationId,\n );\n for (const policy of policies.values()) {\n const checkpoint = await loadStoredPrincipalPolicyCheckpoint(tx, policy);\n if (\n !checkpoint ||\n checkpoint.version !== policy.version ||\n checkpoint.stateHash !== policy.stateHash\n ) {\n throw new Error(\n \"Verified principal policy checkpoint was not persisted\",\n );\n }\n }\n };\n if (input.stillCurrent) {\n await runtime.guardedTransaction(persist, input.stillCurrent, {\n behavior: \"immediate\",\n });\n return;\n }\n await runtime.transaction(persist, { behavior: \"immediate\" });\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { KeyingVerificationError } from "../../internal/crypto/index.js";
|
|
1
|
+
import { KeyingVerificationError, } from "../../internal/crypto/index.js";
|
|
2
2
|
import { eq } from "drizzle-orm";
|
|
3
|
-
import { principalPolicyEvidenceEntries
|
|
3
|
+
import { principalPolicyEvidenceEntries } from "../principals/principalPolicyEvidence.js";
|
|
4
4
|
import { organizationFounders } from "../sqlite/organizationFounderSchema.js";
|
|
5
5
|
import { keyingCheckpointTables } from "../sqlite/schema.js";
|
|
6
6
|
import { getClientSQLitePersistenceRuntime } from "../sqlite/sqlitePersistenceRuntime.js";
|