@tearleads/client-sdk 0.1.18 → 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/container-contents/documentMoveIntentPersistence.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/loro/document.js +8 -11
- package/internal/loro/document.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 +4 -4
- 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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currentShareGrantMutation.js","sourceRoot":"","sources":["currentShareGrantMutation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MaterializedContainerSharePlan } from \"../../../data/containers/shared/types\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { commitCurrentGroupPolicyMutation } from \"../../organizations/commitCurrentGroupPolicyMutation\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadataRuntime\";\nimport { buildSetGroupContainerGrantPolicyRequest } from \"../../organizations/groupPolicyRequests\";\nimport {\n type PreparedPrincipalContainerRematerializationBatch,\n preparePrincipalContainerRematerializationBatch,\n} from \"../../organizations/principalContainerRematerialization\";\nimport { groupPolicyNameMismatch } from \"../../organizations/principalPolicyRequest\";\nimport type {\n createRuntimeCurrentGroupMutation,\n RuntimeCurrentGroupMutationContext,\n} from \"../../organizations/runtimeCurrentGroupMutation\";\nimport type { createRuntimeCurrentSharePrincipalPolicy } from \"./currentSharePrincipalPolicy\";\nimport type { shareRemoteContainerWithGroup } from \"./share\";\nimport { GroupShareNameMismatchError } from \"./sharePrincipalPolicy\";\n\n/** Fresh mutation authority rechecks the chosen name before authoring a grant. */\nexport async function commitCurrentShareGrant(input: {\n readonly runtime: Parameters<\n typeof createRuntimeCurrentSharePrincipalPolicy\n >[0];\n readonly share: Parameters<typeof shareRemoteContainerWithGroup>[0];\n readonly recitationStillCurrent?: (() => boolean) | undefined;\n readonly mutate: NonNullable<\n ReturnType<typeof createRuntimeCurrentGroupMutation>\n >;\n}): ReturnType<typeof shareRemoteContainerWithGroup> {\n const share = input.share;\n const expectedName = share.expectedGroupName;\n if (expectedName === null)\n throw new Error(\n \"Minting a group grant requires the chosen group name; only a re-wrap of an existing signed grant may omit it\",\n );\n const signingKeyPair = share.signingKeyPair;\n if (!signingKeyPair)\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n return input.mutate(\n {\n groupId: share.recipientGroupId,\n organizationId: share.author.organizationId,\n signerUserId: share.author.signerUserId,\n stillCurrent: share.stillCurrent ?? (() => true),\n },\n async (context) => {\n await assertCurrentShareGrantName(\n input.runtime,\n share,\n context,\n expectedName,\n );\n const request = await buildSetGroupContainerGrantPolicyRequest({\n ...context,\n accessLevel: share.accessLevel,\n containerId: share.containerId,\n signerUserId: share.author.signerUserId,\n signingFingerprint: share.author.signerKeyFingerprint,\n signingKeyPair,\n });\n const prepared: {\n batch?: PreparedPrincipalContainerRematerializationBatch;\n } = {};\n const response = await commitCurrentGroupPolicyMutation({\n apiClient: share.apiClient,\n context,\n groupId: share.recipientGroupId,\n organizationId: share.author.organizationId,\n request,\n signerUserId: share.author.signerUserId,\n signingFingerprint: share.author.signerKeyFingerprint,\n signingKeyPair,\n resolveTrustedUserIdentity: share.resolveTrustedUserIdentity,\n prepareContainerMutations: async (nextPolicy) => {\n prepared.batch = await prepareCurrentShareGrantBatch(\n share,\n context,\n nextPolicy,\n input.recitationStillCurrent,\n );\n return prepared.batch;\n },\n });\n const index =\n prepared.batch?.plans.findIndex(\n (planned) => planned.plan.containerId === share.containerId,\n ) ?? -1;\n const plan = prepared.batch?.plans[index];\n const acknowledgement = response.containerMutations[index];\n if (!plan || !acknowledgement || !isSharePlan(plan))\n throw new Error(\"Container group share acknowledgement is incomplete\");\n return {\n containerKey: plan.containerKey,\n plan: plan.plan,\n response: acknowledgement,\n };\n },\n );\n}\n\nfunction isSharePlan(\n plan: PreparedPrincipalContainerRematerializationBatch[\"plans\"][number],\n): plan is MaterializedContainerSharePlan {\n return plan.plan.body.eventType === \"container.grant\";\n}\n\nasync function assertCurrentShareGrantName(\n runtime: Parameters<typeof createRuntimeCurrentSharePrincipalPolicy>[0],\n share: Parameters<typeof shareRemoteContainerWithGroup>[0],\n context: RuntimeCurrentGroupMutationContext,\n expectedName: string,\n) {\n const mismatch = await groupPolicyNameMismatch(\n context.currentPolicy,\n expectedName,\n createRuntimeGroupMetadataAccess(\n runtime,\n share.author.organizationId,\n context.stillCurrent,\n context.verifyMetadataContainer,\n ).readName,\n );\n if (mismatch)\n throw new GroupShareNameMismatchError(\n \"Container share group name does not match the signed group policy\",\n );\n assertProjectionVerificationCurrent(context.stillCurrent);\n}\n\nfunction prepareCurrentShareGrantBatch(\n share: Parameters<typeof shareRemoteContainerWithGroup>[0],\n context: RuntimeCurrentGroupMutationContext,\n nextPolicy: Parameters<\n typeof preparePrincipalContainerRematerializationBatch\n >[0][\"nextPolicy\"],\n recitationStillCurrent?: () => boolean,\n) {\n return preparePrincipalContainerRematerializationBatch({\n ...share,\n grants: [\n ...new Map(\n [...context.currentPolicy.currentGrants, ...nextPolicy.grants].map(\n (grant) => [grant.containerId, grant] as const,\n ),\n ).values(),\n ],\n groupId: share.recipientGroupId,\n nextPolicy,\n resolveAuthoredPolicyReferences: context.resolveAuthoredPolicyReferences,\n stillCurrent: context.stillCurrent,\n recitationStillCurrent,\n });\n}\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { KeyingVerificationError, } from "../../../internal/crypto/index.js";
|
|
2
|
+
import { assertProjectionVerificationCurrent } from "../../../data/keyingProjectionVerification/types.js";
|
|
3
|
+
import { advanceKeyingCheckpointsAtomically } from "../../../data/persistence/keyingCheckpointAdvancePersistence.js";
|
|
4
|
+
import { principalHeadMatchesReference } from "../../../data/principals/organizationAuthorityDescriptor.js";
|
|
5
|
+
import { createSelectedCurrentGroupMetadataContainerVerifier } from "../../organizations/currentGroupMetadataAuthority.js";
|
|
6
|
+
import { loadCurrentOrganizationAuthority } from "../../organizations/currentOrganizationAuthority.js";
|
|
7
|
+
import { createCurrentPrincipalMutationLease } from "../../organizations/currentPrincipalMutationLease.js";
|
|
8
|
+
import { assertGroupMetadataBinding } from "../../organizations/groupMetadataBinding.js";
|
|
9
|
+
import { createRuntimeGroupMetadataAccess } from "../../organizations/groupMetadataRuntime.js";
|
|
10
|
+
import { groupPolicyNameMismatch, } from "../../organizations/principalPolicyRequest.js";
|
|
11
|
+
import { GroupShareNameMismatchError } from "./sharePrincipalPolicy.js";
|
|
12
|
+
/** A share read need not be a group administrator; minting a grant checks that separately. */
|
|
13
|
+
export function createRuntimeCurrentSharePrincipalPolicy(runtime) {
|
|
14
|
+
const lease = createCurrentPrincipalMutationLease(runtime);
|
|
15
|
+
if (!lease)
|
|
16
|
+
return undefined;
|
|
17
|
+
return async (input, work) => {
|
|
18
|
+
input = {
|
|
19
|
+
...input,
|
|
20
|
+
expectedGroupHead: input.expectedGroupHead
|
|
21
|
+
? { ...input.expectedGroupHead }
|
|
22
|
+
: undefined,
|
|
23
|
+
};
|
|
24
|
+
return lease(input.stillCurrent, async ({ resolveCurrentPolicy, stillCurrent: leaseCurrent }) => {
|
|
25
|
+
await runtime.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);
|
|
26
|
+
assertProjectionVerificationCurrent(leaseCurrent);
|
|
27
|
+
const authority = await loadCurrentOrganizationAuthority({
|
|
28
|
+
execSql: runtime.infra.execSql,
|
|
29
|
+
organizationId: input.organizationId,
|
|
30
|
+
resolveCurrentPolicy,
|
|
31
|
+
stillCurrent: leaseCurrent,
|
|
32
|
+
});
|
|
33
|
+
const group = await authority.readGroup(input.groupId);
|
|
34
|
+
const stillCurrent = () => leaseCurrent() && authority.stillCurrent() && group.stillCurrent();
|
|
35
|
+
assertProjectionVerificationCurrent(stillCurrent);
|
|
36
|
+
if (input.expectedGroupHead &&
|
|
37
|
+
!principalHeadMatchesReference(group.policy.state, input.expectedGroupHead))
|
|
38
|
+
throw new KeyingVerificationError("object_mismatch", "Container share expected group head conflicts with the signed organization directory");
|
|
39
|
+
assertGroupMetadataBinding(group.current, authority.descriptor);
|
|
40
|
+
await assertCurrentShareName({
|
|
41
|
+
runtime,
|
|
42
|
+
input,
|
|
43
|
+
authority,
|
|
44
|
+
group,
|
|
45
|
+
stillCurrent,
|
|
46
|
+
});
|
|
47
|
+
assertProjectionVerificationCurrent(stillCurrent);
|
|
48
|
+
const checkpointPolicies = [...group.dependencies, group.policy];
|
|
49
|
+
await advanceKeyingCheckpointsAtomically({
|
|
50
|
+
access: [],
|
|
51
|
+
execSql: runtime.infra.execSql,
|
|
52
|
+
organizationId: input.organizationId,
|
|
53
|
+
policies: checkpointPolicies,
|
|
54
|
+
stillCurrent,
|
|
55
|
+
});
|
|
56
|
+
assertProjectionVerificationCurrent(stillCurrent);
|
|
57
|
+
const result = await work({
|
|
58
|
+
current: group.current,
|
|
59
|
+
policy: group.policy,
|
|
60
|
+
checkpointPolicies,
|
|
61
|
+
stillCurrent,
|
|
62
|
+
});
|
|
63
|
+
assertProjectionVerificationCurrent(stillCurrent);
|
|
64
|
+
return result;
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function assertCurrentShareName({ runtime, input, authority, group, stillCurrent, }) {
|
|
69
|
+
if (input.expectedGroupName === undefined)
|
|
70
|
+
return;
|
|
71
|
+
const readName = input.readEncryptedName ??
|
|
72
|
+
createRuntimeGroupMetadataAccess(runtime, input.organizationId, stillCurrent, createSelectedCurrentGroupMetadataContainerVerifier({
|
|
73
|
+
authority,
|
|
74
|
+
organizationId: input.organizationId,
|
|
75
|
+
stillCurrent,
|
|
76
|
+
})).readName;
|
|
77
|
+
const mismatch = await groupPolicyNameMismatch(group.current, input.expectedGroupName, readName);
|
|
78
|
+
if (mismatch)
|
|
79
|
+
throw new GroupShareNameMismatchError(mismatch === "forbidden_characters"
|
|
80
|
+
? "Container share group name contains control or format characters"
|
|
81
|
+
: "Container share group name does not match the signed group policy");
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=currentSharePrincipalPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"currentSharePrincipalPolicy.js","sourceRoot":"","sources":["currentSharePrincipalPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n KeyingVerificationError,\n type ReferencedPrincipalHead,\n} from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../../data/keyingProjectionVerification/types\";\nimport { advanceKeyingCheckpointsAtomically } from \"../../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { principalHeadMatchesReference } from \"../../../data/principals/organizationAuthorityDescriptor\";\nimport { createSelectedCurrentGroupMetadataContainerVerifier } from \"../../organizations/currentGroupMetadataAuthority\";\nimport { loadCurrentOrganizationAuthority } from \"../../organizations/currentOrganizationAuthority\";\nimport { createCurrentPrincipalMutationLease } from \"../../organizations/currentPrincipalMutationLease\";\nimport { assertGroupMetadataBinding } from \"../../organizations/groupMetadataBinding\";\nimport { createRuntimeGroupMetadataAccess } from \"../../organizations/groupMetadataRuntime\";\nimport type { PrincipalMutationRecoveryApi } from \"../../organizations/principalMutationJournalManagement\";\nimport {\n type GroupPolicyNameReader,\n groupPolicyNameMismatch,\n} from \"../../organizations/principalPolicyRequest\";\nimport { GroupShareNameMismatchError } from \"./sharePrincipalPolicy\";\n\ntype CurrentShareRuntime = Parameters<\n typeof createRuntimeGroupMetadataAccess\n>[0] &\n Parameters<typeof createCurrentPrincipalMutationLease>[0] & {\n readonly apiClient: {\n readonly recoverPendingPrincipalMutation?:\n | PrincipalMutationRecoveryApi[\"recoverPendingPrincipalMutation\"]\n | undefined;\n };\n };\n\ninterface CurrentShareInput {\n readonly groupId: string;\n readonly organizationId: string;\n readonly expectedGroupHead?: ReferencedPrincipalHead | undefined;\n readonly expectedGroupName?: string | undefined;\n /** Trusted internal reader; it must authenticate the signed metadata container. */\n readonly readEncryptedName?: GroupPolicyNameReader | undefined;\n readonly stillCurrent: () => boolean;\n}\n\ntype CurrentGroup = Awaited<\n ReturnType<\n Awaited<ReturnType<typeof loadCurrentOrganizationAuthority>>[\"readGroup\"]\n >\n>;\n\nexport interface CurrentSharePrincipalPolicy {\n readonly current: CurrentGroup[\"current\"];\n readonly policy: CurrentGroup[\"policy\"];\n readonly checkpointPolicies: readonly CurrentGroup[\"policy\"][];\n readonly stillCurrent: () => boolean;\n}\n\n/** A share read need not be a group administrator; minting a grant checks that separately. */\nexport function createRuntimeCurrentSharePrincipalPolicy(\n runtime: CurrentShareRuntime,\n) {\n const lease = createCurrentPrincipalMutationLease(runtime);\n if (!lease) return undefined;\n return async <T>(\n input: CurrentShareInput,\n work: (policy: CurrentSharePrincipalPolicy) => Promise<T>,\n ): Promise<T> => {\n input = {\n ...input,\n expectedGroupHead: input.expectedGroupHead\n ? { ...input.expectedGroupHead }\n : undefined,\n };\n return lease(\n input.stillCurrent,\n async ({ resolveCurrentPolicy, stillCurrent: leaseCurrent }) => {\n await runtime.apiClient.recoverPendingPrincipalMutation?.(\n input.organizationId,\n );\n assertProjectionVerificationCurrent(leaseCurrent);\n const authority = await loadCurrentOrganizationAuthority({\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n resolveCurrentPolicy,\n stillCurrent: leaseCurrent,\n });\n const group = await authority.readGroup(input.groupId);\n const stillCurrent = () =>\n leaseCurrent() && authority.stillCurrent() && group.stillCurrent();\n assertProjectionVerificationCurrent(stillCurrent);\n if (\n input.expectedGroupHead &&\n !principalHeadMatchesReference(\n group.policy.state,\n input.expectedGroupHead,\n )\n )\n throw new KeyingVerificationError(\n \"object_mismatch\",\n \"Container share expected group head conflicts with the signed organization directory\",\n );\n assertGroupMetadataBinding(group.current, authority.descriptor);\n await assertCurrentShareName({\n runtime,\n input,\n authority,\n group,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const checkpointPolicies = [...group.dependencies, group.policy];\n await advanceKeyingCheckpointsAtomically({\n access: [],\n execSql: runtime.infra.execSql,\n organizationId: input.organizationId,\n policies: checkpointPolicies,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const result = await work({\n current: group.current,\n policy: group.policy,\n checkpointPolicies,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n return result;\n },\n );\n };\n}\n\nasync function assertCurrentShareName({\n runtime,\n input,\n authority,\n group,\n stillCurrent,\n}: {\n runtime: CurrentShareRuntime;\n input: CurrentShareInput;\n authority: Awaited<ReturnType<typeof loadCurrentOrganizationAuthority>>;\n group: CurrentGroup;\n stillCurrent: () => boolean;\n}) {\n if (input.expectedGroupName === undefined) return;\n const readName =\n input.readEncryptedName ??\n createRuntimeGroupMetadataAccess(\n runtime,\n input.organizationId,\n stillCurrent,\n createSelectedCurrentGroupMetadataContainerVerifier({\n authority,\n organizationId: input.organizationId,\n stillCurrent,\n }),\n ).readName;\n const mismatch = await groupPolicyNameMismatch(\n group.current,\n input.expectedGroupName,\n readName,\n );\n if (mismatch)\n throw new GroupShareNameMismatchError(\n mismatch === \"forbidden_characters\"\n ? \"Container share group name contains control or format characters\"\n : \"Container share group name does not match the signed group policy\",\n );\n}\n"]}
|
|
@@ -107,7 +107,7 @@ export async function submitAcknowledgedContainerMutation(input) {
|
|
|
107
107
|
// path, so listing it here spares its recitation budget.
|
|
108
108
|
plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],
|
|
109
109
|
reportSecurityIncident: input.reportSecurityIncident,
|
|
110
|
-
stillCurrent: input.stillCurrent,
|
|
110
|
+
stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
113
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnyVerifiedPrincipalPolicy } from \"@tearleads/crypto\";\nimport type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./carriedDescendantRekeys\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly AnyVerifiedPrincipalPolicy[];\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) return null;\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mutationSubmit.js","sourceRoot":"","sources":["mutationSubmit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerMutationRequest } from \"@tearleads/validators/request\";\nimport {\n CONTAINER_MUTATION_ERROR_CODES,\n type ContainerRotationResponse,\n} from \"@tearleads/validators/response\";\nimport { ContainerPathTooDeepError } from \"../../../data/containers/shared/containerPathLimits\";\nimport { rememberVerifiedContainerHeads } from \"../../../data/containers/shared/heldContainerHeads\";\nimport {\n acknowledgeContainerMutation,\n acknowledgeContainerMutationBatch,\n} from \"../../../data/containers/shared/mutationAcknowledgement\";\nimport { isContainerPathTooDeepFailure } from \"../../../data/containers/shared/mutationFailures\";\nimport type { ContainerReciteApi } from \"../../../data/containers/shared/reciteApi\";\nimport type {\n ContainerMutationAuthor,\n ContainerRotationResult,\n MaterializedContainerRekeyPlan,\n} from \"../../../data/containers/shared/types\";\nimport type { PrincipalPolicyCheckpointEvidence } from \"../../../data/principals/principalPolicyEvidence\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n type CarriedRekeyPlanningInput,\n planCarriedDescendantRekeys,\n type SpeculativePath,\n} from \"./carriedDescendantRekeys\";\nimport { scheduleHeldDescendantRecitations } from \"./recite\";\n\n/**\n * Supplied by mutations that mint a new key epoch (rekey, revoke, move). The\n * server refuses one that would strand a level above a directly granted\n * container, and names the descendant rekeys it must carry instead (#2340).\n */\nexport interface CarriedRekeys {\n readonly planning: CarriedRekeyPlanningInput;\n /** The rotated container's own path once the rotation is accepted. */\n readonly rotated: () => Promise<SpeculativePath>;\n}\n\n/** A mutation with no status-bearing variant: a share mints nothing to carry. */\nexport async function submitPlainContainerMutation(\n plain: () => Promise<ContainerRotationResponse | null>,\n): Promise<ContainerRotationResult> {\n const data = await plain();\n return data ? { data, ok: true } : { ok: false, status: null };\n}\n\n/**\n * Adapt a rotation endpoint pair to one status-bearing call. An adapter with\n * only the plain method still rotates; it just cannot learn what to carry, so a\n * rotation that needs descendants fails as any other refusal does.\n */\nexport async function submitContainerRotation(input: {\n plain: () => Promise<ContainerRotationResponse | null>;\n result: (() => Promise<ContainerRotationResult>) | undefined;\n}): Promise<ContainerRotationResult> {\n return input.result\n ? input.result()\n : submitPlainContainerMutation(input.plain);\n}\n\n/**\n * Submit a rotation; if the server refuses it for stranding a level above a\n * directly granted container, sign the descendant rekeys it names and resubmit\n * once with them carried. The refused attempt rolled back whole, so the signed\n * rotation still extends the current head and only the descendants need\n * signing. A second refusal means the tree moved underneath, and the caller's\n * own retry starts from a fresh projection.\n */\nexport async function submitRotationCarryingDescendants(input: {\n carriedRekeys?: CarriedRekeys | undefined;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n carriedPlans: MaterializedContainerRekeyPlan[];\n result: ContainerRotationResult;\n}> {\n const result = await input.submit([]);\n if (\n result.ok ||\n result.code !== CONTAINER_MUTATION_ERROR_CODES.descendantRekeysRequired ||\n !result.requiredContainerIds?.length ||\n !input.carriedRekeys\n ) {\n return { carriedPlans: [], result: reportTerminalRefusal(result) };\n }\n // Answerable, so not an error: callers submit with `reportErrors: false` and\n // only the refusal that ends the attempt is surfaced.\n const carriedPlans = await planCarriedDescendantRekeys({\n ...input.carriedRekeys.planning,\n requiredContainerIds: result.requiredContainerIds,\n rotated: [await input.carriedRekeys.rotated()],\n });\n // Superseded mid-flight: hand back the refusal unreported, since the caller\n // discards it and the generation that owned this attempt is gone.\n if (input.stillCurrent?.() === false) return { carriedPlans: [], result };\n return {\n carriedPlans,\n result: reportTerminalRefusal(\n await input.submit(carriedPlans.map(({ plan }) => plan.request)),\n ),\n };\n}\n\nfunction reportTerminalRefusal(\n result: ContainerRotationResult,\n): ContainerRotationResult {\n if (!result.ok) result.report?.();\n return result;\n}\n\n/**\n * Submit and acknowledge remote share/rekey/revoke/move plans before scheduling\n * opportunistic descendant re-citations. Create separately handles its lost\n * response conflict; group share caches the rotated policy after this tail.\n */\nexport async function submitAcknowledgedContainerMutation<\n TPlan extends Parameters<typeof acknowledgeContainerMutation>[0][\"plan\"],\n>(input: {\n apiClient: ContainerReciteApi;\n author: ContainerMutationAuthor;\n /** Present exactly when the plan minted a new key epoch. */\n carriedRekeys?: CarriedRekeys | undefined;\n containerKey: Uint8Array;\n execSql: ExecSql;\n plan: TPlan;\n recitationPolicies: readonly PrincipalPolicyCheckpointEvidence[];\n /** Session lifetime for best-effort work after durable acknowledgement. */\n recitationStillCurrent?: (() => boolean) | undefined;\n reportSecurityIncident: SecurityIncidentReporter;\n stillCurrent?: (() => boolean) | undefined;\n submit: (\n carried: readonly ContainerMutationRequest[],\n ) => Promise<ContainerRotationResult>;\n}): Promise<{\n containerKey: Uint8Array;\n plan: TPlan;\n response: ContainerRotationResponse;\n} | null> {\n if (input.stillCurrent?.() === false) return null;\n const submitted = await submitRotationCarryingDescendants(input);\n if (!submitted.result.ok) {\n // Final, unlike the other refusals: a queued move must not retry it.\n if (isContainerPathTooDeepFailure(submitted.result))\n throw new ContainerPathTooDeepError();\n return null;\n }\n const { carriedPlans } = submitted;\n const response = submitted.result.data;\n\n const acknowledged =\n carriedPlans.length === 0\n ? await acknowledgeContainerMutation({\n execSql: input.execSql,\n plan: input.plan,\n response,\n stillCurrent: input.stillCurrent,\n })\n : // The rotation and what it carried committed together, so their pins\n // advance together: a missing acknowledgement refuses the whole batch.\n await acknowledgeContainerMutationBatch({\n execSql: input.execSql,\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n responses: [response, ...(response.containerRekeys ?? [])],\n stillCurrent: input.stillCurrent,\n });\n if (!acknowledged || input.stillCurrent?.() === false) return null;\n\n try {\n rememberVerifiedContainerHeads({\n execSql: input.execSql,\n organizationId: input.author.organizationId,\n heads: [],\n policies: input.recitationPolicies,\n });\n scheduleHeldDescendantRecitations({\n apiClient: input.apiClient,\n author: input.author,\n execSql: input.execSql,\n // `plans` are the containers whose descendants get re-cited; they are\n // never re-cited themselves. A carried rekey already cites the current\n // path, so listing it here spares its recitation budget.\n plans: [input.plan, ...carriedPlans.map(({ plan }) => plan)],\n reportSecurityIncident: input.reportSecurityIncident,\n stillCurrent: input.recitationStillCurrent ?? input.stillCurrent,\n });\n } catch {\n // Optional cache population cannot change an acknowledged mutation result.\n }\n return {\n containerKey: input.containerKey,\n plan: input.plan,\n response,\n };\n}\n"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { nullOnProjectionVerificationCancellation, requireProjectionUserKeyResolver, } from "../../../data/keyingProjectionVerification.js";
|
|
2
|
+
import { principalPolicyCacheForVerifiedPolicies } from "../../../data/keyingProjectionVerification/principalPolicyCache.js";
|
|
3
|
+
import { inheritPrincipalHistoryProtection } from "../../../data/principals/principalHistoryRuntime.js";
|
|
4
|
+
import { createRuntimeCurrentGroupMutation } from "../../organizations/runtimeCurrentGroupMutation.js";
|
|
5
|
+
import { commitCurrentShareGrant } from "./currentShareGrantMutation.js";
|
|
6
|
+
import { createRuntimeCurrentSharePrincipalPolicy } from "./currentSharePrincipalPolicy.js";
|
|
7
|
+
import { submitAcknowledgedContainerMutation, submitPlainContainerMutation, } from "./mutationSubmit.js";
|
|
8
|
+
import { buildMaterializedContainerSharePlan } from "./shareMaterialization.js";
|
|
9
|
+
import { resolveShareProjection } from "./shareProjection.js";
|
|
10
|
+
/** Current evidence covers planning, any compound grant mint, and acknowledgement. */
|
|
11
|
+
export function createRuntimeCurrentGroupShare(runtime) {
|
|
12
|
+
const readCurrent = createRuntimeCurrentSharePrincipalPolicy(runtime);
|
|
13
|
+
const api = runtime.apiClient;
|
|
14
|
+
const readPages = api.getPrincipalPolicyPages;
|
|
15
|
+
if (!readCurrent || !readPages)
|
|
16
|
+
return undefined;
|
|
17
|
+
const mutate = createRuntimeCurrentGroupMutation(inheritPrincipalHistoryProtection(runtime, {
|
|
18
|
+
...runtime,
|
|
19
|
+
apiClient: {
|
|
20
|
+
getPrincipalPolicyPages: readPages.bind(api),
|
|
21
|
+
...(api.getProjectionPolicyHistoryPages
|
|
22
|
+
? {
|
|
23
|
+
getProjectionPolicyHistoryPages: api.getProjectionPolicyHistoryPages.bind(api),
|
|
24
|
+
}
|
|
25
|
+
: {}),
|
|
26
|
+
recoverPendingPrincipalMutation: async (organizationId) => {
|
|
27
|
+
// Built-in clients supply journal recovery; standalone hosts retain
|
|
28
|
+
// the same transport/recovery responsibility as the legacy adapter.
|
|
29
|
+
await api.recoverPendingPrincipalMutation?.(organizationId);
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}));
|
|
33
|
+
if (!mutate)
|
|
34
|
+
throw new Error("Current group mutation custody is unavailable");
|
|
35
|
+
return async (input) => {
|
|
36
|
+
if (input.stillCurrent?.() === false)
|
|
37
|
+
return null;
|
|
38
|
+
const recitationStillCurrent = input.stillCurrent ?? (() => true);
|
|
39
|
+
return nullOnProjectionVerificationCancellation(() => readCurrent({
|
|
40
|
+
expectedGroupName: input.expectedGroupName ?? undefined,
|
|
41
|
+
groupId: input.recipientGroupId,
|
|
42
|
+
organizationId: input.author.organizationId,
|
|
43
|
+
stillCurrent: input.stillCurrent ?? (() => true),
|
|
44
|
+
}, async ({ policy, checkpointPolicies, stillCurrent }) => {
|
|
45
|
+
const share = { ...input, stillCurrent };
|
|
46
|
+
const resolveProjectionUserKey = requireProjectionUserKeyResolver(input.resolveProjectionUserKey, "Remote container share");
|
|
47
|
+
const previousProjection = await resolveShareProjection(share, resolveProjectionUserKey);
|
|
48
|
+
if (!previousProjection)
|
|
49
|
+
return null;
|
|
50
|
+
const grant = policy.grants.find((candidate) => candidate.containerId === input.containerId);
|
|
51
|
+
if (!grant || grant.accessLevel !== input.accessLevel)
|
|
52
|
+
return commitCurrentShareGrant({
|
|
53
|
+
runtime,
|
|
54
|
+
share,
|
|
55
|
+
mutate,
|
|
56
|
+
recitationStillCurrent,
|
|
57
|
+
});
|
|
58
|
+
const materialized = await buildMaterializedContainerSharePlan({
|
|
59
|
+
...share,
|
|
60
|
+
previousProjection,
|
|
61
|
+
principalPolicyCache: principalPolicyCacheForVerifiedPolicies(checkpointPolicies),
|
|
62
|
+
recipient: {
|
|
63
|
+
principalPolicy: policy,
|
|
64
|
+
subjectId: input.recipientGroupId,
|
|
65
|
+
subjectType: "group",
|
|
66
|
+
},
|
|
67
|
+
resolveProjectionUserKey,
|
|
68
|
+
});
|
|
69
|
+
return submitAcknowledgedContainerMutation({
|
|
70
|
+
...share,
|
|
71
|
+
recitationPolicies: checkpointPolicies,
|
|
72
|
+
recitationStillCurrent,
|
|
73
|
+
containerKey: materialized.containerKey,
|
|
74
|
+
plan: materialized.plan,
|
|
75
|
+
submit: () => submitPlainContainerMutation(() => input.apiClient.shareContainer(input.containerId, materialized.plan.request, {
|
|
76
|
+
expectedPaymentRequiredOrganizationId: input.author.organizationId,
|
|
77
|
+
})),
|
|
78
|
+
});
|
|
79
|
+
}));
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=runtimeCurrentGroupShare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeCurrentGroupShare.js","sourceRoot":"","sources":["runtimeCurrentGroupShare.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n nullOnProjectionVerificationCancellation,\n requireProjectionUserKeyResolver,\n} from \"../../../data/keyingProjectionVerification\";\nimport { principalPolicyCacheForVerifiedPolicies } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { inheritPrincipalHistoryProtection } from \"../../../data/principals/principalHistoryRuntime\";\nimport { createRuntimeCurrentGroupMutation } from \"../../organizations/runtimeCurrentGroupMutation\";\nimport { commitCurrentShareGrant } from \"./currentShareGrantMutation\";\nimport { createRuntimeCurrentSharePrincipalPolicy } from \"./currentSharePrincipalPolicy\";\nimport {\n submitAcknowledgedContainerMutation,\n submitPlainContainerMutation,\n} from \"./mutationSubmit\";\nimport type { shareRemoteContainerWithGroup } from \"./share\";\nimport { buildMaterializedContainerSharePlan } from \"./shareMaterialization\";\nimport { resolveShareProjection } from \"./shareProjection\";\n\n/** Current evidence covers planning, any compound grant mint, and acknowledgement. */\nexport function createRuntimeCurrentGroupShare(\n runtime: Parameters<typeof createRuntimeCurrentSharePrincipalPolicy>[0],\n): typeof shareRemoteContainerWithGroup | undefined {\n const readCurrent = createRuntimeCurrentSharePrincipalPolicy(runtime);\n const api = runtime.apiClient;\n const readPages = api.getPrincipalPolicyPages;\n if (!readCurrent || !readPages) return undefined;\n const mutate = createRuntimeCurrentGroupMutation(\n inheritPrincipalHistoryProtection(runtime, {\n ...runtime,\n apiClient: {\n getPrincipalPolicyPages: readPages.bind(api),\n ...(api.getProjectionPolicyHistoryPages\n ? {\n getProjectionPolicyHistoryPages:\n api.getProjectionPolicyHistoryPages.bind(api),\n }\n : {}),\n recoverPendingPrincipalMutation: async (organizationId: string) => {\n // Built-in clients supply journal recovery; standalone hosts retain\n // the same transport/recovery responsibility as the legacy adapter.\n await api.recoverPendingPrincipalMutation?.(organizationId);\n },\n },\n }),\n );\n if (!mutate) throw new Error(\"Current group mutation custody is unavailable\");\n return async (input) => {\n if (input.stillCurrent?.() === false) return null;\n const recitationStillCurrent = input.stillCurrent ?? (() => true);\n return nullOnProjectionVerificationCancellation(() =>\n readCurrent(\n {\n expectedGroupName: input.expectedGroupName ?? undefined,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n stillCurrent: input.stillCurrent ?? (() => true),\n },\n async ({ policy, checkpointPolicies, stillCurrent }) => {\n const share = { ...input, stillCurrent };\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const previousProjection = await resolveShareProjection(\n share,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n const grant = policy.grants.find(\n (candidate) => candidate.containerId === input.containerId,\n );\n if (!grant || grant.accessLevel !== input.accessLevel)\n return commitCurrentShareGrant({\n runtime,\n share,\n mutate,\n recitationStillCurrent,\n });\n const materialized = await buildMaterializedContainerSharePlan({\n ...share,\n previousProjection,\n principalPolicyCache:\n principalPolicyCacheForVerifiedPolicies(checkpointPolicies),\n recipient: {\n principalPolicy: policy,\n subjectId: input.recipientGroupId,\n subjectType: \"group\",\n },\n resolveProjectionUserKey,\n });\n return submitAcknowledgedContainerMutation({\n ...share,\n recitationPolicies: checkpointPolicies,\n recitationStillCurrent,\n containerKey: materialized.containerKey,\n plan: materialized.plan,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materialized.plan.request,\n {\n expectedPaymentRequiredOrganizationId:\n input.author.organizationId,\n },\n ),\n ),\n });\n },\n ),\n );\n };\n}\n"]}
|
|
@@ -7,27 +7,14 @@ import { createGroupMetadataContainerVerifier } from "../../organizations/groupM
|
|
|
7
7
|
import { preparePrincipalContainerRematerializationBatch } from "../../organizations/principalContainerRematerialization.js";
|
|
8
8
|
import { setOrganizationGroupContainerGrant } from "../../organizations/principalPolicy.js";
|
|
9
9
|
import { submitAcknowledgedContainerMutation, submitPlainContainerMutation, } from "./mutationSubmit.js";
|
|
10
|
-
import { projectionWithCurrentAncestors } from "./shareAncestorRepair.js";
|
|
11
10
|
import { buildMaterializedContainerSharePlan } from "./shareMaterialization.js";
|
|
12
11
|
import { advanceVerifiedSharePolicies, loadVerifiedGroupSharePrincipalPolicy, } from "./sharePrincipalPolicy.js";
|
|
12
|
+
import { resolveShareProjection } from "./shareProjection.js";
|
|
13
13
|
class ContainerShareGenerationExpiredError extends Error {
|
|
14
14
|
}
|
|
15
15
|
async function buildCurrentContainerSharePlan(input) {
|
|
16
16
|
return nullOnProjectionVerificationCancellation(() => buildMaterializedContainerSharePlan(input));
|
|
17
17
|
}
|
|
18
|
-
/** The container's projection, with any lazily stale chain above it repaired. */
|
|
19
|
-
async function resolveShareProjection(input, resolveProjectionUserKey) {
|
|
20
|
-
const servedProjection = input.previousProjection ??
|
|
21
|
-
(await input.apiClient.getContainerWriterProjection(input.containerId));
|
|
22
|
-
if (!servedProjection || input.stillCurrent?.() === false)
|
|
23
|
-
return null;
|
|
24
|
-
const previousProjection = await projectionWithCurrentAncestors({
|
|
25
|
-
...input,
|
|
26
|
-
previousProjection: servedProjection,
|
|
27
|
-
resolveProjectionUserKey,
|
|
28
|
-
});
|
|
29
|
-
return input.stillCurrent?.() === false ? null : previousProjection;
|
|
30
|
-
}
|
|
31
18
|
export async function shareRemoteContainer(input) {
|
|
32
19
|
const resolveProjectionUserKey = requireProjectionUserKeyResolver(input.resolveProjectionUserKey, "Remote container share");
|
|
33
20
|
const resolveTrustedUserIdentity = requireTrustedUserIdentityResolver(input.resolveTrustedUserIdentity);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share.js","sourceRoot":"","sources":["share.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerAccessLevel,\n SigningKeyPair,\n VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport type {\n ContainerMutationAuthor,\n ContainerShareApi,\n ContainerSharePlan,\n MaterializedContainerSharePlan,\n} from \"../../../data/containers/shared/types\";\nimport {\n isProjectionVerificationCancelledError,\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../../data/keyingProjectionVerification\";\nimport { principalPolicyCacheForVerifiedPolicies } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { savePrincipalPolicyBundle } from \"../../../data/persistence/principalPolicyPersistence\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n requireTrustedUserIdentityResolver,\n type TrustedUserIdentityResolver,\n} from \"../../../data/trustedUserIdentity\";\nimport { createGroupMetadataAccess } from \"../../organizations/groupMetadataAccess\";\nimport { createGroupMetadataContainerVerifier } from \"../../organizations/groupMetadataContainerAuthority\";\nimport { preparePrincipalContainerRematerializationBatch } from \"../../organizations/principalContainerRematerialization\";\nimport { setOrganizationGroupContainerGrant } from \"../../organizations/principalPolicy\";\nimport type { GroupPolicyNameReader } from \"../../organizations/principalPolicyRequest\";\nimport {\n submitAcknowledgedContainerMutation,\n submitPlainContainerMutation,\n} from \"./mutationSubmit\";\nimport { projectionWithCurrentAncestors } from \"./shareAncestorRepair\";\nimport { buildMaterializedContainerSharePlan } from \"./shareMaterialization\";\nimport {\n advanceVerifiedSharePolicies,\n type ContainerManagedPrincipalShareApi,\n loadVerifiedGroupSharePrincipalPolicy,\n} from \"./sharePrincipalPolicy\";\n\nclass ContainerShareGenerationExpiredError extends Error {}\n\nasync function buildCurrentContainerSharePlan(\n input: Parameters<typeof buildMaterializedContainerSharePlan>[0],\n): Promise<MaterializedContainerSharePlan | null> {\n return nullOnProjectionVerificationCancellation(() =>\n buildMaterializedContainerSharePlan(input),\n );\n}\n\n/** The container's projection, with any lazily stale chain above it repaired. */\nasync function resolveShareProjection(\n input: Omit<\n Parameters<typeof projectionWithCurrentAncestors>[0],\n \"previousProjection\" | \"resolveProjectionUserKey\"\n > & { previousProjection?: ContainerWriterProjectionResponse | undefined },\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<ContainerWriterProjectionResponse | null> {\n const servedProjection =\n input.previousProjection ??\n (await input.apiClient.getContainerWriterProjection(input.containerId));\n if (!servedProjection || input.stillCurrent?.() === false) return null;\n const previousProjection = await projectionWithCurrentAncestors({\n ...input,\n previousProjection: servedProjection,\n resolveProjectionUserKey,\n });\n return input.stillCurrent?.() === false ? null : previousProjection;\n}\n\nexport async function shareRemoteContainer(input: {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n} | null> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const resolveTrustedUserIdentity = requireTrustedUserIdentityResolver(\n input.resolveTrustedUserIdentity,\n );\n const recipientIdentity = await resolveTrustedUserIdentity(\n input.recipientUserId,\n );\n if (!recipientIdentity || input.stillCurrent?.() === false) {\n return null;\n }\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n previousProjection,\n recipient: {\n recipientEncapsulationPublicKey: recipientIdentity.encapsulationPublicKey,\n subjectId: input.recipientUserId,\n subjectType: \"user\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n return submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: [],\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n}\n\ninterface RemoteContainerGroupShareInput {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerManagedPrincipalShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n /**\n * The display name the user chose the group by, checked against the name\n * committed in the verified group policy so a relabeled read-model row\n * cannot redirect the share onto another group. `null` is reserved for the\n * grant-preserving re-wrap: a share that would mint a new grant without a\n * name is refused.\n */\n expectedGroupName: string | null;\n readEncryptedName?: GroupPolicyNameReader | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n signingKeyPair?: SigningKeyPair | null | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\ninterface RemoteContainerGroupShareResult {\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n}\n\nfunction isMaterializedContainerSharePlan(\n value: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >[\"plans\"][number],\n): value is MaterializedContainerSharePlan {\n return value.plan.body.eventType === \"container.grant\";\n}\n\nasync function prepareMissingGroupGrantMutations(input: {\n currentPolicy: PrincipalPolicyBundleResponse;\n nextPolicy: VerifiedPrincipalPolicy;\n shareInput: RemoteContainerGroupShareInput;\n}) {\n const { currentPolicy, nextPolicy, shareInput } = input;\n return preparePrincipalContainerRematerializationBatch({\n reportSecurityIncident: shareInput.reportSecurityIncident,\n apiClient: shareInput.apiClient,\n author: shareInput.author,\n execSql: shareInput.execSql,\n grants: [\n ...new Map(\n [...currentPolicy.currentGrants, ...nextPolicy.grants].map(\n (grant) => [grant.containerId, grant] as const,\n ),\n ).values(),\n ],\n groupId: shareInput.recipientGroupId,\n nextPolicy,\n resolveTrustedUserIdentity: shareInput.resolveTrustedUserIdentity,\n stillCurrent: shareInput.stillCurrent,\n targetSecretKey: shareInput.targetSecretKey,\n warmReferencedPrincipalPolicies: shareInput.warmReferencedPrincipalPolicies,\n });\n}\n\nasync function commitMissingGroupGrantPolicy(\n input: RemoteContainerGroupShareInput,\n): Promise<{\n preparedTarget: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >;\n storedPolicy: Awaited<ReturnType<typeof setOrganizationGroupContainerGrant>>;\n} | null> {\n const signingKeyPair = input.signingKeyPair;\n if (!signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n const policyApi = {\n recoverPendingPrincipalMutation:\n input.apiClient.recoverPendingPrincipalMutation?.bind(input.apiClient),\n commitOrganizationGroupPolicy:\n input.apiClient.commitOrganizationGroupPolicy.bind(input.apiClient),\n getCurrentPrincipalPolicy: input.apiClient.getCurrentPrincipalPolicy.bind(\n input.apiClient,\n ),\n };\n let preparedTarget:\n | Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >\n | undefined;\n try {\n const storedPolicy = await setOrganizationGroupContainerGrant({\n accessLevel: input.accessLevel,\n apiClient: policyApi,\n assertCanCommit: () => {\n if (input.stillCurrent?.() === false) {\n throw new ContainerShareGenerationExpiredError();\n }\n },\n containerId: input.containerId,\n execSql: input.execSql,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n prepareContainerMutations: async ({ currentPolicy, nextPolicy }) => {\n preparedTarget = await prepareMissingGroupGrantMutations({\n currentPolicy,\n nextPolicy,\n shareInput: input,\n });\n return preparedTarget;\n },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n signerUserId: input.author.signerUserId,\n signingFingerprint: input.author.signerKeyFingerprint,\n signingKeyPair,\n });\n if (!preparedTarget) {\n throw new Error(\"Container group share preparation is incomplete\");\n }\n return { preparedTarget, storedPolicy };\n } catch (error) {\n if (\n error instanceof ContainerShareGenerationExpiredError ||\n isProjectionVerificationCancelledError(error)\n ) {\n return null;\n }\n throw error;\n }\n}\n\nasync function commitMissingGroupGrant(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (!input.signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n if (input.stillCurrent?.() === false) return null;\n const committed = await commitMissingGroupGrantPolicy(input);\n if (!committed) return null;\n const { preparedTarget, storedPolicy } = committed;\n const targetIndex = preparedTarget?.plans.findIndex(\n (planned) => planned.plan.containerId === input.containerId,\n );\n const response =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : storedPolicy.containerMutations[targetIndex];\n const targetPlan =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : preparedTarget?.plans[targetIndex];\n if (\n !targetPlan ||\n !response ||\n !isMaterializedContainerSharePlan(targetPlan)\n ) {\n throw new Error(\"Container group share acknowledgement is incomplete\");\n }\n return {\n containerKey: targetPlan.containerKey,\n plan: targetPlan.plan,\n response,\n };\n}\n\n// Only a re-wrap of an existing signed grant may run without the chosen name;\n// minting a grant is exactly the operation the name binding protects.\nfunction assertGrantMintNamed(expectedGroupName: string | null): void {\n if (expectedGroupName === null) {\n throw new Error(\n \"Minting a group grant requires the chosen group name; only a re-wrap of an existing signed grant may omit it\",\n );\n }\n}\n\nfunction loadShareGroupPolicy(input: RemoteContainerGroupShareInput) {\n return loadVerifiedGroupSharePrincipalPolicy({\n apiClient: input.apiClient,\n execSql: input.execSql,\n expectedGroupName: input.expectedGroupName ?? undefined,\n readEncryptedName:\n input.readEncryptedName ??\n createGroupMetadataAccess({\n ...input,\n organizationId: input.author.organizationId,\n verifyMetadataContainer: createGroupMetadataContainerVerifier({\n ...input,\n organizationId: input.author.organizationId,\n stillCurrent: input.stillCurrent ?? (() => true),\n }),\n }).readName,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n}\n\nexport async function shareRemoteContainerWithGroup(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (input.stillCurrent?.() === false) return null;\n await input.apiClient.recoverPendingPrincipalMutation?.(\n input.author.organizationId,\n );\n if (input.stillCurrent?.() === false) return null;\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n const verifiedPrincipalPolicy = await loadShareGroupPolicy(input);\n if (input.stillCurrent?.() === false) return null;\n await advanceVerifiedSharePolicies(\n input.execSql,\n verifiedPrincipalPolicy,\n input.stillCurrent,\n );\n if (input.stillCurrent?.() === false) return null;\n\n const signedGrant = verifiedPrincipalPolicy.policy.grants.find(\n (grant) => grant.containerId === input.containerId,\n );\n if (!signedGrant || signedGrant.accessLevel !== input.accessLevel) {\n assertGrantMintNamed(input.expectedGroupName);\n return commitMissingGroupGrant(input);\n }\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n principalPolicyCache: principalPolicyCacheForVerifiedPolicies(\n verifiedPrincipalPolicy.checkpointPolicies,\n ),\n previousProjection,\n recipient: {\n principalPolicy: verifiedPrincipalPolicy.policy,\n subjectId: input.recipientGroupId,\n subjectType: \"group\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n const result = await submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: verifiedPrincipalPolicy.checkpointPolicies,\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n if (!result) return null;\n\n // Keep the previously cached group epoch available until the old container\n // wrap has been unwrapped and the replacement has committed. Root has no\n // parent fallback, so caching the rotated policy any earlier destroys the\n // only local path to the KEK that must be re-wrapped.\n if (input.stillCurrent?.() !== false) {\n await savePrincipalPolicyBundle(\n input.execSql,\n verifiedPrincipalPolicy.bundle,\n new Date().toISOString(),\n input.author.organizationId,\n { stillCurrent: input.stillCurrent },\n );\n }\n if (input.stillCurrent?.() === false) return null;\n\n return result;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"share.js","sourceRoot":"","sources":["share.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ContainerAccessLevel,\n SigningKeyPair,\n VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type {\n ContainerMutationResponse,\n ContainerWriterProjectionResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport type {\n ContainerMutationAuthor,\n ContainerShareApi,\n ContainerSharePlan,\n MaterializedContainerSharePlan,\n} from \"../../../data/containers/shared/types\";\nimport {\n isProjectionVerificationCancelledError,\n nullOnProjectionVerificationCancellation,\n type ProjectionUserKeyResolver,\n type ReferencedPrincipalPolicyWarmer,\n requireProjectionUserKeyResolver,\n} from \"../../../data/keyingProjectionVerification\";\nimport { principalPolicyCacheForVerifiedPolicies } from \"../../../data/keyingProjectionVerification/principalPolicyCache\";\nimport { savePrincipalPolicyBundle } from \"../../../data/persistence/principalPolicyPersistence\";\nimport type { SecurityIncidentReporter } from \"../../../data/securityIncidents\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n requireTrustedUserIdentityResolver,\n type TrustedUserIdentityResolver,\n} from \"../../../data/trustedUserIdentity\";\nimport { createGroupMetadataAccess } from \"../../organizations/groupMetadataAccess\";\nimport { createGroupMetadataContainerVerifier } from \"../../organizations/groupMetadataContainerAuthority\";\nimport { preparePrincipalContainerRematerializationBatch } from \"../../organizations/principalContainerRematerialization\";\nimport { setOrganizationGroupContainerGrant } from \"../../organizations/principalPolicy\";\nimport type { GroupPolicyNameReader } from \"../../organizations/principalPolicyRequest\";\nimport {\n submitAcknowledgedContainerMutation,\n submitPlainContainerMutation,\n} from \"./mutationSubmit\";\nimport { buildMaterializedContainerSharePlan } from \"./shareMaterialization\";\nimport {\n advanceVerifiedSharePolicies,\n type ContainerManagedPrincipalShareApi,\n loadVerifiedGroupSharePrincipalPolicy,\n} from \"./sharePrincipalPolicy\";\nimport { resolveShareProjection } from \"./shareProjection\";\n\nclass ContainerShareGenerationExpiredError extends Error {}\n\nasync function buildCurrentContainerSharePlan(\n input: Parameters<typeof buildMaterializedContainerSharePlan>[0],\n): Promise<MaterializedContainerSharePlan | null> {\n return nullOnProjectionVerificationCancellation(() =>\n buildMaterializedContainerSharePlan(input),\n );\n}\n\nexport async function shareRemoteContainer(input: {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientUserId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}): Promise<{\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n} | null> {\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const resolveTrustedUserIdentity = requireTrustedUserIdentityResolver(\n input.resolveTrustedUserIdentity,\n );\n const recipientIdentity = await resolveTrustedUserIdentity(\n input.recipientUserId,\n );\n if (!recipientIdentity || input.stillCurrent?.() === false) {\n return null;\n }\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n previousProjection,\n recipient: {\n recipientEncapsulationPublicKey: recipientIdentity.encapsulationPublicKey,\n subjectId: input.recipientUserId,\n subjectType: \"user\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n return submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: [],\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n}\n\ninterface RemoteContainerGroupShareInput {\n reportSecurityIncident: SecurityIncidentReporter;\n accessLevel: ContainerAccessLevel;\n apiClient: ContainerManagedPrincipalShareApi;\n author: ContainerMutationAuthor;\n containerId: string;\n eventId?: string | undefined;\n execSql: ExecSql;\n /**\n * The display name the user chose the group by, checked against the name\n * committed in the verified group policy so a relabeled read-model row\n * cannot redirect the share onto another group. `null` is reserved for the\n * grant-preserving re-wrap: a share that would mint a new grant without a\n * name is refused.\n */\n expectedGroupName: string | null;\n readEncryptedName?: GroupPolicyNameReader | undefined;\n knownContainerKeks?: ReadonlyMap<string, Uint8Array> | undefined;\n previousProjection?: ContainerWriterProjectionResponse | undefined;\n recipientGroupId: string;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n signedAt?: string | undefined;\n signingKeyPair?: SigningKeyPair | null | undefined;\n stillCurrent?: (() => boolean) | undefined;\n targetSecretKey: Uint8Array;\n warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;\n}\n\ninterface RemoteContainerGroupShareResult {\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n response: ContainerMutationResponse;\n}\n\nfunction isMaterializedContainerSharePlan(\n value: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >[\"plans\"][number],\n): value is MaterializedContainerSharePlan {\n return value.plan.body.eventType === \"container.grant\";\n}\n\nasync function prepareMissingGroupGrantMutations(input: {\n currentPolicy: PrincipalPolicyBundleResponse;\n nextPolicy: VerifiedPrincipalPolicy;\n shareInput: RemoteContainerGroupShareInput;\n}) {\n const { currentPolicy, nextPolicy, shareInput } = input;\n return preparePrincipalContainerRematerializationBatch({\n reportSecurityIncident: shareInput.reportSecurityIncident,\n apiClient: shareInput.apiClient,\n author: shareInput.author,\n execSql: shareInput.execSql,\n grants: [\n ...new Map(\n [...currentPolicy.currentGrants, ...nextPolicy.grants].map(\n (grant) => [grant.containerId, grant] as const,\n ),\n ).values(),\n ],\n groupId: shareInput.recipientGroupId,\n nextPolicy,\n resolveTrustedUserIdentity: shareInput.resolveTrustedUserIdentity,\n stillCurrent: shareInput.stillCurrent,\n targetSecretKey: shareInput.targetSecretKey,\n warmReferencedPrincipalPolicies: shareInput.warmReferencedPrincipalPolicies,\n });\n}\n\nasync function commitMissingGroupGrantPolicy(\n input: RemoteContainerGroupShareInput,\n): Promise<{\n preparedTarget: Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >;\n storedPolicy: Awaited<ReturnType<typeof setOrganizationGroupContainerGrant>>;\n} | null> {\n const signingKeyPair = input.signingKeyPair;\n if (!signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n const policyApi = {\n recoverPendingPrincipalMutation:\n input.apiClient.recoverPendingPrincipalMutation?.bind(input.apiClient),\n commitOrganizationGroupPolicy:\n input.apiClient.commitOrganizationGroupPolicy.bind(input.apiClient),\n getCurrentPrincipalPolicy: input.apiClient.getCurrentPrincipalPolicy.bind(\n input.apiClient,\n ),\n };\n let preparedTarget:\n | Awaited<\n ReturnType<typeof preparePrincipalContainerRematerializationBatch>\n >\n | undefined;\n try {\n const storedPolicy = await setOrganizationGroupContainerGrant({\n accessLevel: input.accessLevel,\n apiClient: policyApi,\n assertCanCommit: () => {\n if (input.stillCurrent?.() === false) {\n throw new ContainerShareGenerationExpiredError();\n }\n },\n containerId: input.containerId,\n execSql: input.execSql,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n prepareContainerMutations: async ({ currentPolicy, nextPolicy }) => {\n preparedTarget = await prepareMissingGroupGrantMutations({\n currentPolicy,\n nextPolicy,\n shareInput: input,\n });\n return preparedTarget;\n },\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n signerUserId: input.author.signerUserId,\n signingFingerprint: input.author.signerKeyFingerprint,\n signingKeyPair,\n });\n if (!preparedTarget) {\n throw new Error(\"Container group share preparation is incomplete\");\n }\n return { preparedTarget, storedPolicy };\n } catch (error) {\n if (\n error instanceof ContainerShareGenerationExpiredError ||\n isProjectionVerificationCancelledError(error)\n ) {\n return null;\n }\n throw error;\n }\n}\n\nasync function commitMissingGroupGrant(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (!input.signingKeyPair) {\n throw new Error(\n \"Container group share requires principal policy signing context\",\n );\n }\n if (input.stillCurrent?.() === false) return null;\n const committed = await commitMissingGroupGrantPolicy(input);\n if (!committed) return null;\n const { preparedTarget, storedPolicy } = committed;\n const targetIndex = preparedTarget?.plans.findIndex(\n (planned) => planned.plan.containerId === input.containerId,\n );\n const response =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : storedPolicy.containerMutations[targetIndex];\n const targetPlan =\n targetIndex === undefined || targetIndex < 0\n ? undefined\n : preparedTarget?.plans[targetIndex];\n if (\n !targetPlan ||\n !response ||\n !isMaterializedContainerSharePlan(targetPlan)\n ) {\n throw new Error(\"Container group share acknowledgement is incomplete\");\n }\n return {\n containerKey: targetPlan.containerKey,\n plan: targetPlan.plan,\n response,\n };\n}\n\n// Only a re-wrap of an existing signed grant may run without the chosen name;\n// minting a grant is exactly the operation the name binding protects.\nfunction assertGrantMintNamed(expectedGroupName: string | null): void {\n if (expectedGroupName === null) {\n throw new Error(\n \"Minting a group grant requires the chosen group name; only a re-wrap of an existing signed grant may omit it\",\n );\n }\n}\n\nfunction loadShareGroupPolicy(input: RemoteContainerGroupShareInput) {\n return loadVerifiedGroupSharePrincipalPolicy({\n apiClient: input.apiClient,\n execSql: input.execSql,\n expectedGroupName: input.expectedGroupName ?? undefined,\n readEncryptedName:\n input.readEncryptedName ??\n createGroupMetadataAccess({\n ...input,\n organizationId: input.author.organizationId,\n verifyMetadataContainer: createGroupMetadataContainerVerifier({\n ...input,\n organizationId: input.author.organizationId,\n stillCurrent: input.stillCurrent ?? (() => true),\n }),\n }).readName,\n groupId: input.recipientGroupId,\n organizationId: input.author.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n}\n\nexport async function shareRemoteContainerWithGroup(\n input: RemoteContainerGroupShareInput,\n): Promise<RemoteContainerGroupShareResult | null> {\n if (input.stillCurrent?.() === false) return null;\n await input.apiClient.recoverPendingPrincipalMutation?.(\n input.author.organizationId,\n );\n if (input.stillCurrent?.() === false) return null;\n const resolveProjectionUserKey = requireProjectionUserKeyResolver(\n input.resolveProjectionUserKey,\n \"Remote container share\",\n );\n const previousProjection = await resolveShareProjection(\n input,\n resolveProjectionUserKey,\n );\n if (!previousProjection) return null;\n const verifiedPrincipalPolicy = await loadShareGroupPolicy(input);\n if (input.stillCurrent?.() === false) return null;\n await advanceVerifiedSharePolicies(\n input.execSql,\n verifiedPrincipalPolicy,\n input.stillCurrent,\n );\n if (input.stillCurrent?.() === false) return null;\n\n const signedGrant = verifiedPrincipalPolicy.policy.grants.find(\n (grant) => grant.containerId === input.containerId,\n );\n if (!signedGrant || signedGrant.accessLevel !== input.accessLevel) {\n assertGrantMintNamed(input.expectedGroupName);\n return commitMissingGroupGrant(input);\n }\n\n const materializedPlan = await buildCurrentContainerSharePlan({\n accessLevel: input.accessLevel,\n author: input.author,\n eventId: input.eventId,\n execSql: input.execSql,\n knownContainerKeks: input.knownContainerKeks,\n principalPolicyCache: principalPolicyCacheForVerifiedPolicies(\n verifiedPrincipalPolicy.checkpointPolicies,\n ),\n previousProjection,\n recipient: {\n principalPolicy: verifiedPrincipalPolicy.policy,\n subjectId: input.recipientGroupId,\n subjectType: \"group\",\n },\n resolveProjectionUserKey,\n signedAt: input.signedAt,\n stillCurrent: input.stillCurrent,\n targetSecretKey: input.targetSecretKey,\n warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,\n });\n if (!materializedPlan) return null;\n const result = await submitAcknowledgedContainerMutation({\n reportSecurityIncident: input.reportSecurityIncident,\n recitationPolicies: verifiedPrincipalPolicy.checkpointPolicies,\n apiClient: input.apiClient,\n author: input.author,\n containerKey: materializedPlan.containerKey,\n execSql: input.execSql,\n plan: materializedPlan.plan,\n stillCurrent: input.stillCurrent,\n submit: () =>\n submitPlainContainerMutation(() =>\n input.apiClient.shareContainer(\n input.containerId,\n materializedPlan.plan.request,\n {\n expectedPaymentRequiredOrganizationId: input.author.organizationId,\n },\n ),\n ),\n });\n if (!result) return null;\n\n // Keep the previously cached group epoch available until the old container\n // wrap has been unwrapped and the replacement has committed. Root has no\n // parent fallback, so caching the rotated policy any earlier destroys the\n // only local path to the KEK that must be re-wrapped.\n if (input.stillCurrent?.() !== false) {\n await savePrincipalPolicyBundle(\n input.execSql,\n verifiedPrincipalPolicy.bundle,\n new Date().toISOString(),\n input.author.organizationId,\n { stillCurrent: input.stillCurrent },\n );\n }\n if (input.stillCurrent?.() === false) return null;\n\n return result;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { projectionWithCurrentAncestors } from "./shareAncestorRepair.js";
|
|
2
|
+
/** The container's projection, with any lazily stale chain above it repaired. */
|
|
3
|
+
export async function resolveShareProjection(input, resolveProjectionUserKey) {
|
|
4
|
+
const servedProjection = input.previousProjection ??
|
|
5
|
+
(await input.apiClient.getContainerWriterProjection(input.containerId));
|
|
6
|
+
if (!servedProjection || input.stillCurrent?.() === false)
|
|
7
|
+
return null;
|
|
8
|
+
const previousProjection = await projectionWithCurrentAncestors({
|
|
9
|
+
...input,
|
|
10
|
+
previousProjection: servedProjection,
|
|
11
|
+
resolveProjectionUserKey,
|
|
12
|
+
});
|
|
13
|
+
return input.stillCurrent?.() === false ? null : previousProjection;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=shareProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shareProjection.js","sourceRoot":"","sources":["shareProjection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAEvE,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,KAG0E,EAC1E,wBAAmD;IAEnD,MAAM,gBAAgB,GACpB,KAAK,CAAC,kBAAkB;QACxB,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,4BAA4B,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1E,IAAI,CAAC,gBAAgB,IAAI,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACvE,MAAM,kBAAkB,GAAG,MAAM,8BAA8B,CAAC;QAC9D,GAAG,KAAK;QACR,kBAAkB,EAAE,gBAAgB;QACpC,wBAAwB;KACzB,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,YAAY,EAAE,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACtE,CAAC","sourcesContent":["import type { ContainerWriterProjectionResponse } from \"@tearleads/validators/response\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport { projectionWithCurrentAncestors } from \"./shareAncestorRepair\";\n\n/** The container's projection, with any lazily stale chain above it repaired. */\nexport async function resolveShareProjection(\n input: Omit<\n Parameters<typeof projectionWithCurrentAncestors>[0],\n \"previousProjection\" | \"resolveProjectionUserKey\"\n > & { previousProjection?: ContainerWriterProjectionResponse | undefined },\n resolveProjectionUserKey: ProjectionUserKeyResolver,\n): Promise<ContainerWriterProjectionResponse | null> {\n const servedProjection =\n input.previousProjection ??\n (await input.apiClient.getContainerWriterProjection(input.containerId));\n if (!servedProjection || input.stillCurrent?.() === false) return null;\n const previousProjection = await projectionWithCurrentAncestors({\n ...input,\n previousProjection: servedProjection,\n resolveProjectionUserKey,\n });\n return input.stillCurrent?.() === false ? null : previousProjection;\n}\n"]}
|
|
@@ -29,6 +29,8 @@ export declare function createVerifiedRemoteDocumentDeletionHandler(input: {
|
|
|
29
29
|
readonly documentId: string;
|
|
30
30
|
}) => Promise<void> | void;
|
|
31
31
|
readonly resolveProjectionUserKey: ProjectionUserKeyResolver;
|
|
32
|
+
readonly stillCurrent?: (() => boolean) | undefined;
|
|
33
|
+
readonly warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;
|
|
32
34
|
}): (deleted: {
|
|
33
35
|
readonly documentId: string;
|
|
34
36
|
}) => Promise<void>;
|
|
@@ -41,6 +43,7 @@ export declare function purgeRemoteDocument(input: {
|
|
|
41
43
|
readonly commitPurgeProof: (transactionExecSql: ExecSql) => Promise<void>;
|
|
42
44
|
}) => Promise<void> | void;
|
|
43
45
|
readonly resolveProjectionUserKey: ProjectionUserKeyResolver;
|
|
46
|
+
readonly stillCurrent?: (() => boolean) | undefined;
|
|
44
47
|
readonly warmReferencedPrincipalPolicies?: ReferencedPrincipalPolicyWarmer | undefined;
|
|
45
48
|
}): Promise<DocumentPurgeResponse | null>;
|
|
46
49
|
export {};
|
|
@@ -26,6 +26,8 @@ async function loadAuthenticatedDocumentPurgeProof(input) {
|
|
|
26
26
|
expectedOrganizationId: input.expectedOrganizationId,
|
|
27
27
|
proof: initialProof,
|
|
28
28
|
resolveUserKey: input.resolveProjectionUserKey,
|
|
29
|
+
stillCurrent: input.stillCurrent,
|
|
30
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
29
31
|
});
|
|
30
32
|
// The current API returns complete history to recorded readers. Otherwise
|
|
31
33
|
// its terminal snapshot needs an exact local pin; a floor refetch cannot
|
|
@@ -105,6 +107,8 @@ export function createVerifiedRemoteDocumentDeletionHandler(input) {
|
|
|
105
107
|
execSql: input.execSql,
|
|
106
108
|
expectedOrganizationId: input.expectedOrganizationId,
|
|
107
109
|
resolveProjectionUserKey: input.resolveProjectionUserKey,
|
|
110
|
+
stillCurrent: input.stillCurrent,
|
|
111
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
108
112
|
});
|
|
109
113
|
if (!proof) {
|
|
110
114
|
throw new ProjectionDependencyUnavailableError("Remote document deletion is missing its signed purge proof");
|
|
@@ -115,6 +119,8 @@ export function createVerifiedRemoteDocumentDeletionHandler(input) {
|
|
|
115
119
|
expectedOrganizationId: input.expectedOrganizationId,
|
|
116
120
|
proof,
|
|
117
121
|
resolveUserKey: input.resolveProjectionUserKey,
|
|
122
|
+
stillCurrent: input.stillCurrent,
|
|
123
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
118
124
|
});
|
|
119
125
|
await input.onVerifiedDeletion({
|
|
120
126
|
commitPurgeProof: verified.commitCheckpoints,
|
|
@@ -137,6 +143,8 @@ export async function purgeRemoteDocument(input) {
|
|
|
137
143
|
execSql: input.execSql,
|
|
138
144
|
expectedOrganizationId: input.author.organizationId,
|
|
139
145
|
resolveProjectionUserKey: input.resolveProjectionUserKey,
|
|
146
|
+
stillCurrent: input.stillCurrent,
|
|
147
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
140
148
|
});
|
|
141
149
|
if (!proof) {
|
|
142
150
|
throw new ProjectionDependencyUnavailableError("Purged remote document is missing its signed purge proof");
|
|
@@ -147,6 +155,8 @@ export async function purgeRemoteDocument(input) {
|
|
|
147
155
|
expectedOrganizationId: input.author.organizationId,
|
|
148
156
|
proof,
|
|
149
157
|
resolveUserKey: input.resolveProjectionUserKey,
|
|
158
|
+
stillCurrent: input.stillCurrent,
|
|
159
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
150
160
|
});
|
|
151
161
|
await input.onVerifiedPurge({
|
|
152
162
|
commitPurgeProof: verified.commitCheckpoints,
|
|
@@ -157,6 +167,7 @@ export async function purgeRemoteDocument(input) {
|
|
|
157
167
|
execSql: input.execSql,
|
|
158
168
|
projection: writerProjection,
|
|
159
169
|
resolveUserKey: input.resolveProjectionUserKey,
|
|
170
|
+
stillCurrent: input.stillCurrent,
|
|
160
171
|
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
161
172
|
});
|
|
162
173
|
const request = await buildDocumentPurgeRequest({
|
|
@@ -175,6 +186,8 @@ export async function purgeRemoteDocument(input) {
|
|
|
175
186
|
expectedOrganizationId: input.author.organizationId,
|
|
176
187
|
proof: response,
|
|
177
188
|
resolveUserKey: input.resolveProjectionUserKey,
|
|
189
|
+
stillCurrent: input.stillCurrent,
|
|
190
|
+
warmReferencedPrincipalPolicies: input.warmReferencedPrincipalPolicies,
|
|
178
191
|
});
|
|
179
192
|
await input.onVerifiedPurge({
|
|
180
193
|
commitPurgeProof: verified.commitCheckpoints,
|