@tearleads/client-sdk 0.1.19 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/organizations/index.js +2 -2
- package/client/organizations/index.js.map +1 -1
- package/client/organizations/organizationHistory.js +66 -0
- package/client/organizations/organizationHistory.js.map +1 -0
- package/client/organizations/organizationReadModels.d.ts +1 -1
- package/client/organizations/organizationReadModels.js +7 -27
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/client/organizations/organizationsTypes.d.ts +1 -1
- package/client/organizations/organizationsTypes.js.map +1 -1
- package/data/containers/shared/types.d.ts +2 -2
- package/data/containers/shared/types.js.map +1 -1
- package/data/documents/shared/syncSubmitFailure.d.ts +2 -2
- package/data/documents/shared/syncSubmitFailure.js.map +1 -1
- package/data/keyingProjectionVerification/documentPurgeCheckpointCurrency.js +34 -8
- package/data/keyingProjectionVerification/documentPurgeCheckpointCurrency.js.map +1 -1
- package/data/keyingProjectionVerification/documentPurgeDocumentChainVerification.js.map +1 -1
- package/data/keyingProjectionVerification/documentPurgePolicyCheckpoints.js +17 -0
- package/data/keyingProjectionVerification/documentPurgePolicyCheckpoints.js.map +1 -0
- package/data/keyingProjectionVerification/documentPurgePolicyCurrency.js +55 -0
- package/data/keyingProjectionVerification/documentPurgePolicyCurrency.js.map +1 -0
- package/data/keyingProjectionVerification/documentPurgePrincipalEvidence.js +25 -13
- package/data/keyingProjectionVerification/documentPurgePrincipalEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/documentPurgeProofVerification.d.ts +5 -3
- package/data/keyingProjectionVerification/documentPurgeProofVerification.js +52 -8
- package/data/keyingProjectionVerification/documentPurgeProofVerification.js.map +1 -1
- package/data/keyingProjectionVerification/projectionPolicyEvidence.js.map +1 -1
- package/data/keyingProjectionVerification/types.d.ts +4 -0
- package/data/keyingProjectionVerification/types.js.map +1 -1
- package/data/persistence/principalAuthorizationCheckpoints.js +1 -1
- package/data/persistence/principalAuthorizationCheckpoints.js.map +1 -1
- package/data/persistence/principalCurrentAcknowledgementPersistence.d.ts +1 -0
- package/data/persistence/principalCurrentAcknowledgementPersistence.js +58 -12
- package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -1
- package/data/persistence/principalHistoryEvidencePersistence.d.ts +2 -0
- package/data/persistence/principalHistoryEvidencePersistence.js +2 -0
- package/data/persistence/principalHistoryEvidencePersistence.js.map +1 -1
- package/data/persistence/principalHistoryIncompleteRetention.js +32 -0
- package/data/persistence/principalHistoryIncompleteRetention.js.map +1 -0
- package/data/persistence/principalHistoryNodeRetention.js +76 -0
- package/data/persistence/principalHistoryNodeRetention.js.map +1 -0
- package/data/persistence/principalHistoryPrefixPersistence.d.ts +1 -0
- package/data/persistence/principalHistoryPrefixPersistence.js +30 -1
- package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
- package/data/persistence/principalHistoryRootOwnership.js +71 -0
- package/data/persistence/principalHistoryRootOwnership.js.map +1 -0
- package/data/persistence/principalHistoryStagePersistence.js +45 -0
- package/data/persistence/principalHistoryStagePersistence.js.map +1 -1
- package/data/persistence/principalHistoryStageRetention.js +44 -0
- package/data/persistence/principalHistoryStageRetention.js.map +1 -0
- package/data/persistence/principalHistoryUnpublishedRetention.js +71 -0
- package/data/persistence/principalHistoryUnpublishedRetention.js.map +1 -0
- package/data/persistence/principalKeyEnvelopeArchivePersistence.js +63 -0
- package/data/persistence/principalKeyEnvelopeArchivePersistence.js.map +1 -0
- package/data/persistence/principalKeyEnvelopeCandidates.js +10 -1
- package/data/persistence/principalKeyEnvelopeCandidates.js.map +1 -1
- package/data/sqlite/principalHistoryEvidenceSchema.js +2 -0
- package/data/sqlite/principalHistoryEvidenceSchema.js.map +1 -1
- package/data/sqlite/principalHistoryNodeRetentionSchema.js +30 -0
- package/data/sqlite/principalHistoryNodeRetentionSchema.js.map +1 -0
- package/data/sqlite/principalHistoryRetentionSchema.js +40 -0
- package/data/sqlite/principalHistoryRetentionSchema.js.map +1 -0
- package/data/sqlite/principalHistoryStageSchema.js +2 -0
- package/data/sqlite/principalHistoryStageSchema.js.map +1 -1
- package/data/sqlite/schema.d.ts +453 -0
- package/data/sqlite/schema.js +6 -0
- package/data/sqlite/schema.js.map +1 -1
- package/data/sqlite/sqliteCommitGuards.js +49 -0
- package/data/sqlite/sqliteCommitGuards.js.map +1 -0
- package/data/sqlite/sqlitePersistenceRuntime.js +14 -2
- package/data/sqlite/sqlitePersistenceRuntime.js.map +1 -1
- package/index.d.ts +3 -1
- package/index.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +60 -137
- package/internal/api-client/ApiClient.js +7 -5
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/apiRequestRuntime.js +7 -7
- package/internal/api-client/apiRequestRuntime.js.map +1 -1
- package/internal/api-client/documentPurge.js +25 -0
- package/internal/api-client/documentPurge.js.map +1 -0
- package/internal/api-client/organizationPolicyHistory.d.ts +53 -0
- package/internal/api-client/organizationPolicyHistory.js +15 -0
- package/internal/api-client/organizationPolicyHistory.js.map +1 -0
- package/internal/api-client/requestInternals.js +4 -4
- package/internal/api-client/requestInternals.js.map +1 -1
- package/internal/api-client/types.d.ts +2 -2
- package/internal/api-client/types.js.map +1 -1
- 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/validators/operation/containerMutations.d.ts +448 -6528
- package/internal/validators/operation/documentMutations.d.ts +323 -579
- package/internal/validators/operation/documentMutations.js +22 -4
- package/internal/validators/operation/documentMutations.js.map +1 -1
- package/internal/validators/operation/documentSync.d.ts +26 -406
- package/internal/validators/operation/organizationPolicyHistory.d.ts +188 -310
- package/internal/validators/operation/organizationPolicyHistory.js +17 -3
- package/internal/validators/operation/organizationPolicyHistory.js.map +1 -1
- package/internal/validators/response/containerMutationError.d.ts +28 -408
- package/internal/validators/response/documentMutation.d.ts +232 -544
- package/internal/validators/response/documentMutation.js +1 -2
- package/internal/validators/response/documentMutation.js.map +1 -1
- package/internal/validators/response/documentSyncError.d.ts +26 -406
- package/internal/validators/response/documentSyncError.js +4 -3
- package/internal/validators/response/documentSyncError.js.map +1 -1
- package/internal/validators/response/index.d.ts +1 -1
- package/internal/validators/response/index.js +1 -1
- package/internal/validators/response/index.js.map +1 -1
- package/internal/validators/response/organizationPolicyHistory.d.ts +127 -309
- package/internal/validators/response/organizationPolicyHistory.js +10 -4
- package/internal/validators/response/organizationPolicyHistory.js.map +1 -1
- package/internal/validators/response/principal.d.ts +28 -408
- package/internal/validators/response/principal.js +3 -1
- package/internal/validators/response/principal.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/principalHistoryWire.d.ts +2 -0
- package/internal/validators/util/principalHistoryWire.js +2 -0
- package/internal/validators/util/principalHistoryWire.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/container-state/createWithMetadata.js +19 -49
- package/workflows/container-contents/container-state/createWithMetadata.js.map +1 -1
- package/workflows/container-contents/container-state/groupGrantVerification.js +29 -0
- package/workflows/container-contents/container-state/groupGrantVerification.js.map +1 -1
- package/workflows/container-contents/container-state/groupShareEpoch.js +33 -0
- package/workflows/container-contents/container-state/groupShareEpoch.js.map +1 -0
- package/workflows/container-contents/container-state/remote.js +4 -1
- package/workflows/container-contents/container-state/remote.js.map +1 -1
- package/workflows/container-contents/container-state/share.js +2 -24
- package/workflows/container-contents/container-state/share.js.map +1 -1
- package/workflows/container-contents/documentTombstoneEvidence.js +23 -12
- package/workflows/container-contents/documentTombstoneEvidence.js.map +1 -1
- package/workflows/containers/child/create.js +1 -3
- package/workflows/containers/child/create.js.map +1 -1
- package/workflows/containers/child/createSubmission.d.ts +1 -3
- package/workflows/containers/child/createSubmission.js +13 -15
- package/workflows/containers/child/createSubmission.js.map +1 -1
- package/workflows/containers/child/currentShareGrantMutation.js +82 -0
- package/workflows/containers/child/currentShareGrantMutation.js.map +1 -0
- package/workflows/containers/child/currentSharePrincipalPolicy.js +83 -0
- package/workflows/containers/child/currentSharePrincipalPolicy.js.map +1 -0
- package/workflows/containers/child/mutationSubmit.js +1 -1
- package/workflows/containers/child/mutationSubmit.js.map +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js +82 -0
- package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -0
- package/workflows/containers/child/share.js +1 -14
- package/workflows/containers/child/share.js.map +1 -1
- package/workflows/containers/child/shareProjection.js +15 -0
- package/workflows/containers/child/shareProjection.js.map +1 -0
- package/workflows/documents/purge.d.ts +3 -0
- package/workflows/documents/purge.js +13 -0
- package/workflows/documents/purge.js.map +1 -1
- package/workflows/documents/sync.js +2 -0
- package/workflows/documents/sync.js.map +1 -1
- package/workflows/documents/syncFailures.js +2 -2
- package/workflows/documents/syncFailures.js.map +1 -1
- package/workflows/documents/syncPolicyRepair.js +15 -13
- package/workflows/documents/syncPolicyRepair.js.map +1 -1
- package/workflows/organizations/initialPrincipalCurrentPublication.js +2 -0
- package/workflows/organizations/initialPrincipalCurrentPublication.js.map +1 -1
- package/workflows/organizations/loadPolicyHistoryDetails.js +31 -32
- package/workflows/organizations/loadPolicyHistoryDetails.js.map +1 -1
- package/workflows/organizations/organizationPolicyHistoryDetails.js +37 -15
- package/workflows/organizations/organizationPolicyHistoryDetails.js.map +1 -1
- package/workflows/organizations/organizationPolicyHistoryVerification.js +56 -69
- package/workflows/organizations/organizationPolicyHistoryVerification.js.map +1 -1
- package/workflows/organizations/policyHistoryCache.js +5 -2
- package/workflows/organizations/policyHistoryCache.js.map +1 -1
- package/workflows/organizations/policyHistoryTypes.d.ts +1 -0
- package/workflows/organizations/policyHistoryTypes.js.map +1 -1
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js +4 -1
- package/workflows/organizations/retainAcknowledgedPrincipalCurrents.js.map +1 -1
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.d.ts +0 -1
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.js +1 -2
- package/workflows/principals/loadRecoveredPrincipalHistoryPage.js.map +1 -1
- package/workflows/principals/policyRepair.js +38 -0
- package/workflows/principals/policyRepair.js.map +1 -0
- package/workflows/principals/policyRepairBudget.d.ts +2 -2
- package/workflows/principals/policyRepairBudget.js +3 -3
- package/workflows/principals/policyRepairBudget.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryPrefix.js +4 -0
- package/workflows/principals/principalHistoryRecoveryPrefix.js.map +1 -1
- package/workflows/principals/principalRecoveryLocalPreference.js +3 -2
- package/workflows/principals/principalRecoveryLocalPreference.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryPage.js +1 -0
- package/workflows/principals/publicPrincipalHistoryPage.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryProgress.js +1 -0
- package/workflows/principals/publicPrincipalHistoryProgress.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryTypes.d.ts +2 -0
- package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -1
- package/workflows/principals/publicProjectionPrincipal.js +1 -0
- package/workflows/principals/publicProjectionPrincipal.js.map +1 -1
- package/workflows/principals/recoverPrincipalHistoryPage.js +2 -1
- package/workflows/principals/recoverPrincipalHistoryPage.js.map +1 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js +1 -0
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/recoverPublicPrincipalHistory.js +2 -0
- package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js +2 -1
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/selectPublicPrincipalHistory.js +21 -15
- package/workflows/principals/selectPublicPrincipalHistory.js.map +1 -1
- package/workflows/sync/remoteResetPrincipalScope.js +6 -0
- package/workflows/sync/remoteResetPrincipalScope.js.map +1 -1
- package/data/keyingProjectionVerification/principalPolicySnapshotVerification.js +0 -208
- package/data/keyingProjectionVerification/principalPolicySnapshotVerification.js.map +0 -1
- package/data/keyingProjectionVerification/snapshotVerificationCache.js +0 -39
- package/data/keyingProjectionVerification/snapshotVerificationCache.js.map +0 -1
- package/workflows/containers/child/policyRepair.js +0 -23
- package/workflows/containers/child/policyRepair.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadPolicyHistoryDetails.js","sourceRoot":"","sources":["loadPolicyHistoryDetails.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loadPolicyHistoryDetails.js","sourceRoot":"","sources":["loadPolicyHistoryDetails.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport type { ReferencedPrincipalHead } from \"@tearleads/crypto\";\nimport type { DomainScope } from \"../../data/domainScope\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { reportKeyingVerificationErrorInCauseChain } from \"../../data/keyingProjectionVerification/error\";\nimport type { ReferencedPrincipalPolicyWarmer } from \"../../data/keyingProjectionVerification/types\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { RecoveredPrincipalHistoryPage } from \"../principals/loadRecoveredPrincipalHistoryPage\";\nimport { loadLocalOrganizationPolicyReference } from \"./localReadModelDetails\";\nimport { buildDetailedOrganizationPolicyHistory } from \"./organizationPolicyHistoryDetails\";\nimport {\n captureOrganizationPresentationAccessAttempt,\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n} from \"./organizationPresentationAccessState\";\nimport { isOrganizationPresentationAccessDeniedFailure } from \"./organizationPresentationFailures\";\nimport { denyPolicyHistoryAccess } from \"./policyHistoryAccessDenial\";\nimport {\n cachePolicyHistory,\n loadCachedPolicyHistory,\n} from \"./policyHistoryCache\";\nimport type { OrganizationPolicyHistory } from \"./policyHistoryTypes\";\n\nexport async function loadPolicyHistoryDetails(input: {\n apiClient: Pick<ApiClient, \"getOrganizationPolicyHistoryResult\">;\n currentUserId: string;\n domainScope: DomainScope;\n execSql: ExecSql;\n organizationId: string;\n head: ReferencedPrincipalHead;\n page: RecoveredPrincipalHistoryPage;\n history: OrganizationPolicyHistory;\n resolveHistory: NonNullable<\n ReferencedPrincipalPolicyWarmer[\"resolveProjectionHistory\"]\n >;\n stillCurrent: () => boolean;\n online: boolean;\n olderPage: boolean;\n reportSecurityIncident?: SecurityIncidentReporter | undefined;\n // Forwarded to denyPolicyHistoryAccess to report failed durable cleanup.\n logError: (message: string | Error, cause?: unknown) => void;\n}): Promise<OrganizationPolicyHistory | null> {\n const access = { ...input, requesterUserId: input.currentUserId };\n const attempt = captureOrganizationPresentationAccessAttempt(\n access,\n \"readModel\",\n );\n const current = () =>\n input.stillCurrent() &&\n isOrganizationPresentationAccessAttemptCurrent(access, attempt) &&\n isOrganizationPresentationAccessReadable(access, \"readModel\");\n if (!current()) return null;\n const beforeVersion = (input.page.entries.at(-1)?.state.version ?? 0) + 1;\n const cache = {\n domainScope: input.domainScope,\n access,\n stateHash: input.head.stateHash,\n beforeVersion,\n };\n const retain = async (history: OrganizationPolicyHistory) => {\n const latest = await loadLocalOrganizationPolicyReference({\n ...input,\n principalType: \"organization\",\n principalId: input.organizationId,\n });\n return current() && latest?.stateHash === input.head.stateHash\n ? history\n : null;\n };\n const cached = loadCachedPolicyHistory(cache);\n if (cached) return retain(cached);\n if (!input.online) return retain(input.history);\n try {\n const response = await input.apiClient.getOrganizationPolicyHistoryResult(\n input.organizationId,\n input.head.stateHash,\n { beforeVersion, reportErrors: false },\n );\n if (!input.stillCurrent()) return null;\n if (!response.ok) {\n if (isOrganizationPresentationAccessDeniedFailure(response)) {\n await denyPolicyHistoryAccess(access);\n return null;\n }\n response.report();\n if (input.olderPage) throw new Error(response.message);\n return retain(input.history);\n }\n const history = await buildDetailedOrganizationPolicyHistory({\n head: input.head,\n page: input.page,\n evidence: response.data,\n resolveHistory: input.resolveHistory,\n stillCurrent: current,\n });\n const retained = await retain(history);\n if (retained === history)\n cachePolicyHistory({ ...cache, attempt, history });\n return retained;\n } catch (error) {\n if (\n !input.olderPage &&\n error instanceof ProjectionDependencyUnavailableError\n )\n return retain(input.history);\n await reportKeyingVerificationErrorInCauseChain(\n error,\n input.reportSecurityIncident,\n {\n objectId: input.organizationId,\n objectKind: \"principal\",\n operation: \"organization.policy_history.load\",\n organizationId: input.organizationId,\n },\n );\n throw error;\n }\n}\n"]}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { principalPolicyMatchesReference, } from "../../internal/crypto/index.js";
|
|
2
|
+
import { assertProjectionVerificationCurrent, } from "../../data/keyingProjectionVerification/types.js";
|
|
3
|
+
import { buildOrganizationGroupPolicyHistoryPage } from "./groupPolicyHistoryPage.js";
|
|
1
4
|
import { verifyOrganizationPolicyHistory } from "./organizationPolicyHistoryVerification.js";
|
|
2
|
-
import {
|
|
5
|
+
import { diffPrincipalProjectionMembers, } from "./policyHistoryReadModel.js";
|
|
3
6
|
function diffGrants(previous, current) {
|
|
4
7
|
const before = new Map(previous.map((grant) => [grant.containerId, grant.accessLevel]));
|
|
5
8
|
const after = new Map(current.map((grant) => [grant.containerId, grant.accessLevel]));
|
|
@@ -52,34 +55,53 @@ function diffGroups(previousHeads, heads, groupState) {
|
|
|
52
55
|
}
|
|
53
56
|
return changes;
|
|
54
57
|
}
|
|
55
|
-
/**
|
|
58
|
+
/** Display only: historical group selections never advance current checkpoints. */
|
|
56
59
|
export async function buildDetailedOrganizationPolicyHistory(input) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
input.
|
|
61
|
-
|
|
60
|
+
input = {
|
|
61
|
+
...input,
|
|
62
|
+
head: structuredClone(input.head),
|
|
63
|
+
page: structuredClone(input.page),
|
|
64
|
+
evidence: structuredClone(input.evidence),
|
|
65
|
+
};
|
|
66
|
+
const { descriptors, references } = await verifyOrganizationPolicyHistory(input);
|
|
67
|
+
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
68
|
+
const resolved = await input.resolveHistory({
|
|
69
|
+
organizationId: input.head.principalId,
|
|
70
|
+
evidence: input.evidence.evidence,
|
|
71
|
+
references,
|
|
72
|
+
stillCurrent: input.stillCurrent,
|
|
73
|
+
});
|
|
74
|
+
assertProjectionVerificationCurrent(() => input.stillCurrent() && resolved.stillCurrent());
|
|
62
75
|
const groupState = (head) => {
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
?.history.find((entry) => entry.state.stateHash === head.stateHash);
|
|
76
|
+
const policy = resolved.policies.find((policy) => principalPolicyMatchesReference({ policy, reference: head }));
|
|
77
|
+
const entry = policy?.retainedHistory.find((entry) => entry.state.stateHash === head.stateHash);
|
|
66
78
|
if (!entry)
|
|
67
79
|
throw new Error("Verified group history state is missing");
|
|
68
80
|
return entry;
|
|
69
81
|
};
|
|
82
|
+
const basic = buildOrganizationGroupPolicyHistoryPage({
|
|
83
|
+
page: input.page,
|
|
84
|
+
groupId: input.head.principalId,
|
|
85
|
+
organizationId: input.head.principalId,
|
|
86
|
+
});
|
|
70
87
|
const byState = new Map();
|
|
71
|
-
let previousHeads =
|
|
72
|
-
|
|
88
|
+
let previousHeads = input.page.predecessor
|
|
89
|
+
? (descriptors.get(input.page.predecessor.state.stateHash)?.groupHeads ??
|
|
90
|
+
[])
|
|
91
|
+
: [];
|
|
92
|
+
for (const { state } of input.page.entries) {
|
|
73
93
|
const heads = descriptors.get(state.stateHash)?.groupHeads;
|
|
74
94
|
if (!heads)
|
|
75
95
|
throw new Error("Verified organization directory is missing");
|
|
76
96
|
byState.set(state.stateHash, diffGroups(previousHeads, heads, groupState));
|
|
77
97
|
previousHeads = heads;
|
|
78
98
|
}
|
|
79
|
-
const history = buildOrganizationPolicyHistory(input.bundle);
|
|
80
99
|
return {
|
|
81
|
-
|
|
82
|
-
|
|
100
|
+
principalId: input.head.principalId,
|
|
101
|
+
principalType: "organization",
|
|
102
|
+
organizationId: input.head.principalId,
|
|
103
|
+
nextBeforeVersion: input.page.nextBeforeVersion,
|
|
104
|
+
entries: basic.entries.map((entry) => ({
|
|
83
105
|
...entry,
|
|
84
106
|
groupChanges: byState.get(entry.stateHash) ?? [],
|
|
85
107
|
})),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationPolicyHistoryDetails.js","sourceRoot":"","sources":["organizationPolicyHistoryDetails.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PrincipalContainerGrant,\n PrincipalPolicyStateChainEntry,\n} from \"@tearleads/crypto\";\nimport type { OrganizationGroupHead } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { verifyOrganizationPolicyHistory } from \"./organizationPolicyHistoryVerification\";\nimport {\n buildOrganizationPolicyHistory,\n diffPrincipalProjectionMembers,\n type OrganizationPolicyHistory,\n} from \"./policyHistoryReadModel\";\nimport type {\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n} from \"./policyHistoryTypes\";\n\nfunction diffGrants(\n previous: readonly PrincipalContainerGrant[],\n current: readonly PrincipalContainerGrant[],\n): OrganizationPolicyGrantChange[] {\n const before = new Map(\n previous.map((grant) => [grant.containerId, grant.accessLevel]),\n );\n const after = new Map(\n current.map((grant) => [grant.containerId, grant.accessLevel]),\n );\n return [...new Set([...before.keys(), ...after.keys()])]\n .sort()\n .flatMap((containerId) => {\n const previousAccess = before.get(containerId) ?? null;\n const nextAccess = after.get(containerId) ?? null;\n return previousAccess === nextAccess\n ? []\n : [{ containerId, previousAccess, nextAccess }];\n });\n}\n\nfunction describeGroupChange(\n previous: OrganizationGroupHead | undefined,\n current: OrganizationGroupHead | undefined,\n groupState: (head: OrganizationGroupHead) => PrincipalPolicyStateChainEntry,\n): OrganizationPolicyGroupChange {\n const head = current ?? previous;\n if (!head) throw new Error(\"Group change has no state\");\n const oldEntry = previous ? groupState(previous) : null;\n const newEntry = current ? groupState(current) : null;\n return {\n groupId: head.principalId,\n changeType: !previous ? \"created\" : !current ? \"deleted\" : \"updated\",\n previousVersion: previous?.version ?? null,\n version: head.version,\n previousKeyEpoch: previous?.keyEpoch ?? null,\n keyEpoch: head.keyEpoch,\n changes: newEntry\n ? diffPrincipalProjectionMembers({\n previous: oldEntry?.projection ?? [],\n current: newEntry.projection,\n })\n : [],\n grantChanges: newEntry\n ? diffGrants(oldEntry?.grants ?? [], newEntry.grants)\n : [],\n };\n}\n\nfunction diffGroups(\n previousHeads: readonly OrganizationGroupHead[],\n heads: readonly OrganizationGroupHead[],\n groupState: (head: OrganizationGroupHead) => PrincipalPolicyStateChainEntry,\n): OrganizationPolicyGroupChange[] {\n const before = new Map(previousHeads.map((head) => [head.principalId, head]));\n const after = new Map(heads.map((head) => [head.principalId, head]));\n const changes: OrganizationPolicyGroupChange[] = [];\n for (const groupId of [\n ...new Set([...before.keys(), ...after.keys()]),\n ].sort()) {\n const previous = before.get(groupId);\n const current = after.get(groupId);\n if (previous?.stateHash === current?.stateHash) continue;\n changes.push(describeGroupChange(previous, current, groupState));\n }\n return changes;\n}\n\n/** Derived in memory; names remain in their existing encrypted sources. */\nexport async function buildDetailedOrganizationPolicyHistory(\n input: Parameters<typeof verifyOrganizationPolicyHistory>[0],\n): Promise<OrganizationPolicyHistory> {\n const { descriptors, groups } = await verifyOrganizationPolicyHistory(input);\n const states = [\n ...input.bundle.previousStates.map((entry) => entry.state),\n input.bundle.currentState,\n ].sort((a, b) => a.version - b.version);\n const groupState = (\n head: OrganizationGroupHead,\n ): PrincipalPolicyStateChainEntry => {\n const entry = groups\n .find((group) => group.principalId === head.principalId)\n ?.history.find((entry) => entry.state.stateHash === head.stateHash);\n if (!entry) throw new Error(\"Verified group history state is missing\");\n return entry;\n };\n const byState = new Map<string, OrganizationPolicyGroupChange[]>();\n let previousHeads: readonly OrganizationGroupHead[] = [];\n for (const state of states) {\n const heads = descriptors.get(state.stateHash)?.groupHeads;\n if (!heads) throw new Error(\"Verified organization directory is missing\");\n byState.set(state.stateHash, diffGroups(previousHeads, heads, groupState));\n previousHeads = heads;\n }\n const history = buildOrganizationPolicyHistory(input.bundle);\n return {\n ...history,\n entries: history.entries.map((entry) => ({\n ...entry,\n groupChanges: byState.get(entry.stateHash) ?? [],\n })),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"organizationPolicyHistoryDetails.js","sourceRoot":"","sources":["organizationPolicyHistoryDetails.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type PrincipalContainerGrant,\n type PrincipalPolicyStateChainEntry,\n principalPolicyMatchesReference,\n} from \"@tearleads/crypto\";\nimport {\n assertProjectionVerificationCurrent,\n type ReferencedPrincipalPolicyWarmer,\n} from \"../../data/keyingProjectionVerification/types\";\nimport type { OrganizationGroupHead } from \"../../data/principals/organizationAuthorityDescriptor\";\nimport { buildOrganizationGroupPolicyHistoryPage } from \"./groupPolicyHistoryPage\";\nimport { verifyOrganizationPolicyHistory } from \"./organizationPolicyHistoryVerification\";\nimport {\n diffPrincipalProjectionMembers,\n type OrganizationPolicyHistory,\n} from \"./policyHistoryReadModel\";\nimport type {\n OrganizationPolicyGrantChange,\n OrganizationPolicyGroupChange,\n} from \"./policyHistoryTypes\";\n\nfunction diffGrants(\n previous: readonly PrincipalContainerGrant[],\n current: readonly PrincipalContainerGrant[],\n): OrganizationPolicyGrantChange[] {\n const before = new Map(\n previous.map((grant) => [grant.containerId, grant.accessLevel]),\n );\n const after = new Map(\n current.map((grant) => [grant.containerId, grant.accessLevel]),\n );\n return [...new Set([...before.keys(), ...after.keys()])]\n .sort()\n .flatMap((containerId) => {\n const previousAccess = before.get(containerId) ?? null;\n const nextAccess = after.get(containerId) ?? null;\n return previousAccess === nextAccess\n ? []\n : [{ containerId, previousAccess, nextAccess }];\n });\n}\n\nfunction describeGroupChange(\n previous: OrganizationGroupHead | undefined,\n current: OrganizationGroupHead | undefined,\n groupState: (head: OrganizationGroupHead) => PrincipalPolicyStateChainEntry,\n): OrganizationPolicyGroupChange {\n const head = current ?? previous;\n if (!head) throw new Error(\"Group change has no state\");\n const oldEntry = previous ? groupState(previous) : null;\n const newEntry = current ? groupState(current) : null;\n return {\n groupId: head.principalId,\n changeType: !previous ? \"created\" : !current ? \"deleted\" : \"updated\",\n previousVersion: previous?.version ?? null,\n version: head.version,\n previousKeyEpoch: previous?.keyEpoch ?? null,\n keyEpoch: head.keyEpoch,\n changes: newEntry\n ? diffPrincipalProjectionMembers({\n previous: oldEntry?.projection ?? [],\n current: newEntry.projection,\n })\n : [],\n grantChanges: newEntry\n ? diffGrants(oldEntry?.grants ?? [], newEntry.grants)\n : [],\n };\n}\n\nfunction diffGroups(\n previousHeads: readonly OrganizationGroupHead[],\n heads: readonly OrganizationGroupHead[],\n groupState: (head: OrganizationGroupHead) => PrincipalPolicyStateChainEntry,\n): OrganizationPolicyGroupChange[] {\n const before = new Map(previousHeads.map((head) => [head.principalId, head]));\n const after = new Map(heads.map((head) => [head.principalId, head]));\n const changes: OrganizationPolicyGroupChange[] = [];\n for (const groupId of [\n ...new Set([...before.keys(), ...after.keys()]),\n ].sort()) {\n const previous = before.get(groupId);\n const current = after.get(groupId);\n if (previous?.stateHash === current?.stateHash) continue;\n changes.push(describeGroupChange(previous, current, groupState));\n }\n return changes;\n}\n\n/** Display only: historical group selections never advance current checkpoints. */\nexport async function buildDetailedOrganizationPolicyHistory(\n input: Parameters<typeof verifyOrganizationPolicyHistory>[0] & {\n readonly resolveHistory: NonNullable<\n ReferencedPrincipalPolicyWarmer[\"resolveProjectionHistory\"]\n >;\n readonly stillCurrent: () => boolean;\n },\n): Promise<OrganizationPolicyHistory> {\n input = {\n ...input,\n head: structuredClone(input.head),\n page: structuredClone(input.page),\n evidence: structuredClone(input.evidence),\n };\n const { descriptors, references } =\n await verifyOrganizationPolicyHistory(input);\n assertProjectionVerificationCurrent(input.stillCurrent);\n const resolved = await input.resolveHistory({\n organizationId: input.head.principalId,\n evidence: input.evidence.evidence,\n references,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(\n () => input.stillCurrent() && resolved.stillCurrent(),\n );\n const groupState = (\n head: OrganizationGroupHead,\n ): PrincipalPolicyStateChainEntry => {\n const policy = resolved.policies.find((policy) =>\n principalPolicyMatchesReference({ policy, reference: head }),\n );\n const entry = policy?.retainedHistory.find(\n (entry) => entry.state.stateHash === head.stateHash,\n );\n if (!entry) throw new Error(\"Verified group history state is missing\");\n return entry;\n };\n const basic = buildOrganizationGroupPolicyHistoryPage({\n page: input.page,\n groupId: input.head.principalId,\n organizationId: input.head.principalId,\n });\n const byState = new Map<string, OrganizationPolicyGroupChange[]>();\n let previousHeads: readonly OrganizationGroupHead[] = input.page.predecessor\n ? (descriptors.get(input.page.predecessor.state.stateHash)?.groupHeads ??\n [])\n : [];\n for (const { state } of input.page.entries) {\n const heads = descriptors.get(state.stateHash)?.groupHeads;\n if (!heads) throw new Error(\"Verified organization directory is missing\");\n byState.set(state.stateHash, diffGroups(previousHeads, heads, groupState));\n previousHeads = heads;\n }\n return {\n principalId: input.head.principalId,\n principalType: \"organization\",\n organizationId: input.head.principalId,\n nextBeforeVersion: input.page.nextBeforeVersion,\n entries: basic.entries.map((entry) => ({\n ...entry,\n groupChanges: byState.get(entry.stateHash) ?? [],\n })),\n };\n}\n"]}
|
|
@@ -1,80 +1,67 @@
|
|
|
1
|
-
import { computePrincipalStatePayloadCiphertextHash, KeyingVerificationError,
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { verifyOrganizationAdminPolicy } from "../../data/principals/principalPolicyAdminSigners.js";
|
|
6
|
-
import { collectPrincipalPolicySignerPublicKeys } from "../principals/policyVerification.js";
|
|
7
|
-
function reject(message, code = "hash_mismatch") {
|
|
8
|
-
throw new KeyingVerificationError(code, `Organization policy history: ${message}`);
|
|
1
|
+
import { computePrincipalStatePayloadCiphertextHash, KeyingVerificationError, } from "../../internal/crypto/index.js";
|
|
2
|
+
import { parseOrganizationAuthorityDescriptor, principalHeadMatchesReference, } from "../../data/principals/organizationAuthorityDescriptor.js";
|
|
3
|
+
function reject(message) {
|
|
4
|
+
throw new KeyingVerificationError("hash_mismatch", `Organization policy history: ${message}`);
|
|
9
5
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
/** Bind every display payload and public source to the privately verified page. */
|
|
7
|
+
export async function verifyOrganizationPolicyHistory(input) {
|
|
8
|
+
const { head, page, evidence } = input;
|
|
9
|
+
const beforeVersion = (page.entries.at(-1)?.state.version ?? 0) + 1;
|
|
10
|
+
if (head.principalType !== "organization" ||
|
|
11
|
+
evidence.organizationId !== head.principalId ||
|
|
12
|
+
evidence.stateHash !== head.stateHash ||
|
|
13
|
+
evidence.beforeVersion !== beforeVersion ||
|
|
14
|
+
evidence.nextBeforeVersion !== page.nextBeforeVersion ||
|
|
15
|
+
!evidence.evidence.organization ||
|
|
16
|
+
!principalHeadMatchesReference(evidence.evidence.organization.head, head))
|
|
17
|
+
reject("response does not match the requested organization page");
|
|
18
|
+
const entries = page.predecessor
|
|
19
|
+
? [page.predecessor, ...page.entries]
|
|
20
|
+
: page.entries;
|
|
21
|
+
if (evidence.evidence.organizationPayloads.length !== entries.length)
|
|
22
|
+
reject("directory page is incomplete");
|
|
17
23
|
const descriptors = new Map();
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
const references = [head];
|
|
25
|
+
const groups = new Map();
|
|
26
|
+
for (const [index, item,] of evidence.evidence.organizationPayloads.entries()) {
|
|
27
|
+
const { reference, payload } = item;
|
|
28
|
+
const entry = entries[index];
|
|
29
|
+
if (!entry ||
|
|
30
|
+
!principalHeadMatchesReference(entry.state, reference) ||
|
|
22
31
|
payload.principalType !== "organization" ||
|
|
23
|
-
payload.principalId !==
|
|
24
|
-
|
|
32
|
+
payload.principalId !== head.principalId ||
|
|
33
|
+
payload.stateHash !== reference.stateHash ||
|
|
34
|
+
descriptors.has(reference.stateHash))
|
|
35
|
+
reject("directory payload scope or order is invalid");
|
|
25
36
|
const hash = await computePrincipalStatePayloadCiphertextHash(payload.ciphertext);
|
|
26
|
-
if (hash !== state.payloadCiphertextHash ||
|
|
37
|
+
if (hash !== entry.state.payloadCiphertextHash ||
|
|
38
|
+
hash !== payload.ciphertextHash)
|
|
27
39
|
reject("directory payload does not match its signed hash");
|
|
28
40
|
const descriptor = parseOrganizationAuthorityDescriptor(payload.ciphertext);
|
|
29
|
-
if (descriptor.organizationId !==
|
|
30
|
-
reject("directory belongs to another organization"
|
|
31
|
-
descriptors.set(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const { bundle, evidence, organizationId } = input;
|
|
38
|
-
if (evidence.organizationId !== organizationId ||
|
|
39
|
-
evidence.stateHash !== bundle.currentState.stateHash)
|
|
40
|
-
reject("response does not match the requested organization head", "object_mismatch");
|
|
41
|
-
const keys = await collectPrincipalPolicySignerPublicKeys(input);
|
|
42
|
-
if ("error" in keys) {
|
|
43
|
-
if (keys.error === "not-found")
|
|
44
|
-
throw new ProjectionDependencyUnavailableError("Organization policy history signer identity is unavailable");
|
|
45
|
-
reject("signer fingerprint does not match", "signer_mismatch");
|
|
46
|
-
}
|
|
47
|
-
const verified = await verifyOrganizationAdminPolicy({
|
|
48
|
-
...input,
|
|
49
|
-
signerPublicKeys: keys.signerPublicKeys,
|
|
50
|
-
});
|
|
51
|
-
if (!verified.ok)
|
|
52
|
-
throw verified.error;
|
|
53
|
-
const descriptors = await verifyDirectoryPayloads(bundle, evidence, organizationId);
|
|
54
|
-
// These are historical display proofs, authenticated by the selected
|
|
55
|
-
// organization chain. They never advance a group's current-policy checkpoint.
|
|
56
|
-
const groups = await verifyPrincipalPolicySnapshots({
|
|
57
|
-
resolveUserKey: input.resolveTrustedUserIdentity,
|
|
58
|
-
snapshots: evidence.groups,
|
|
59
|
-
});
|
|
60
|
-
const expectedGroups = new Set();
|
|
61
|
-
for (const descriptor of descriptors.values()) {
|
|
62
|
-
for (const reference of descriptor.groupHeads) {
|
|
63
|
-
expectedGroups.add(reference.principalId);
|
|
64
|
-
const policy = groups.find((group) => group.principalType === "group" &&
|
|
65
|
-
group.principalId === reference.principalId);
|
|
66
|
-
if (!policy || !principalPolicyMatchesReference({ policy, reference }))
|
|
67
|
-
reject("group history does not match the signed directory");
|
|
41
|
+
if (descriptor.organizationId !== head.principalId)
|
|
42
|
+
reject("directory belongs to another organization");
|
|
43
|
+
descriptors.set(reference.stateHash, descriptor);
|
|
44
|
+
references.push(reference, ...descriptor.groupHeads);
|
|
45
|
+
for (const group of descriptor.groupHeads) {
|
|
46
|
+
const previous = groups.get(group.principalId);
|
|
47
|
+
if (!previous || group.version > previous.version)
|
|
48
|
+
groups.set(group.principalId, group);
|
|
68
49
|
}
|
|
69
50
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
51
|
+
verifyGroupSources(evidence, groups);
|
|
52
|
+
return { descriptors, references };
|
|
53
|
+
}
|
|
54
|
+
function verifyGroupSources(evidence, groups) {
|
|
55
|
+
if (evidence.evidence.groups.length !== groups.size)
|
|
56
|
+
reject("unexpected group source");
|
|
57
|
+
const seen = new Set();
|
|
58
|
+
for (const source of evidence.evidence.groups) {
|
|
59
|
+
const expected = groups.get(source.head.principalId);
|
|
60
|
+
if (!expected ||
|
|
61
|
+
seen.has(source.head.principalId) ||
|
|
62
|
+
!principalHeadMatchesReference(source.head, expected))
|
|
63
|
+
reject("group source extends beyond the page's signed directory");
|
|
64
|
+
seen.add(source.head.principalId);
|
|
77
65
|
}
|
|
78
|
-
return { descriptors, groups };
|
|
79
66
|
}
|
|
80
67
|
//# sourceMappingURL=organizationPolicyHistoryVerification.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationPolicyHistoryVerification.js","sourceRoot":"","sources":["organizationPolicyHistoryVerification.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0CAA0C,
|
|
1
|
+
{"version":3,"file":"organizationPolicyHistoryVerification.js","sourceRoot":"","sources":["organizationPolicyHistoryVerification.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n computePrincipalStatePayloadCiphertextHash,\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport type { OrganizationPolicyHistoryResponse } from \"@tearleads/validators/response\";\nimport {\n type OrganizationAuthorityDescriptor,\n parseOrganizationAuthorityDescriptor,\n principalHeadMatchesReference,\n} from \"../../data/principals/organizationAuthorityDescriptor\";\nimport type { RecoveredPrincipalHistoryPage } from \"../principals/loadRecoveredPrincipalHistoryPage\";\n\nfunction reject(message: string): never {\n throw new KeyingVerificationError(\n \"hash_mismatch\",\n `Organization policy history: ${message}`,\n );\n}\n\n/** Bind every display payload and public source to the privately verified page. */\nexport async function verifyOrganizationPolicyHistory(input: {\n readonly head: ReferencedPrincipalHead;\n readonly page: RecoveredPrincipalHistoryPage;\n readonly evidence: OrganizationPolicyHistoryResponse;\n}) {\n const { head, page, evidence } = input;\n const beforeVersion = (page.entries.at(-1)?.state.version ?? 0) + 1;\n if (\n head.principalType !== \"organization\" ||\n evidence.organizationId !== head.principalId ||\n evidence.stateHash !== head.stateHash ||\n evidence.beforeVersion !== beforeVersion ||\n evidence.nextBeforeVersion !== page.nextBeforeVersion ||\n !evidence.evidence.organization ||\n !principalHeadMatchesReference(evidence.evidence.organization.head, head)\n )\n reject(\"response does not match the requested organization page\");\n const entries = page.predecessor\n ? [page.predecessor, ...page.entries]\n : page.entries;\n if (evidence.evidence.organizationPayloads.length !== entries.length)\n reject(\"directory page is incomplete\");\n const descriptors = new Map<string, OrganizationAuthorityDescriptor>();\n const references: ReferencedPrincipalHead[] = [head];\n const groups = new Map<string, ReferencedPrincipalHead>();\n for (const [\n index,\n item,\n ] of evidence.evidence.organizationPayloads.entries()) {\n const { reference, payload } = item;\n const entry = entries[index];\n if (\n !entry ||\n !principalHeadMatchesReference(entry.state, reference) ||\n payload.principalType !== \"organization\" ||\n payload.principalId !== head.principalId ||\n payload.stateHash !== reference.stateHash ||\n descriptors.has(reference.stateHash)\n )\n reject(\"directory payload scope or order is invalid\");\n const hash = await computePrincipalStatePayloadCiphertextHash(\n payload.ciphertext,\n );\n if (\n hash !== entry.state.payloadCiphertextHash ||\n hash !== payload.ciphertextHash\n )\n reject(\"directory payload does not match its signed hash\");\n const descriptor = parseOrganizationAuthorityDescriptor(payload.ciphertext);\n if (descriptor.organizationId !== head.principalId)\n reject(\"directory belongs to another organization\");\n descriptors.set(reference.stateHash, descriptor);\n references.push(reference, ...descriptor.groupHeads);\n for (const group of descriptor.groupHeads) {\n const previous = groups.get(group.principalId);\n if (!previous || group.version > previous.version)\n groups.set(group.principalId, group);\n }\n }\n verifyGroupSources(evidence, groups);\n return { descriptors, references };\n}\n\nfunction verifyGroupSources(\n evidence: OrganizationPolicyHistoryResponse,\n groups: Map<string, ReferencedPrincipalHead>,\n) {\n if (evidence.evidence.groups.length !== groups.size)\n reject(\"unexpected group source\");\n const seen = new Set<string>();\n for (const source of evidence.evidence.groups) {\n const expected = groups.get(source.head.principalId);\n if (\n !expected ||\n seen.has(source.head.principalId) ||\n !principalHeadMatchesReference(source.head, expected)\n )\n reject(\"group source extends beyond the page's signed directory\");\n seen.add(source.head.principalId);\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isOrganizationPresentationAccessAttemptCurrent, isOrganizationPresentationAccessReadable, organizationAccessScopeKey, } from "./organizationPresentationAccessState.js";
|
|
2
|
-
// Only
|
|
2
|
+
// Only one verified page per account/org is retained. Names and wire
|
|
3
3
|
// evidence never enter this cache, and nothing here is written to a database.
|
|
4
4
|
const histories = new WeakMap();
|
|
5
5
|
export function loadCachedPolicyHistory(input) {
|
|
@@ -9,7 +9,8 @@ export function loadCachedPolicyHistory(input) {
|
|
|
9
9
|
if (!cached)
|
|
10
10
|
return null;
|
|
11
11
|
if (cached.access.execSql !== input.access.execSql ||
|
|
12
|
-
cached.
|
|
12
|
+
cached.stateHash !== input.stateHash ||
|
|
13
|
+
cached.beforeVersion !== input.beforeVersion ||
|
|
13
14
|
!isOrganizationPresentationAccessAttemptCurrent(input.access, cached.attempt) ||
|
|
14
15
|
!isOrganizationPresentationAccessReadable(input.access, "readModel")) {
|
|
15
16
|
byKey?.delete(key);
|
|
@@ -34,6 +35,8 @@ export function cachePolicyHistory(input) {
|
|
|
34
35
|
},
|
|
35
36
|
attempt: input.attempt,
|
|
36
37
|
history: structuredClone(input.history),
|
|
38
|
+
stateHash: input.stateHash,
|
|
39
|
+
beforeVersion: input.beforeVersion,
|
|
37
40
|
});
|
|
38
41
|
}
|
|
39
42
|
//# sourceMappingURL=policyHistoryCache.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policyHistoryCache.js","sourceRoot":"","sources":["policyHistoryCache.ts"],"names":[],"mappings":"AACA,OAAO,EACL,8CAA8C,EAC9C,wCAAwC,EAGxC,0BAA0B,GAC3B,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"policyHistoryCache.js","sourceRoot":"","sources":["policyHistoryCache.ts"],"names":[],"mappings":"AACA,OAAO,EACL,8CAA8C,EAC9C,wCAAwC,EAGxC,0BAA0B,GAC3B,MAAM,uCAAuC,CAAC;AAW/C,qEAAqE;AACrE,8EAA8E;AAC9E,MAAM,SAAS,GAAG,IAAI,OAAO,EAA2C,CAAC;AAEzE,MAAM,UAAU,uBAAuB,CAAC,KAKvC;IACC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,0BAA0B,CACpC,KAAK,CAAC,MAAM,CAAC,cAAc,EAC3B,KAAK,CAAC,MAAM,CAAC,eAAe,CAC7B,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IACE,MAAM,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,CAAC,OAAO;QAC9C,MAAM,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QACpC,MAAM,CAAC,aAAa,KAAK,KAAK,CAAC,aAAa;QAC5C,CAAC,8CAA8C,CAC7C,KAAK,CAAC,MAAM,EACZ,MAAM,CAAC,OAAO,CACf;QACD,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,EACpE,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAOlC;IACC,IACE,CAAC,8CAA8C,CAC7C,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,OAAO,CACd;QACD,CAAC,wCAAwC,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;QAEpE,OAAO;IACT,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,GAAG,CACP,0BAA0B,CACxB,KAAK,CAAC,MAAM,CAAC,cAAc,EAC3B,KAAK,CAAC,MAAM,CAAC,eAAe,CAC7B,EACD;QACE,MAAM,EAAE;YACN,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;YAC7B,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,cAAc;YAC3C,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe;SAC9C;QACD,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;QACvC,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa,EAAE,KAAK,CAAC,aAAa;KACnC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DomainScope } from \"../../data/domainScope\";\nimport {\n isOrganizationPresentationAccessAttemptCurrent,\n isOrganizationPresentationAccessReadable,\n type OrganizationPresentationAccessAttempt,\n type OrganizationPresentationAccessInput,\n organizationAccessScopeKey,\n} from \"./organizationPresentationAccessState\";\nimport type { OrganizationPolicyHistory } from \"./policyHistoryTypes\";\n\ninterface CachedHistory {\n readonly access: OrganizationPresentationAccessInput;\n readonly attempt: OrganizationPresentationAccessAttempt;\n readonly history: OrganizationPolicyHistory;\n readonly stateHash: string;\n readonly beforeVersion: number;\n}\n\n// Only one verified page per account/org is retained. Names and wire\n// evidence never enter this cache, and nothing here is written to a database.\nconst histories = new WeakMap<DomainScope, Map<string, CachedHistory>>();\n\nexport function loadCachedPolicyHistory(input: {\n domainScope: DomainScope;\n access: OrganizationPresentationAccessInput;\n stateHash: string;\n beforeVersion: number;\n}): OrganizationPolicyHistory | null {\n const byKey = histories.get(input.domainScope);\n const key = organizationAccessScopeKey(\n input.access.organizationId,\n input.access.requesterUserId,\n );\n const cached = byKey?.get(key);\n if (!cached) return null;\n if (\n cached.access.execSql !== input.access.execSql ||\n cached.stateHash !== input.stateHash ||\n cached.beforeVersion !== input.beforeVersion ||\n !isOrganizationPresentationAccessAttemptCurrent(\n input.access,\n cached.attempt,\n ) ||\n !isOrganizationPresentationAccessReadable(input.access, \"readModel\")\n ) {\n byKey?.delete(key);\n return null;\n }\n return structuredClone(cached.history);\n}\n\nexport function cachePolicyHistory(input: {\n domainScope: DomainScope;\n access: OrganizationPresentationAccessInput;\n attempt: OrganizationPresentationAccessAttempt;\n history: OrganizationPolicyHistory;\n stateHash: string;\n beforeVersion: number;\n}): void {\n if (\n !isOrganizationPresentationAccessAttemptCurrent(\n input.access,\n input.attempt,\n ) ||\n !isOrganizationPresentationAccessReadable(input.access, \"readModel\")\n )\n return;\n let byKey = histories.get(input.domainScope);\n if (!byKey) {\n byKey = new Map();\n histories.set(input.domainScope, byKey);\n }\n byKey.set(\n organizationAccessScopeKey(\n input.access.organizationId,\n input.access.requesterUserId,\n ),\n {\n access: {\n execSql: input.access.execSql,\n organizationId: input.access.organizationId,\n requesterUserId: input.access.requesterUserId,\n },\n attempt: input.attempt,\n history: structuredClone(input.history),\n stateHash: input.stateHash,\n beforeVersion: input.beforeVersion,\n },\n );\n}\n"]}
|
|
@@ -31,6 +31,7 @@ export interface OrganizationGroupPolicyHistory extends OrganizationPrincipalPol
|
|
|
31
31
|
readonly principalType: "group";
|
|
32
32
|
}
|
|
33
33
|
export interface OrganizationPolicyHistory extends OrganizationPrincipalPolicyHistory {
|
|
34
|
+
readonly nextBeforeVersion?: number | null;
|
|
34
35
|
readonly entries: OrganizationPolicyHistoryEntry[];
|
|
35
36
|
readonly organizationId: string;
|
|
36
37
|
readonly principalType: "organization";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policyHistoryTypes.js","sourceRoot":"","sources":["policyHistoryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n PrincipalContainerGrantResponse,\n PrincipalProjectionMemberResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\n\nexport type OrganizationPrincipalMemberChangeType =\n | \"added\"\n | \"removed\"\n | \"role_changed\";\nexport interface OrganizationPrincipalMemberChange {\n readonly changeType: OrganizationPrincipalMemberChangeType;\n readonly userId: string;\n readonly nextRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n readonly previousRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n}\nexport interface OrganizationPrincipalPolicyHistoryEntry {\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly createdAt: string;\n readonly keyEpoch: number;\n readonly memberCount: number;\n readonly signedAt: string;\n readonly signerUserId: string;\n readonly signerUserKeyFingerprint: string;\n readonly stateHash: string;\n readonly version: number;\n}\nexport type OrganizationGroupPolicyHistoryEntry =\n OrganizationPrincipalPolicyHistoryEntry;\nexport interface OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPrincipalPolicyHistoryEntry[];\n readonly principalId: string;\n readonly principalType: PrincipalStateResponse[\"principalType\"];\n}\nexport interface OrganizationGroupPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n /** Exclusive cursor for older entries; absent on a legacy complete history. */\n readonly nextBeforeVersion?: number | null;\n readonly groupId: string;\n readonly organizationId: string;\n readonly principalType: \"group\";\n}\nexport interface OrganizationPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPolicyHistoryEntry[];\n readonly organizationId: string;\n readonly principalType: \"organization\";\n}\n\nexport interface OrganizationPolicyHistoryEntry\n extends OrganizationPrincipalPolicyHistoryEntry {\n /** Null when the additional signed evidence has not been loaded. */\n readonly groupChanges: OrganizationPolicyGroupChange[] | null;\n}\n\nexport interface OrganizationPolicyGrantChange {\n readonly containerId: string;\n readonly previousAccess:\n | PrincipalContainerGrantResponse[\"accessLevel\"]\n | null;\n readonly nextAccess: PrincipalContainerGrantResponse[\"accessLevel\"] | null;\n}\n\nexport interface OrganizationPolicyGroupChange {\n readonly groupId: string;\n readonly changeType: \"created\" | \"updated\" | \"deleted\";\n readonly previousVersion: number | null;\n readonly version: number;\n readonly previousKeyEpoch: number | null;\n readonly keyEpoch: number;\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly grantChanges: OrganizationPolicyGrantChange[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"policyHistoryTypes.js","sourceRoot":"","sources":["policyHistoryTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n PrincipalContainerGrantResponse,\n PrincipalProjectionMemberResponse,\n PrincipalStateResponse,\n} from \"@tearleads/validators/response\";\n\nexport type OrganizationPrincipalMemberChangeType =\n | \"added\"\n | \"removed\"\n | \"role_changed\";\nexport interface OrganizationPrincipalMemberChange {\n readonly changeType: OrganizationPrincipalMemberChangeType;\n readonly userId: string;\n readonly nextRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n readonly previousRole: PrincipalProjectionMemberResponse[\"role\"] | null;\n}\nexport interface OrganizationPrincipalPolicyHistoryEntry {\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly createdAt: string;\n readonly keyEpoch: number;\n readonly memberCount: number;\n readonly signedAt: string;\n readonly signerUserId: string;\n readonly signerUserKeyFingerprint: string;\n readonly stateHash: string;\n readonly version: number;\n}\nexport type OrganizationGroupPolicyHistoryEntry =\n OrganizationPrincipalPolicyHistoryEntry;\nexport interface OrganizationPrincipalPolicyHistory {\n readonly entries: OrganizationPrincipalPolicyHistoryEntry[];\n readonly principalId: string;\n readonly principalType: PrincipalStateResponse[\"principalType\"];\n}\nexport interface OrganizationGroupPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n /** Exclusive cursor for older entries; absent on a legacy complete history. */\n readonly nextBeforeVersion?: number | null;\n readonly groupId: string;\n readonly organizationId: string;\n readonly principalType: \"group\";\n}\nexport interface OrganizationPolicyHistory\n extends OrganizationPrincipalPolicyHistory {\n readonly nextBeforeVersion?: number | null;\n readonly entries: OrganizationPolicyHistoryEntry[];\n readonly organizationId: string;\n readonly principalType: \"organization\";\n}\n\nexport interface OrganizationPolicyHistoryEntry\n extends OrganizationPrincipalPolicyHistoryEntry {\n /** Null when the additional signed evidence has not been loaded. */\n readonly groupChanges: OrganizationPolicyGroupChange[] | null;\n}\n\nexport interface OrganizationPolicyGrantChange {\n readonly containerId: string;\n readonly previousAccess:\n | PrincipalContainerGrantResponse[\"accessLevel\"]\n | null;\n readonly nextAccess: PrincipalContainerGrantResponse[\"accessLevel\"] | null;\n}\n\nexport interface OrganizationPolicyGroupChange {\n readonly groupId: string;\n readonly changeType: \"created\" | \"updated\" | \"deleted\";\n readonly previousVersion: number | null;\n readonly version: number;\n readonly previousKeyEpoch: number | null;\n readonly keyEpoch: number;\n readonly changes: OrganizationPrincipalMemberChange[];\n readonly grantChanges: OrganizationPolicyGrantChange[];\n}\n"]}
|
|
@@ -50,6 +50,7 @@ async function restorePredecessor(options) {
|
|
|
50
50
|
artifacts,
|
|
51
51
|
verifier: restored.value,
|
|
52
52
|
previous: previous.value,
|
|
53
|
+
predecessorIndexRootHash: history.value.indexRootHash,
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
async function preparePublication(options, request, response) {
|
|
@@ -62,7 +63,7 @@ async function preparePublication(options, request, response) {
|
|
|
62
63
|
};
|
|
63
64
|
const current = () => !options.signal?.aborted && options.stillCurrent();
|
|
64
65
|
assertProjectionVerificationCurrent(current);
|
|
65
|
-
const { scopeId, saved, artifacts, verifier, previous } = await restorePredecessor(options);
|
|
66
|
+
const { scopeId, saved, artifacts, verifier, previous, predecessorIndexRootHash, } = await restorePredecessor(options);
|
|
66
67
|
const expectedHead = await groupPolicyMutationHead(request);
|
|
67
68
|
assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });
|
|
68
69
|
const keys = await collectPrincipalPolicySignerPublicKeys({
|
|
@@ -103,8 +104,10 @@ async function preparePublication(options, request, response) {
|
|
|
103
104
|
policy,
|
|
104
105
|
previousPrefixProgress: saved.progress,
|
|
105
106
|
predecessorStage,
|
|
107
|
+
predecessorIndexRootHash,
|
|
106
108
|
...sealed,
|
|
107
109
|
evidence: await preparePrincipalHistoryEvidencePage({
|
|
110
|
+
indexRootHash: appended.value.indexRootHash,
|
|
108
111
|
scopeId,
|
|
109
112
|
organizationId: options.organizationId,
|
|
110
113
|
entries: [entry],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retainAcknowledgedPrincipalCurrents.js","sourceRoot":"","sources":["retainAcknowledgedPrincipalCurrents.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n restorePrincipalPolicyHistoryVerifier,\n type VerifiedPrincipalPolicyCurrent,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n type AcknowledgedPrincipalCurrentPublication,\n type AcknowledgedPrincipalCurrentRetirement,\n persistAcknowledgedPrincipalCurrents,\n} from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { preparePrincipalHistoryEvidencePage } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport { loadPrincipalHistoryPrefix } from \"../../data/persistence/principalHistoryPrefixPersistence\";\nimport {\n principalHistoryEvidenceScopeId,\n principalHistoryPrefixProtection,\n} from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { ownPrincipalHistoryProtection } from \"../../data/principals/principalHistoryProtection\";\nimport { parsePrincipalHistoryStageCurrent } from \"../../data/principals/principalHistoryStageProtection\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"../principals/policyVerification\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport {\n assertPrincipalHistoryVerificationMode,\n principalHistoryVerificationContext,\n} from \"../principals/principalHistoryRecoveryVerification\";\nimport { assertAcknowledgedDirectoryBindings } from \"./acknowledgedDirectoryBindings\";\nimport { acknowledgeGroupPolicyState } from \"./groupPolicyMutationAcknowledgement\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { prepareInitialGroupCurrentPublication } from \"./initialPrincipalCurrentPublication\";\nimport {\n sealPrincipalCurrentPublication,\n sealPrincipalCurrentStage,\n} from \"./principalCurrentPublicationSeal\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\nexport type { AcknowledgedPrincipalCurrentRetirement } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\n\nexport interface AcknowledgedPrincipalCurrentInput {\n /** Only a newly authored group at version one; never skips a predecessor. */\n readonly initialGroup?: boolean | undefined;\n /** The same scoped protection and verification mode used to recover the predecessor. */\n readonly recovery: Omit<\n RecoverPrincipalPolicyHistoryOptions,\n \"execSql\" | \"organizationId\" | \"stillCurrent\"\n >;\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n}\n\nasync function restorePredecessor(\n options: RecoverPrincipalPolicyHistoryOptions,\n) {\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: options.organizationId,\n head: options.expectedHead,\n protection: options.protection,\n });\n const saved = await loadPrincipalHistoryPrefix(options.execSql, scopeId);\n if (!saved || saved.organizationId !== options.organizationId)\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Acknowledgement requires its authenticated predecessor prefix\",\n );\n const restored = await restorePrincipalPolicyHistoryVerifier(\n {\n principalId: options.expectedHead.principalId,\n principalType: options.expectedHead.principalType,\n },\n saved.progress,\n await principalHistoryPrefixProtection(options.protection, saved),\n );\n if (!restored.ok) throw restored.error;\n const history = restored.value.finish(options.expectedHead);\n if (!history.ok) throw history.error;\n const artifacts = parsePrincipalHistoryStageCurrent({\n currentJson: saved.currentJson,\n afterVersion: saved.version - 1,\n });\n if (!artifacts)\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Acknowledged predecessor artifacts are malformed\",\n );\n const previous = await verifyPrincipalPolicyCurrent({\n current: artifacts,\n history: history.value,\n });\n if (!previous.ok) throw previous.error;\n return {\n scopeId,\n saved,\n artifacts,\n verifier: restored.value,\n previous: previous.value,\n };\n}\n\nasync function preparePublication(\n options: RecoverPrincipalPolicyHistoryOptions,\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n): Promise<AcknowledgedPrincipalCurrentPublication> {\n options = {\n ...options,\n protection: {\n ...options.protection,\n context: principalHistoryVerificationContext(options),\n },\n };\n const current = () => !options.signal?.aborted && options.stillCurrent();\n assertProjectionVerificationCurrent(current);\n const { scopeId, saved, artifacts, verifier, previous } =\n await restorePredecessor(options);\n const expectedHead = await groupPolicyMutationHead(request);\n assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });\n const keys = await collectPrincipalPolicySignerPublicKeys({\n bundle: { currentState: response.currentState, previousStates: [] },\n resolveTrustedUserIdentity: options.resolveTrustedUserIdentity,\n });\n assertProjectionVerificationCurrent(current);\n if (\"error\" in keys)\n throw new KeyingVerificationError(\n keys.error === \"not-found\" ? \"missing_dependency\" : \"signer_mismatch\",\n \"Acknowledged principal signer could not be authenticated\",\n );\n const externalAuthority = await options.loadExternalAuthority?.(\n request.state.externalAuthority ? [request.state.externalAuthority] : [],\n );\n assertProjectionVerificationCurrent(current);\n const policy = await acknowledgeGroupPolicyState({\n verifiedCurrentPolicy: previous,\n expectedHead,\n request,\n response: response.currentState,\n signerPublicKeys: keys.signerPublicKeys,\n externalAuthority,\n stillCurrent: current,\n });\n const entry = {\n state: response.currentState,\n projection: response.currentProjection,\n grants: response.currentGrants,\n };\n assertPrincipalHistoryVerificationMode(options, [entry]);\n const predecessorStage = await sealPrincipalCurrentStage(\n options,\n previous.state,\n verifier,\n artifacts,\n );\n const appended = await verifier.append({\n entries: [entry],\n signerPublicKeys: keys.signerPublicKeys,\n ...(externalAuthority ? { externalAuthority } : {}),\n });\n if (!appended.ok) throw appended.error;\n const sealed = await sealPrincipalCurrentPublication(\n options,\n scopeId,\n expectedHead,\n verifier,\n response,\n );\n assertProjectionVerificationCurrent(current);\n return {\n policy,\n previousPrefixProgress: saved.progress,\n predecessorStage,\n ...sealed,\n evidence: await preparePrincipalHistoryEvidencePage({\n scopeId,\n organizationId: options.organizationId,\n entries: [entry],\n nodes: appended.value.indexNodes,\n }),\n };\n}\n\n/** Extend authenticated local progress and retain exact acknowledged artifacts atomically with pins. */\nexport async function retainAcknowledgedPrincipalCurrents(input: {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly entries: readonly AcknowledgedPrincipalCurrentInput[];\n readonly retirements?:\n | readonly AcknowledgedPrincipalCurrentRetirement[]\n | undefined;\n readonly stillCurrent: () => boolean;\n}): Promise<VerifiedPrincipalPolicyCurrent[]> {\n const execSql = input.execSql;\n const organizationId = input.organizationId;\n const stillCurrent = input.stillCurrent;\n const retirements = structuredClone(input.retirements ?? []);\n const entries: {\n initialGroup: boolean;\n request: PutPrincipalPolicyRequest;\n response: PrincipalPolicyMutationResponse;\n options: RecoverPrincipalPolicyHistoryOptions;\n }[] = [];\n try {\n assertProjectionVerificationCurrent(stillCurrent);\n for (const entry of input.entries)\n entries.push({\n initialGroup: entry.initialGroup === true,\n request: structuredClone(entry.request),\n response: structuredClone(entry.response),\n options: {\n ...entry.recovery,\n expectedHead: structuredClone(entry.recovery.expectedHead),\n protection: ownPrincipalHistoryProtection(entry.recovery.protection),\n execSql,\n organizationId,\n stillCurrent,\n },\n });\n const publications: AcknowledgedPrincipalCurrentPublication[] = [];\n for (const entry of entries)\n publications.push(\n await (entry.initialGroup\n ? prepareInitialGroupCurrentPublication\n : preparePublication)(entry.options, entry.request, entry.response),\n );\n assertAcknowledgedDirectoryBindings(\n organizationId,\n entries.map(({ response }) => response),\n );\n await persistAcknowledgedPrincipalCurrents({\n execSql,\n organizationId,\n entries: publications,\n retirements,\n stillCurrent: () =>\n stillCurrent() &&\n entries.every((entry) => !entry.options.signal?.aborted),\n });\n return publications.map(({ policy }) => policy);\n } finally {\n for (const entry of entries) entry.options.protection.localKey.fill(0);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"retainAcknowledgedPrincipalCurrents.js","sourceRoot":"","sources":["retainAcknowledgedPrincipalCurrents.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n restorePrincipalPolicyHistoryVerifier,\n type VerifiedPrincipalPolicyCurrent,\n verifyPrincipalPolicyCurrent,\n} from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport {\n type AcknowledgedPrincipalCurrentPublication,\n type AcknowledgedPrincipalCurrentRetirement,\n persistAcknowledgedPrincipalCurrents,\n} from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\nimport { preparePrincipalHistoryEvidencePage } from \"../../data/persistence/principalHistoryEvidencePersistence\";\nimport { loadPrincipalHistoryPrefix } from \"../../data/persistence/principalHistoryPrefixPersistence\";\nimport {\n principalHistoryEvidenceScopeId,\n principalHistoryPrefixProtection,\n} from \"../../data/principals/principalHistoryPrefixProtection\";\nimport { ownPrincipalHistoryProtection } from \"../../data/principals/principalHistoryProtection\";\nimport { parsePrincipalHistoryStageCurrent } from \"../../data/principals/principalHistoryStageProtection\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { collectPrincipalPolicySignerPublicKeys } from \"../principals/policyVerification\";\nimport type { RecoverPrincipalPolicyHistoryOptions } from \"../principals/principalHistoryRecoveryTypes\";\nimport {\n assertPrincipalHistoryVerificationMode,\n principalHistoryVerificationContext,\n} from \"../principals/principalHistoryRecoveryVerification\";\nimport { assertAcknowledgedDirectoryBindings } from \"./acknowledgedDirectoryBindings\";\nimport { acknowledgeGroupPolicyState } from \"./groupPolicyMutationAcknowledgement\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport { prepareInitialGroupCurrentPublication } from \"./initialPrincipalCurrentPublication\";\nimport {\n sealPrincipalCurrentPublication,\n sealPrincipalCurrentStage,\n} from \"./principalCurrentPublicationSeal\";\nimport { assertPrincipalPolicyReceiptArtifacts } from \"./principalPolicyReceiptArtifacts\";\n\nexport type { AcknowledgedPrincipalCurrentRetirement } from \"../../data/persistence/principalCurrentAcknowledgementPersistence\";\n\nexport interface AcknowledgedPrincipalCurrentInput {\n /** Only a newly authored group at version one; never skips a predecessor. */\n readonly initialGroup?: boolean | undefined;\n /** The same scoped protection and verification mode used to recover the predecessor. */\n readonly recovery: Omit<\n RecoverPrincipalPolicyHistoryOptions,\n \"execSql\" | \"organizationId\" | \"stillCurrent\"\n >;\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n}\n\nasync function restorePredecessor(\n options: RecoverPrincipalPolicyHistoryOptions,\n) {\n const scopeId = await principalHistoryEvidenceScopeId({\n organizationId: options.organizationId,\n head: options.expectedHead,\n protection: options.protection,\n });\n const saved = await loadPrincipalHistoryPrefix(options.execSql, scopeId);\n if (!saved || saved.organizationId !== options.organizationId)\n throw new KeyingVerificationError(\n \"missing_dependency\",\n \"Acknowledgement requires its authenticated predecessor prefix\",\n );\n const restored = await restorePrincipalPolicyHistoryVerifier(\n {\n principalId: options.expectedHead.principalId,\n principalType: options.expectedHead.principalType,\n },\n saved.progress,\n await principalHistoryPrefixProtection(options.protection, saved),\n );\n if (!restored.ok) throw restored.error;\n const history = restored.value.finish(options.expectedHead);\n if (!history.ok) throw history.error;\n const artifacts = parsePrincipalHistoryStageCurrent({\n currentJson: saved.currentJson,\n afterVersion: saved.version - 1,\n });\n if (!artifacts)\n throw new KeyingVerificationError(\n \"invalid_shape\",\n \"Acknowledged predecessor artifacts are malformed\",\n );\n const previous = await verifyPrincipalPolicyCurrent({\n current: artifacts,\n history: history.value,\n });\n if (!previous.ok) throw previous.error;\n return {\n scopeId,\n saved,\n artifacts,\n verifier: restored.value,\n previous: previous.value,\n predecessorIndexRootHash: history.value.indexRootHash,\n };\n}\n\nasync function preparePublication(\n options: RecoverPrincipalPolicyHistoryOptions,\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n): Promise<AcknowledgedPrincipalCurrentPublication> {\n options = {\n ...options,\n protection: {\n ...options.protection,\n context: principalHistoryVerificationContext(options),\n },\n };\n const current = () => !options.signal?.aborted && options.stillCurrent();\n assertProjectionVerificationCurrent(current);\n const {\n scopeId,\n saved,\n artifacts,\n verifier,\n previous,\n predecessorIndexRootHash,\n } = await restorePredecessor(options);\n const expectedHead = await groupPolicyMutationHead(request);\n assertPrincipalPolicyReceiptArtifacts({ expectedHead, request, response });\n const keys = await collectPrincipalPolicySignerPublicKeys({\n bundle: { currentState: response.currentState, previousStates: [] },\n resolveTrustedUserIdentity: options.resolveTrustedUserIdentity,\n });\n assertProjectionVerificationCurrent(current);\n if (\"error\" in keys)\n throw new KeyingVerificationError(\n keys.error === \"not-found\" ? \"missing_dependency\" : \"signer_mismatch\",\n \"Acknowledged principal signer could not be authenticated\",\n );\n const externalAuthority = await options.loadExternalAuthority?.(\n request.state.externalAuthority ? [request.state.externalAuthority] : [],\n );\n assertProjectionVerificationCurrent(current);\n const policy = await acknowledgeGroupPolicyState({\n verifiedCurrentPolicy: previous,\n expectedHead,\n request,\n response: response.currentState,\n signerPublicKeys: keys.signerPublicKeys,\n externalAuthority,\n stillCurrent: current,\n });\n const entry = {\n state: response.currentState,\n projection: response.currentProjection,\n grants: response.currentGrants,\n };\n assertPrincipalHistoryVerificationMode(options, [entry]);\n const predecessorStage = await sealPrincipalCurrentStage(\n options,\n previous.state,\n verifier,\n artifacts,\n );\n const appended = await verifier.append({\n entries: [entry],\n signerPublicKeys: keys.signerPublicKeys,\n ...(externalAuthority ? { externalAuthority } : {}),\n });\n if (!appended.ok) throw appended.error;\n const sealed = await sealPrincipalCurrentPublication(\n options,\n scopeId,\n expectedHead,\n verifier,\n response,\n );\n assertProjectionVerificationCurrent(current);\n return {\n policy,\n previousPrefixProgress: saved.progress,\n predecessorStage,\n predecessorIndexRootHash,\n ...sealed,\n evidence: await preparePrincipalHistoryEvidencePage({\n indexRootHash: appended.value.indexRootHash,\n scopeId,\n organizationId: options.organizationId,\n entries: [entry],\n nodes: appended.value.indexNodes,\n }),\n };\n}\n\n/** Extend authenticated local progress and retain exact acknowledged artifacts atomically with pins. */\nexport async function retainAcknowledgedPrincipalCurrents(input: {\n readonly execSql: ExecSql;\n readonly organizationId: string;\n readonly entries: readonly AcknowledgedPrincipalCurrentInput[];\n readonly retirements?:\n | readonly AcknowledgedPrincipalCurrentRetirement[]\n | undefined;\n readonly stillCurrent: () => boolean;\n}): Promise<VerifiedPrincipalPolicyCurrent[]> {\n const execSql = input.execSql;\n const organizationId = input.organizationId;\n const stillCurrent = input.stillCurrent;\n const retirements = structuredClone(input.retirements ?? []);\n const entries: {\n initialGroup: boolean;\n request: PutPrincipalPolicyRequest;\n response: PrincipalPolicyMutationResponse;\n options: RecoverPrincipalPolicyHistoryOptions;\n }[] = [];\n try {\n assertProjectionVerificationCurrent(stillCurrent);\n for (const entry of input.entries)\n entries.push({\n initialGroup: entry.initialGroup === true,\n request: structuredClone(entry.request),\n response: structuredClone(entry.response),\n options: {\n ...entry.recovery,\n expectedHead: structuredClone(entry.recovery.expectedHead),\n protection: ownPrincipalHistoryProtection(entry.recovery.protection),\n execSql,\n organizationId,\n stillCurrent,\n },\n });\n const publications: AcknowledgedPrincipalCurrentPublication[] = [];\n for (const entry of entries)\n publications.push(\n await (entry.initialGroup\n ? prepareInitialGroupCurrentPublication\n : preparePublication)(entry.options, entry.request, entry.response),\n );\n assertAcknowledgedDirectoryBindings(\n organizationId,\n entries.map(({ response }) => response),\n );\n await persistAcknowledgedPrincipalCurrents({\n execSql,\n organizationId,\n entries: publications,\n retirements,\n stillCurrent: () =>\n stillCurrent() &&\n entries.every((entry) => !entry.options.signal?.aborted),\n });\n return publications.map(({ policy }) => policy);\n } finally {\n for (const entry of entries) entry.options.protection.localKey.fill(0);\n }\n}\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type PrincipalPolicyStateChainEntryResponse } from "../../internal/validators/response/index.js";
|
|
2
2
|
import { type RecoverPrincipalPolicyHistoryOptions } from "./principalHistoryRecoveryTypes.js";
|
|
3
|
-
export declare const PRINCIPAL_DISPLAY_HISTORY_PAGE_SIZE = 32;
|
|
4
3
|
export interface RecoveredPrincipalHistoryPage {
|
|
5
4
|
/** Ascending entries, with the immediate predecessor kept separately for diffs. */
|
|
6
5
|
readonly entries: readonly PrincipalPolicyStateChainEntryResponse[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KeyingVerificationError, verifyPrincipalPolicyHistoryReferences, } from "../../internal/crypto/index.js";
|
|
2
|
-
import { isPrincipalPolicyStateChainEntryResponse, } from "../../internal/validators/response/index.js";
|
|
2
|
+
import { isPrincipalPolicyStateChainEntryResponse, PRINCIPAL_DISPLAY_HISTORY_PAGE_SIZE, } from "../../internal/validators/response/index.js";
|
|
3
3
|
import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
|
|
4
4
|
import { loadPrincipalPolicyCheckpoint } from "../../data/persistence/keyingCheckpointPersistence.js";
|
|
5
5
|
import { loadPrincipalHistoryReference } from "../../data/persistence/principalHistoryEvidencePersistence.js";
|
|
@@ -9,7 +9,6 @@ import { loadVerifiedPrincipalHistoryPrefix } from "./principalHistoryRecoveryPr
|
|
|
9
9
|
import { PrincipalHistoryEvidenceUnavailableError } from "./principalHistoryRecoveryReferences.js";
|
|
10
10
|
import { PrincipalHistoryRecoveryRaceError, } from "./principalHistoryRecoveryTypes.js";
|
|
11
11
|
import { principalHistoryVerificationContext } from "./principalHistoryRecoveryVerification.js";
|
|
12
|
-
export const PRINCIPAL_DISPLAY_HISTORY_PAGE_SIZE = 32;
|
|
13
12
|
/** Read a bounded historical window from an already recovered, exact private root. */
|
|
14
13
|
export async function loadRecoveredPrincipalHistoryPage(options, beforeVersion = options.expectedHead.version + 1) {
|
|
15
14
|
const owned = {
|