@tearleads/client-sdk 0.1.54 → 0.1.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/containers/shared/types.d.ts +1 -2
- package/data/containers/shared/types.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/container-state/types.js.map +1 -1
- package/workflows/container-contents/remoteHydration/types.d.ts +5 -4
- package/workflows/container-contents/remoteHydration/types.js.map +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js +5 -8
- package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -1
- package/workflows/containers/child/sharePrincipalPolicy.d.ts +3 -3
- package/workflows/containers/child/sharePrincipalPolicy.js +1 -1
- package/workflows/containers/child/sharePrincipalPolicy.js.map +1 -1
- package/workflows/organizations/currentOrganizationMutationRetention.js +1 -1
- package/workflows/organizations/currentOrganizationMutationRetention.js.map +1 -1
- package/workflows/organizations/currentPrincipalMutationLease.js +5 -4
- package/workflows/organizations/currentPrincipalMutationLease.js.map +1 -1
- package/workflows/organizations/deleteOrganizationGroup.js +1 -1
- package/workflows/organizations/deleteOrganizationGroup.js.map +1 -1
- package/workflows/organizations/groupCreation.js +1 -1
- package/workflows/organizations/groupCreation.js.map +1 -1
- package/workflows/organizations/groupNameUniqueness.js.map +1 -1
- package/workflows/organizations/groupPolicyMutationContext.js +1 -1
- package/workflows/organizations/groupPolicyMutationContext.js.map +1 -1
- package/workflows/organizations/organizationGroupNamePolicies.js +19 -5
- package/workflows/organizations/organizationGroupNamePolicies.js.map +1 -1
- package/workflows/organizations/principalPolicyApi.d.ts +3 -3
- package/workflows/organizations/principalPolicyApi.js.map +1 -1
- package/workflows/organizations/runtimeCurrentGroupMutation.js +4 -4
- package/workflows/organizations/runtimeCurrentGroupMutation.js.map +1 -1
- package/workflows/organizations/runtimeCurrentOrganizationMutation.js +2 -2
- package/workflows/organizations/runtimeCurrentOrganizationMutation.js.map +1 -1
- package/workflows/principals/currentPrincipalPolicyReader.d.ts +12 -0
- package/workflows/principals/currentPrincipalPolicyReader.js +2 -0
- package/workflows/principals/currentPrincipalPolicyReader.js.map +1 -0
- package/workflows/principals/externalAdminPolicy.d.ts +2 -1
- package/workflows/principals/externalAdminPolicy.js +3 -3
- package/workflows/principals/externalAdminPolicy.js.map +1 -1
- package/workflows/principals/policyCache.d.ts +3 -2
- package/workflows/principals/policyCache.js +9 -9
- package/workflows/principals/policyCache.js.map +1 -1
- package/workflows/principals/principalHistoryRecoveryTypes.d.ts +3 -2
- package/workflows/principals/principalHistoryRecoveryTypes.js.map +1 -1
- package/workflows/principals/principalPolicyHistoryReader.d.ts +20 -0
- package/workflows/principals/principalPolicyHistoryReader.js +13 -0
- package/workflows/principals/principalPolicyHistoryReader.js.map +1 -0
- package/workflows/principals/principalPolicyOrganizationScope.js +1 -1
- package/workflows/principals/principalPolicyOrganizationScope.js.map +1 -1
- package/workflows/principals/principalRecoveryDirectory.js +6 -6
- package/workflows/principals/principalRecoveryDirectory.js.map +1 -1
- package/workflows/principals/principalRecoveryDiscoveryPage.js +4 -4
- package/workflows/principals/principalRecoveryDiscoveryPage.js.map +1 -1
- package/workflows/principals/publicPrincipalHistoryTypes.d.ts +2 -2
- package/workflows/principals/publicPrincipalHistoryTypes.js.map +1 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js +1 -1
- package/workflows/principals/recoverPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/recoverPublicPrincipalHistory.js +1 -1
- package/workflows/principals/recoverPublicPrincipalHistory.js.map +1 -1
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js +1 -1
- package/workflows/principals/recoverScopedPrincipalPolicyHistory.js.map +1 -1
- package/workflows/principals/runtimePolicyRecovery.js +4 -3
- package/workflows/principals/runtimePolicyRecovery.js.map +1 -1
- package/workflows/principals/runtimeProjectionPolicyRecovery.js +4 -3
- package/workflows/principals/runtimeProjectionPolicyRecovery.js.map +1 -1
- package/workflows/registration/provisionedPrincipalHistory.js +1 -1
- package/workflows/registration/provisionedPrincipalHistory.js.map +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AccessEvent, AccessManifest, ContainerAccessManifestState, ContainerCreateAccessEventBody, ContainerDirectGrant, ContainerGrantAccessEventBody, ContainerGrantPrincipalHead, ContainerKekKeyring, ContainerKekRecipientTarget, ContainerKeyEpoch, ContainerKeyWrap, ContainerMoveAccessEventBody, ContainerRekeyAccessEventBody, ContainerRevokeAccessEventBody, ContainerUserRecipientKey } from "../../../internal/crypto/index.js";
|
|
2
2
|
import type { AccessManifestBundleWire, ContainerCreateWithMetadataDocumentRequest, ContainerMutationRequest, ContainerRotationRequest } from "../../../internal/validators/request/index.js";
|
|
3
|
-
import type { ContainerCreateWithMetadataDocumentResponse, ContainerKekResponse, ContainerMutationResponse, ContainerRotationResponse, ContainerWriterProjectionResponse,
|
|
3
|
+
import type { ContainerCreateWithMetadataDocumentResponse, ContainerKekResponse, ContainerMutationResponse, ContainerRotationResponse, ContainerWriterProjectionResponse, ReferencedPrincipalStateResponse } from "../../../internal/validators/response/index.js";
|
|
4
4
|
import type { PrincipalPolicyCurrentEvidence } from "../../principals/principalPolicyEvidence.js";
|
|
5
5
|
import type { ExecSql } from "../../sqlite/sqlSchema.js";
|
|
6
6
|
import type { ContainerMutationRequestOptions } from "./mutationRequestOptions.js";
|
|
@@ -87,7 +87,6 @@ export interface ContainerCreateApi {
|
|
|
87
87
|
createContainerWithMetadataDocumentResult(input: ContainerCreateWithMetadataDocumentRequest, options?: ContainerMutationRequestOptions): Promise<ContainerMutationSubmitResult<ContainerCreateWithMetadataDocumentResponse>>;
|
|
88
88
|
evictContainerWriterProjection(containerId: string): void;
|
|
89
89
|
getContainerWriterProjection(containerId: string): Promise<ContainerWriterProjectionResponse | null>;
|
|
90
|
-
getCurrentPrincipalPolicy(principalType: "group" | "organization", principalId: string): Promise<PrincipalPolicyBundleResponse | null>;
|
|
91
90
|
}
|
|
92
91
|
export interface ContainerShareApi extends ContainerReciteApi {
|
|
93
92
|
getContainerWriterProjection(containerId: string): Promise<ContainerWriterProjectionResponse | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccessEvent,\n AccessManifest,\n ContainerAccessManifestState,\n ContainerCreateAccessEventBody,\n ContainerDirectGrant,\n ContainerGrantAccessEventBody,\n ContainerGrantPrincipalHead,\n ContainerKekKeyring,\n ContainerKekRecipientTarget,\n ContainerKeyEpoch,\n ContainerKeyWrap,\n ContainerMoveAccessEventBody,\n ContainerRekeyAccessEventBody,\n ContainerRevokeAccessEventBody,\n ContainerUserRecipientKey,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWire,\n ContainerCreateWithMetadataDocumentRequest,\n ContainerMutationRequest,\n ContainerRotationRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n ContainerCreateWithMetadataDocumentResponse,\n ContainerKekResponse,\n ContainerMutationResponse,\n ContainerRotationResponse,\n ContainerWriterProjectionResponse,\n PrincipalPolicyBundleResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport type { ContainerMutationRequestOptions } from \"./mutationRequestOptions\";\nimport type { ContainerReciteApi } from \"./reciteApi\";\n\nexport interface ContainerMutationAuthor {\n organizationId: string;\n signerDeviceId: string;\n signerKeyFingerprint: string;\n signerPrivateKey: Uint8Array;\n signerUserId: string;\n}\n\nexport interface BuildContainerCreatePlanInput {\n author: ContainerMutationAuthor;\n containerId?: string | undefined;\n containerKey: Uint8Array;\n containerKeyEpochId?: string | undefined;\n eventId?: string | undefined;\n /**\n * Optional group grant to bake into the\n * create manifest, wrapping the new container key to that principal in\n * addition to the normal parent-inheritance wrap. Used to birth a child\n * container that is directly readable by a group — e.g. the org public\n * metadata container granted to the reserved Members group. The principal's\n * verified policy must also be supplied via `principalPolicies` so the server\n * can derive the recipient target.\n */\n managedPrincipalGrant?:\n | {\n accessLevel: ContainerDirectGrant[\"accessLevel\"];\n principalEncapsulationPublicKey: string;\n principalHead: ContainerGrantPrincipalHead;\n }\n | undefined;\n metadataDocumentId?: string | undefined;\n systemSlot?: string | null | undefined;\n parentProjection: ContainerWriterProjectionResponse;\n principalPolicies?: readonly PrincipalPolicyCurrentEvidence[] | undefined;\n signedAt?: string | undefined;\n}\n\nexport interface ContainerCreatePlan {\n body: ContainerCreateAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyEpochHash: string;\n keyTargetHash: string;\n manifest: AccessManifest;\n manifestHash: string;\n metadataDocumentId: string;\n parentContainerId: string | null;\n parentManifestHash: string | null;\n recipientTargets: ContainerKekRecipientTarget[];\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerCreatePlan {\n containerKey: Uint8Array;\n plan: ContainerCreatePlan;\n}\n\nexport interface ContainerCreatePlanContext\n extends BuildContainerCreatePlanInput {\n containerKeyPublicKey: string;\n containerId: string;\n containerKeyEpochId: string;\n eventId: string;\n metadataDocumentId: string;\n parent: ParentContainerCreateContext;\n signedAt: string;\n}\n\nexport interface ContainerMutationSubmitFailure {\n readonly code?: string | undefined;\n readonly message: string;\n readonly ok: false;\n readonly report: () => void;\n readonly stalePrincipalHeads?:\n | readonly ReferencedPrincipalStateResponse[]\n | undefined;\n readonly status: number | null;\n}\n\nexport type ContainerMutationSubmitResult<T> =\n | {\n readonly data: T;\n readonly ok: true;\n }\n | ContainerMutationSubmitFailure;\n\nexport interface ContainerCreateApi {\n createContainerResult(\n input: ContainerMutationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerMutationSubmitResult<ContainerMutationResponse>>;\n createContainerWithMetadataDocumentResult(\n input: ContainerCreateWithMetadataDocumentRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<\n ContainerMutationSubmitResult<ContainerCreateWithMetadataDocumentResponse>\n >;\n evictContainerWriterProjection(containerId: string): void;\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n getCurrentPrincipalPolicy(\n principalType: \"group\" | \"organization\",\n principalId: string,\n ): Promise<PrincipalPolicyBundleResponse | null>;\n}\n\nexport interface ContainerShareApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n shareContainer(\n containerId: string,\n input: ContainerMutationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerMutationResponse | null>;\n}\n\n/**\n * A status-bearing rotation outcome. A refusal that names\n * `requiredContainerIds` is answerable: sign those descendant rekeys and\n * resubmit with them carried.\n */\nexport type ContainerRotationResult =\n | { readonly ok: true; readonly data: ContainerRotationResponse }\n | {\n readonly ok: false;\n readonly code?: string | undefined;\n /** Surface a failure that was submitted with `reportErrors: false`. */\n readonly report?: (() => void) | undefined;\n readonly requiredContainerIds?: readonly string[] | undefined;\n readonly status: number | null;\n };\n\nexport interface ContainerMoveApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n moveContainer(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResponse | null>;\n /** Optional status-bearing variant; without it nothing can be carried. */\n moveContainerResult?(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResult>;\n}\n\nexport interface ContainerRevokeApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n revokeContainer(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResponse | null>;\n /** Optional status-bearing variant; without it nothing can be carried. */\n revokeContainerResult?(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResult>;\n}\n\nexport interface CreateRemoteContainerResult {\n containerKey: Uint8Array;\n containerId: string;\n metadataDocumentId: string;\n plan: ContainerCreatePlan;\n response: ContainerMutationResponse;\n}\n\nexport interface ContainerSharePlan {\n body: ContainerGrantAccessEventBody;\n /** The unchanged epoch's stored keyring, echoed back by the server. */\n previousKeyring?: Record<string, unknown> | null | undefined;\n containerId: string;\n event: AccessEvent;\n eventHash: string;\n grant: ContainerDirectGrant;\n keyEpoch: ContainerKeyEpoch;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n recipientTarget: ContainerKekRecipientTarget;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerSharePlan {\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n}\n\nexport interface ContainerRevokePlan {\n body: ContainerRevokeAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerRevokePlan {\n containerKey: Uint8Array;\n plan: ContainerRevokePlan;\n}\n\nexport interface ContainerRekeyPlan {\n body: ContainerRekeyAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerRekeyPlan {\n containerKey: Uint8Array;\n plan: ContainerRekeyPlan;\n writerProjection: ContainerWriterProjectionResponse;\n}\n\nexport interface ContainerRekeyApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n rekeyContainer(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResponse | null>;\n /** Optional status-bearing variant; see DocumentSyncApi. */\n rekeyContainerResult?(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResult>;\n}\n\nexport interface ContainerMovePlan {\n body: ContainerMoveAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerMovePlan {\n containerKey: Uint8Array;\n plan: ContainerMovePlan;\n}\n\nexport interface BuildMaterializedContainerMovePlanInput {\n author: ContainerMutationAuthor;\n containerKeyEpochId?: string | undefined;\n destinationParentProjection: ContainerWriterProjectionResponse;\n eventId?: string | undefined;\n execSql: ExecSql;\n previousProjection: ContainerWriterProjectionResponse;\n signedAt?: string | undefined;\n targetSecretKey: Uint8Array;\n}\n\nexport interface ParentContainerCreateContext {\n manifest: ContainerWriterProjectionResponse[\"path\"][number];\n kek: ContainerKekResponse;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n AccessEvent,\n AccessManifest,\n ContainerAccessManifestState,\n ContainerCreateAccessEventBody,\n ContainerDirectGrant,\n ContainerGrantAccessEventBody,\n ContainerGrantPrincipalHead,\n ContainerKekKeyring,\n ContainerKekRecipientTarget,\n ContainerKeyEpoch,\n ContainerKeyWrap,\n ContainerMoveAccessEventBody,\n ContainerRekeyAccessEventBody,\n ContainerRevokeAccessEventBody,\n ContainerUserRecipientKey,\n} from \"@tearleads/crypto\";\nimport type {\n AccessManifestBundleWire,\n ContainerCreateWithMetadataDocumentRequest,\n ContainerMutationRequest,\n ContainerRotationRequest,\n} from \"@tearleads/validators/request\";\nimport type {\n ContainerCreateWithMetadataDocumentResponse,\n ContainerKekResponse,\n ContainerMutationResponse,\n ContainerRotationResponse,\n ContainerWriterProjectionResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { PrincipalPolicyCurrentEvidence } from \"../../principals/principalPolicyEvidence\";\nimport type { ExecSql } from \"../../sqlite/sqlSchema\";\nimport type { ContainerMutationRequestOptions } from \"./mutationRequestOptions\";\nimport type { ContainerReciteApi } from \"./reciteApi\";\n\nexport interface ContainerMutationAuthor {\n organizationId: string;\n signerDeviceId: string;\n signerKeyFingerprint: string;\n signerPrivateKey: Uint8Array;\n signerUserId: string;\n}\n\nexport interface BuildContainerCreatePlanInput {\n author: ContainerMutationAuthor;\n containerId?: string | undefined;\n containerKey: Uint8Array;\n containerKeyEpochId?: string | undefined;\n eventId?: string | undefined;\n /**\n * Optional group grant to bake into the\n * create manifest, wrapping the new container key to that principal in\n * addition to the normal parent-inheritance wrap. Used to birth a child\n * container that is directly readable by a group — e.g. the org public\n * metadata container granted to the reserved Members group. The principal's\n * verified policy must also be supplied via `principalPolicies` so the server\n * can derive the recipient target.\n */\n managedPrincipalGrant?:\n | {\n accessLevel: ContainerDirectGrant[\"accessLevel\"];\n principalEncapsulationPublicKey: string;\n principalHead: ContainerGrantPrincipalHead;\n }\n | undefined;\n metadataDocumentId?: string | undefined;\n systemSlot?: string | null | undefined;\n parentProjection: ContainerWriterProjectionResponse;\n principalPolicies?: readonly PrincipalPolicyCurrentEvidence[] | undefined;\n signedAt?: string | undefined;\n}\n\nexport interface ContainerCreatePlan {\n body: ContainerCreateAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyEpochHash: string;\n keyTargetHash: string;\n manifest: AccessManifest;\n manifestHash: string;\n metadataDocumentId: string;\n parentContainerId: string | null;\n parentManifestHash: string | null;\n recipientTargets: ContainerKekRecipientTarget[];\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerCreatePlan {\n containerKey: Uint8Array;\n plan: ContainerCreatePlan;\n}\n\nexport interface ContainerCreatePlanContext\n extends BuildContainerCreatePlanInput {\n containerKeyPublicKey: string;\n containerId: string;\n containerKeyEpochId: string;\n eventId: string;\n metadataDocumentId: string;\n parent: ParentContainerCreateContext;\n signedAt: string;\n}\n\nexport interface ContainerMutationSubmitFailure {\n readonly code?: string | undefined;\n readonly message: string;\n readonly ok: false;\n readonly report: () => void;\n readonly stalePrincipalHeads?:\n | readonly ReferencedPrincipalStateResponse[]\n | undefined;\n readonly status: number | null;\n}\n\nexport type ContainerMutationSubmitResult<T> =\n | {\n readonly data: T;\n readonly ok: true;\n }\n | ContainerMutationSubmitFailure;\n\nexport interface ContainerCreateApi {\n createContainerResult(\n input: ContainerMutationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerMutationSubmitResult<ContainerMutationResponse>>;\n createContainerWithMetadataDocumentResult(\n input: ContainerCreateWithMetadataDocumentRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<\n ContainerMutationSubmitResult<ContainerCreateWithMetadataDocumentResponse>\n >;\n evictContainerWriterProjection(containerId: string): void;\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n}\n\nexport interface ContainerShareApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n shareContainer(\n containerId: string,\n input: ContainerMutationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerMutationResponse | null>;\n}\n\n/**\n * A status-bearing rotation outcome. A refusal that names\n * `requiredContainerIds` is answerable: sign those descendant rekeys and\n * resubmit with them carried.\n */\nexport type ContainerRotationResult =\n | { readonly ok: true; readonly data: ContainerRotationResponse }\n | {\n readonly ok: false;\n readonly code?: string | undefined;\n /** Surface a failure that was submitted with `reportErrors: false`. */\n readonly report?: (() => void) | undefined;\n readonly requiredContainerIds?: readonly string[] | undefined;\n readonly status: number | null;\n };\n\nexport interface ContainerMoveApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n moveContainer(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResponse | null>;\n /** Optional status-bearing variant; without it nothing can be carried. */\n moveContainerResult?(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResult>;\n}\n\nexport interface ContainerRevokeApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n revokeContainer(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResponse | null>;\n /** Optional status-bearing variant; without it nothing can be carried. */\n revokeContainerResult?(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResult>;\n}\n\nexport interface CreateRemoteContainerResult {\n containerKey: Uint8Array;\n containerId: string;\n metadataDocumentId: string;\n plan: ContainerCreatePlan;\n response: ContainerMutationResponse;\n}\n\nexport interface ContainerSharePlan {\n body: ContainerGrantAccessEventBody;\n /** The unchanged epoch's stored keyring, echoed back by the server. */\n previousKeyring?: Record<string, unknown> | null | undefined;\n containerId: string;\n event: AccessEvent;\n eventHash: string;\n grant: ContainerDirectGrant;\n keyEpoch: ContainerKeyEpoch;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n recipientTarget: ContainerKekRecipientTarget;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerSharePlan {\n containerKey: Uint8Array;\n plan: ContainerSharePlan;\n}\n\nexport interface ContainerRevokePlan {\n body: ContainerRevokeAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerRevokePlan {\n containerKey: Uint8Array;\n plan: ContainerRevokePlan;\n}\n\nexport interface ContainerRekeyPlan {\n body: ContainerRekeyAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n userRecipientKeys: ContainerUserRecipientKey[];\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerRekeyPlan {\n containerKey: Uint8Array;\n plan: ContainerRekeyPlan;\n writerProjection: ContainerWriterProjectionResponse;\n}\n\nexport interface ContainerRekeyApi extends ContainerReciteApi {\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n rekeyContainer(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResponse | null>;\n /** Optional status-bearing variant; see DocumentSyncApi. */\n rekeyContainerResult?(\n containerId: string,\n input: ContainerRotationRequest,\n options?: ContainerMutationRequestOptions,\n ): Promise<ContainerRotationResult>;\n}\n\nexport interface ContainerMovePlan {\n body: ContainerMoveAccessEventBody;\n containerId: string;\n containerKeyEpochId: string;\n event: AccessEvent;\n eventHash: string;\n keyEpoch: ContainerKeyEpoch;\n keyring: ContainerKekKeyring;\n manifest: AccessManifest;\n manifestHash: string;\n previousManifest: AccessManifestBundleWire;\n request: ContainerMutationRequest;\n state: ContainerAccessManifestState;\n wraps: ContainerKeyWrap[];\n}\n\nexport interface MaterializedContainerMovePlan {\n containerKey: Uint8Array;\n plan: ContainerMovePlan;\n}\n\nexport interface BuildMaterializedContainerMovePlanInput {\n author: ContainerMutationAuthor;\n containerKeyEpochId?: string | undefined;\n destinationParentProjection: ContainerWriterProjectionResponse;\n eventId?: string | undefined;\n execSql: ExecSql;\n previousProjection: ContainerWriterProjectionResponse;\n signedAt?: string | undefined;\n targetSecretKey: Uint8Array;\n}\n\nexport interface ParentContainerCreateContext {\n manifest: ContainerWriterProjectionResponse[\"path\"][number];\n kek: ContainerKekResponse;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerSystemSlot } from \"@tearleads/validators/containerSystemSlot\";\nimport type {\n ContainerDeleteResponse,\n ContainerWriterProjectionResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { createInitializedContainerMetadataDocument } from \"../../../data/containers/containerMetadataDocument\";\nimport type { ProjectionUserKeyResolver } from \"../../../data/keyingProjectionVerification\";\nimport type { DocumentRecord } from \"../../../data/sqlite/documentPersistence\";\nimport type {\n createRemoteContainer,\n moveRemoteContainer,\n shareRemoteContainer,\n shareRemoteContainerWithGroup,\n} from \"../../containers\";\nimport type { createRemoteDocument } from \"../../documents\";\nimport type { CurrentPrincipalPolicyReader } from \"../../principals/currentPrincipalPolicyReader\";\nimport type { PrincipalPolicyHistoryReader } from \"../../principals/principalPolicyHistoryReader\";\nimport type {\n ContainerContentsPersistence,\n ContainerCreateIntentRecord,\n ContainerMoveIntentRecord,\n} from \"../containerPersistence\";\nimport type {\n ContainerState,\n RemoteContainer as HydratedRemoteContainer,\n RemoteContainerHydrationHost,\n} from \"../remoteHydration\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport type ContainerWorkflowApi = Parameters<\n typeof createRemoteContainer\n>[0][\"apiClient\"] &\n Parameters<typeof shareRemoteContainer>[0][\"apiClient\"] &\n Parameters<typeof shareRemoteContainerWithGroup>[0][\"apiClient\"] &\n Parameters<typeof moveRemoteContainer>[0][\"apiClient\"] &\n Parameters<typeof createRemoteDocument>[0][\"apiClient\"] &\n Partial<PrincipalPolicyHistoryReader> &\n CurrentPrincipalPolicyReader & {\n deleteContainerResult(\n containerId: string,\n options?: {\n expectedPaymentRequiredOrganizationId?: string;\n reportErrors?: boolean;\n requiredAncestorId?: string | undefined;\n },\n ): Promise<\n | { data: ContainerDeleteResponse; ok: true }\n | {\n ok: false;\n report: () => void;\n status: number | null;\n }\n >;\n primeContainerWriterProjection(\n containerId: string,\n projection: ContainerWriterProjectionResponse,\n ): void;\n };\n\nexport interface ContainerWorkflowRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n readonly apiClient: ContainerWorkflowApi;\n}\n\nexport interface CreatedRemoteContainerState {\n accessManifestHash: string;\n /** The slot this client signed into the create; never the server's echo. */\n systemSlot: ContainerSystemSlot | null;\n containerId: string;\n createdAt: string;\n metadataDocumentId: string;\n organizationId: string;\n /** A created container is a child; the acknowledgement echoed this parent. */\n parentId: string;\n persistedMetadataState: Pick<\n DocumentRecord,\n | \"documentId\"\n | \"contentKeyBundle\"\n | \"documentKekTargets\"\n | \"documentManifestBundle\"\n >;\n updatedAt: string;\n}\n\nexport interface SharedRemoteContainerState {\n accessEpoch: number;\n accessManifestHash: string;\n createdAt: string;\n metadataDocumentId: string;\n referencedPrincipalHeads: ReferencedPrincipalStateResponse[];\n updatedAt: string;\n writerProjection: ContainerWriterProjectionResponse | null;\n}\n\nexport interface SharedContainerState {\n container: ContainerState[\"container\"];\n record: ContainerState[\"record\"];\n}\n\nexport type SharedContainerStateResult =\n | { status: \"missing\" }\n | { status: \"confirmed\" }\n | (SharedContainerState & {\n status: \"identity-superseded\" | \"persisted\";\n });\n\nexport type RemoteContainer = HydratedRemoteContainer;\n\nexport type ContainerMetadataDocumentState = Awaited<\n ReturnType<typeof createInitializedContainerMetadataDocument>\n>[\"doc\"];\n\nexport interface CreatedChildContainerState {\n containerState: ContainerState;\n initialUpdate: Uint8Array;\n shouldRequestSync: boolean;\n}\n\nexport interface ContainerIntentSyncState {\n containersById: ReadonlyMap<string, ContainerState>;\n persistence: ContainerContentsPersistence;\n resolveProjectionUserKey: ProjectionUserKeyResolver;\n runtime: ContainerWorkflowRuntime;\n /**\n * Verifies that a listed container is this device's pending create before it\n * is adopted and returns where it sits; `assertContainerCreateAdoptable`\n * unless a test replaces it.\n */\n verifyCreateAdoption?: (input: {\n readonly containerId: string;\n readonly expectedOrganizationId: string;\n }) => Promise<AdoptedContainerPlacement>;\n}\n\n/** Where a verified listed create committed, and where its container is now. */\nexport interface AdoptedContainerPlacement {\n /** The parent its signed epoch-1 `container.create` named. */\n readonly createdParentId: string;\n /** The verified head's parent; another writer may have moved it since. */\n readonly currentParentId: string;\n}\n\nexport type ContainerCreateIntentSyncState = ContainerIntentSyncState;\n\nexport type ContainerCreateIntentSyncHost = Pick<\n RemoteContainerHydrationHost,\n \"persistContainerState\"\n>;\n\nexport interface ContainerCreateIntentSyncInput {\n host: ContainerCreateIntentSyncHost;\n /** A parent whose own create has not settled takes no child create. */\n isCreatePending: (containerId: string) => boolean;\n isCurrent: () => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n intent: ContainerCreateIntentRecord;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerCreateIntentSyncState;\n}\n\nexport type ContainerMoveIntentSyncState = ContainerIntentSyncState;\n\nexport type ContainerMoveIntentSyncHost = Pick<\n RemoteContainerHydrationHost,\n \"persistContainerState\" | \"updateSnapshot\"\n>;\n\nexport interface ContainerMoveIntentSyncInput {\n host: ContainerMoveIntentSyncHost;\n isCurrent: () => boolean;\n /** A folder whose create has not settled takes no structural writes. */\n isCreatePending: (containerId: string) => boolean;\n isRemoteSyncBlocked: (organizationId: string) => boolean;\n intent: ContainerMoveIntentRecord;\n requestRemoteReconciliation: (parentContainerId: string | null) => void;\n state: ContainerMoveIntentSyncState;\n}\n"]}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RequestResult } from "../../../internal/api-client/index.js";
|
|
2
2
|
import type { ContainerReplacementAuthorizationsResponse } from "../../../internal/validators/operation/index.js";
|
|
3
3
|
import type { ListContainerParentLanesRequest } from "../../../internal/validators/request/index.js";
|
|
4
|
-
import type { ContainerSummary, ContainerWriterProjectionResponse, DocumentWriterProjectionResponse, ListContainerParentLanesResponse, ListContainersResponse,
|
|
4
|
+
import type { ContainerSummary, ContainerWriterProjectionResponse, DocumentWriterProjectionResponse, ListContainerParentLanesResponse, ListContainersResponse, ReferencedPrincipalStateResponse } from "../../../internal/validators/response/index.js";
|
|
5
5
|
import type { createContainerMetadataDocument } from "../../../data/containers/containerMetadataDocument.js";
|
|
6
|
+
import type { CurrentPrincipalPolicyReader } from "../../principals/currentPrincipalPolicyReader.js";
|
|
7
|
+
import type { PrincipalPolicyHistoryReader } from "../../principals/principalPolicyHistoryReader.js";
|
|
6
8
|
import type { ContainerContentsPersistence, ContainerDocumentRecord, ContainerHydrationTombstone, ContainerRecord, createContainerParentSyncLane } from "../containerPersistence.js";
|
|
7
9
|
import type { ContainerMetadataPatch } from "../metadata.js";
|
|
8
10
|
import type { ContainerContentsWorkflowRuntime } from "../runtime.js";
|
|
@@ -30,11 +32,10 @@ export interface ContainerState {
|
|
|
30
32
|
pullContinuation?: ContainerDocumentRecord["pullContinuation"] | undefined;
|
|
31
33
|
record: ContainerDocumentRecord;
|
|
32
34
|
}
|
|
33
|
-
interface RemoteContainerHydrationApi extends Partial<
|
|
35
|
+
interface RemoteContainerHydrationApi extends Partial<PrincipalPolicyHistoryReader>, CurrentPrincipalPolicyReader {
|
|
34
36
|
getContainerReplacementAuthorizationsResult(containerId: string, replacesOrganizationId: string): Promise<RequestResult<ContainerReplacementAuthorizationsResponse>>;
|
|
35
37
|
evictContainerWriterProjection(containerId: string): void;
|
|
36
38
|
getContainerWriterProjection(containerId: string): Promise<ContainerWriterProjectionResponse | null>;
|
|
37
|
-
getCurrentPrincipalPolicy(principalType: "group" | "organization", principalId: string): Promise<PrincipalPolicyBundleResponse | null>;
|
|
38
39
|
listContainerParentLanes(input: ListContainerParentLanesRequest): Promise<ListContainerParentLanesResponse | null>;
|
|
39
40
|
}
|
|
40
41
|
interface RemoteContainerHydrationRuntime extends Pick<ContainerContentsWorkflowRuntime, "auth" | "adoptRootContainer" | "crypto" | "infra" | "resolveTrustedUserIdentity" | "state" | "util"> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import type { RequestResult } from \"@tearleads/api-client\";\nimport type { ContainerReplacementAuthorizationsResponse } from \"@tearleads/validators/operation\";\nimport type { ListContainerParentLanesRequest } from \"@tearleads/validators/request\";\nimport type {\n ContainerSummary,\n ContainerWriterProjectionResponse,\n DocumentWriterProjectionResponse,\n ListContainerParentLanesResponse,\n ListContainersResponse,\n ReferencedPrincipalStateResponse,\n} from \"@tearleads/validators/response\";\nimport type { createContainerMetadataDocument } from \"../../../data/containers/containerMetadataDocument\";\nimport type { CurrentPrincipalPolicyReader } from \"../../principals/currentPrincipalPolicyReader\";\nimport type { PrincipalPolicyHistoryReader } from \"../../principals/principalPolicyHistoryReader\";\nimport type {\n ContainerContentsPersistence,\n ContainerDocumentRecord,\n ContainerHydrationTombstone,\n ContainerRecord,\n createContainerParentSyncLane,\n} from \"../containerPersistence\";\nimport type { ContainerMetadataPatch } from \"../metadata\";\nimport type { ContainerContentsWorkflowRuntime } from \"../runtime\";\n\nexport type ListedRemoteContainerPageItem =\n ListContainersResponse[\"items\"][number];\nexport type ContainerChildIndex = Map<string, Set<string>>;\nexport type QueueContainerParentLane = (parentId: string | null) => void;\nexport type RemoteContainerIngestQueue = Map<string, RemoteContainer>;\nexport type SaveContainerOptions = Parameters<\n ContainerContentsPersistence[\"saveContainer\"]\n>[3];\n\nexport type ContainerMetadataDocumentState = Awaited<\n ReturnType<typeof createContainerMetadataDocument>\n>;\nexport type RemoteContainer = Pick<\n ContainerSummary,\n | \"createdAt\"\n | \"effectiveAccessLevel\"\n | \"systemSlot\"\n | \"id\"\n | \"metadataAccessEpoch\"\n | \"metadataAccessStateHash\"\n | \"metadataDocumentId\"\n | \"metadataReferencedPrincipals\"\n | \"organizationId\"\n | \"parentId\"\n | \"updatedAt\"\n>;\n\nexport interface ContainerState {\n containerWriterProjection?:\n | ContainerWriterProjectionResponse\n | null\n | undefined;\n /**\n * Bumped whenever a realtime hint drops this container's cached writer\n * projections (container and metadata document alike); an operation that\n * fetched or carried a projection installs it only if this is unchanged\n * since it started, so a pre-hint answer never lands after the hint.\n */\n writerProjectionGeneration?: number | undefined;\n metadataReferencedPrincipals?:\n | readonly ReferencedPrincipalStateResponse[]\n | undefined;\n container: ContainerRecord;\n doc: ContainerMetadataDocumentState;\n metadataWriterProjection?:\n | DocumentWriterProjectionResponse\n | null\n | undefined;\n /** Durable pull progress mirrored from the metadata document record. */\n pullContinuation?: ContainerDocumentRecord[\"pullContinuation\"] | undefined;\n record: ContainerDocumentRecord;\n}\n\ninterface RemoteContainerHydrationApi\n extends Partial<PrincipalPolicyHistoryReader>,\n CurrentPrincipalPolicyReader {\n getContainerReplacementAuthorizationsResult(\n containerId: string,\n replacesOrganizationId: string,\n ): Promise<RequestResult<ContainerReplacementAuthorizationsResponse>>;\n evictContainerWriterProjection(containerId: string): void;\n getContainerWriterProjection(\n containerId: string,\n ): Promise<ContainerWriterProjectionResponse | null>;\n listContainerParentLanes(\n input: ListContainerParentLanesRequest,\n ): Promise<ListContainerParentLanesResponse | null>;\n}\n\ninterface RemoteContainerHydrationRuntime\n extends Pick<\n ContainerContentsWorkflowRuntime,\n | \"auth\"\n | \"adoptRootContainer\"\n | \"crypto\"\n | \"infra\"\n | \"resolveTrustedUserIdentity\"\n | \"state\"\n | \"util\"\n > {\n apiClient: RemoteContainerHydrationApi;\n}\n\nexport interface RemoteContainerHydrationState {\n containersById: Map<string, ContainerState>;\n lifecycleGeneration?: number | undefined;\n persistence: ContainerContentsPersistence;\n rootLaneHydrated?: boolean | undefined;\n runtime: RemoteContainerHydrationRuntime;\n structuralGeneration?: number | undefined;\n}\n\nexport type PersistContainerStateResult =\n | { status: \"identity-superseded\"; record: ContainerDocumentRecord }\n | { status: \"missing\" }\n | {\n status: \"persisted\";\n record: ContainerDocumentRecord;\n createIntentSettled?: true | undefined;\n moveIntentSettled?: true | undefined;\n }\n | { status: \"stale-generation\" };\n\nexport interface RemoteContainerHydrationHost {\n persistContainerState: (\n containerState: ContainerState,\n patch?: Partial<ContainerMetadataPatch>,\n updateView?: boolean,\n saveOptions?: SaveContainerOptions,\n mutationOptions?: {\n expectedStateWhenMissing?: ContainerState | undefined;\n isCurrent?: (() => boolean) | undefined;\n createIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"createIntentSettlement\"];\n moveIntentSettlement?: Parameters<\n ContainerContentsPersistence[\"commitMetadataMutation\"]\n >[1][\"moveIntentSettlement\"];\n preserveDurableStructureWhenPending?: boolean | undefined;\n },\n ) => Promise<PersistContainerStateResult>;\n requestDocumentPriming?: (() => void) | undefined;\n updateSnapshot: () => void;\n}\n\nexport interface ContainerParentHydrationLane {\n parentId: string | null;\n watermark?: ListContainersResponse[\"nextWatermark\"];\n}\n\nexport interface ExpectedContainerState {\n container: ContainerRecord;\n fingerprint: string;\n}\n\nexport interface FetchedContainerParentLanePage {\n expectedContainerStates: ReadonlyMap<string, ExpectedContainerState>;\n expectedHydrationTombstones: ReadonlyMap<string, ContainerHydrationTombstone>;\n lane: ContainerParentHydrationLane;\n response: ListContainersResponse;\n syncLane: ReturnType<typeof createContainerParentSyncLane>;\n}\n"]}
|
|
@@ -2,6 +2,7 @@ import { nullOnProjectionVerificationCancellation, requireProjectionUserKeyResol
|
|
|
2
2
|
import { principalPolicyCacheForVerifiedPolicies } from "../../../data/keyingProjectionVerification/principalPolicyCache.js";
|
|
3
3
|
import { inheritPrincipalHistoryProtection } from "../../../data/principals/principalHistoryRuntime.js";
|
|
4
4
|
import { createRuntimeCurrentGroupMutation } from "../../organizations/runtimeCurrentGroupMutation.js";
|
|
5
|
+
import { apiPrincipalPolicyPageReader, apiProjectionPolicyHistoryReader, } from "../../principals/principalPolicyHistoryReader.js";
|
|
5
6
|
import { commitCurrentShareGrant } from "./currentShareGrantMutation.js";
|
|
6
7
|
import { createRuntimeCurrentSharePrincipalPolicy } from "./currentSharePrincipalPolicy.js";
|
|
7
8
|
import { submitAcknowledgedContainerMutation, submitPlainContainerMutation, } from "./mutationSubmit.js";
|
|
@@ -11,18 +12,14 @@ import { resolveShareProjection } from "./shareProjection.js";
|
|
|
11
12
|
export function createRuntimeCurrentGroupShare(runtime) {
|
|
12
13
|
const readCurrent = createRuntimeCurrentSharePrincipalPolicy(runtime);
|
|
13
14
|
const api = runtime.apiClient;
|
|
14
|
-
const
|
|
15
|
-
if (!readCurrent || !
|
|
15
|
+
const historyReader = apiPrincipalPolicyPageReader(api);
|
|
16
|
+
if (!readCurrent || !historyReader)
|
|
16
17
|
return undefined;
|
|
17
18
|
const mutate = createRuntimeCurrentGroupMutation(inheritPrincipalHistoryProtection(runtime, {
|
|
18
19
|
...runtime,
|
|
19
20
|
apiClient: {
|
|
20
|
-
|
|
21
|
-
...(api
|
|
22
|
-
? {
|
|
23
|
-
getProjectionPolicyHistoryPages: api.getProjectionPolicyHistoryPages.bind(api),
|
|
24
|
-
}
|
|
25
|
-
: {}),
|
|
21
|
+
...historyReader,
|
|
22
|
+
...apiProjectionPolicyHistoryReader(api),
|
|
26
23
|
recoverPendingPrincipalMutation: async (organizationId) => {
|
|
27
24
|
// Built-in clients supply journal recovery; standalone hosts retain
|
|
28
25
|
// responsibility for transport and exact-outcome recovery.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeCurrentGroupShare.js","sourceRoot":"","sources":["runtimeCurrentGroupShare.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wCAAwC,EACxC,gCAAgC,GACjC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAAE,uCAAuC,EAAE,MAAM,iEAAiE,CAAC;AAC1H,OAAO,EAAE,iCAAiC,EAAE,MAAM,kDAAkD,CAAC;AACrG,OAAO,EAAE,iCAAiC,EAAE,MAAM,iDAAiD,CAAC;AACpG,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,wCAAwC,EAAE,MAAM,+BAA+B,CAAC;AACzF,OAAO,EACL,mCAAmC,EACnC,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,mCAAmC,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,sFAAsF;AACtF,MAAM,UAAU,8BAA8B,CAC5C,OAAuE;IAEvE,MAAM,WAAW,GAAG,wCAAwC,CAAC,OAAO,CAAC,CAAC;IACtE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC;IAC9B,MAAM,
|
|
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 {\n apiPrincipalPolicyPageReader,\n apiProjectionPolicyHistoryReader,\n} from \"../../principals/principalPolicyHistoryReader\";\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 historyReader = apiPrincipalPolicyPageReader(api);\n if (!readCurrent || !historyReader) return undefined;\n const mutate = createRuntimeCurrentGroupMutation(\n inheritPrincipalHistoryProtection(runtime, {\n ...runtime,\n apiClient: {\n ...historyReader,\n ...apiProjectionPolicyHistoryReader(api),\n recoverPendingPrincipalMutation: async (organizationId: string) => {\n // Built-in clients supply journal recovery; standalone hosts retain\n // responsibility for transport and exact-outcome recovery.\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"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { ApiClient } from "../../../internal/api-client/index.js";
|
|
2
|
-
import { KeyingVerificationError, type
|
|
2
|
+
import { KeyingVerificationError, type ReferencedPrincipalHead, type VerifiedPrincipalPolicy } from "../../../internal/crypto/index.js";
|
|
3
3
|
import type { CommitOrganizationGroupPolicyRequest } from "../../../internal/validators/request/index.js";
|
|
4
4
|
import type { CommitOrganizationGroupPolicyResponse, PrincipalPolicyBundleResponse } from "../../../internal/validators/response/index.js";
|
|
5
5
|
import type { ContainerShareApi } from "../../../data/containers/shared/types.js";
|
|
6
6
|
import type { ExecSql } from "../../../data/sqlite/sqlSchema.js";
|
|
7
7
|
import type { TrustedUserIdentityResolver } from "../../../data/trustedUserIdentity/index.js";
|
|
8
8
|
import { type GroupPolicyNameReader } from "../../organizations/principalPolicyRequest.js";
|
|
9
|
-
|
|
9
|
+
import type { CurrentPrincipalPolicyReader } from "../../principals/currentPrincipalPolicyReader.js";
|
|
10
|
+
export interface ContainerManagedPrincipalShareApi extends ContainerShareApi, CurrentPrincipalPolicyReader, Pick<ApiClient, "evictContainerWriterProjection" | "getContainerWriterProjectionResult"> {
|
|
10
11
|
readonly recoverPendingPrincipalMutation?: ((organizationId: string) => Promise<void>) | undefined;
|
|
11
12
|
commitOrganizationGroupPolicy: (organizationId: string, groupId: string, input: CommitOrganizationGroupPolicyRequest) => Promise<CommitOrganizationGroupPolicyResponse | null>;
|
|
12
|
-
getCurrentPrincipalPolicy: (principalType: ManagedPrincipalKind, principalId: string) => Promise<PrincipalPolicyBundleResponse | null>;
|
|
13
13
|
}
|
|
14
14
|
export interface VerifiedSharePrincipalPolicy {
|
|
15
15
|
readonly bundle: PrincipalPolicyBundleResponse;
|
|
@@ -130,8 +130,8 @@ async function assertShareGroupName(input) {
|
|
|
130
130
|
}
|
|
131
131
|
export async function loadVerifiedGroupSharePrincipalPolicy(input) {
|
|
132
132
|
const organizationAdminPolicy = await loadOrganizationExternalAdminPolicy({
|
|
133
|
+
currentPolicyReader: input.apiClient,
|
|
133
134
|
execSql: input.execSql,
|
|
134
|
-
getCurrentPrincipalPolicy: (principalType, principalId) => input.apiClient.getCurrentPrincipalPolicy(principalType, principalId),
|
|
135
135
|
organizationId: input.organizationId,
|
|
136
136
|
resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,
|
|
137
137
|
stillCurrent: input.stillCurrent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharePrincipalPolicy.js","sourceRoot":"","sources":["sharePrincipalPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport {\n KeyingVerificationError,\n type ManagedPrincipalKind,\n type PrincipalPolicyCheckpoint,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { CommitOrganizationGroupPolicyRequest } from \"@tearleads/validators/request\";\nimport type {\n CommitOrganizationGroupPolicyResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport type { ContainerShareApi } from \"../../../data/containers/shared/types\";\nimport { throwKeyingVerificationErrorWithContext } from \"../../../data/keyingProjectionVerification/error\";\nimport { advanceKeyingCheckpointsAtomically } from \"../../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../../data/persistence/keyingCheckpointPersistence\";\nimport { savePrincipalPolicyBundle } from \"../../../data/persistence/principalPolicyPersistence\";\nimport { loadPrincipalPolicyBundleForReference } from \"../../../data/persistence/principalPolicyReferencePersistence\";\nimport { retainVerifiedPrincipalPolicyBundle } from \"../../../data/persistence/verifiedPrincipalPolicyRetentionPersistence\";\nimport {\n principalHeadMatchesReference,\n requireOrganizationGroupHead,\n} from \"../../../data/principals/organizationAuthorityDescriptor\";\nimport {\n principalPolicyReferenceFromBundle,\n verifyPrincipalPolicyBundleWithExternalOrganizationAdmins,\n} from \"../../../data/principals/principalPolicyAdminSigners\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport { assertGroupMetadataBinding } from \"../../organizations/groupMetadataBinding\";\nimport {\n type GroupPolicyNameReader,\n groupPolicyNameMismatch,\n} from \"../../organizations/principalPolicyRequest\";\nimport {\n externalAdminPolicyPersistenceEntries,\n loadOrganizationExternalAdminPolicy,\n type VerifiedExternalAdminPolicy,\n} from \"../../principals/externalAdminPolicy\";\nimport {\n collectPrincipalPolicySignerPublicKeys,\n type PrincipalPolicySignerPublicKeyLoadErrorCode,\n} from \"../../principals/policyVerification\";\n\nexport interface ContainerManagedPrincipalShareApi\n extends ContainerShareApi,\n Pick<\n ApiClient,\n \"evictContainerWriterProjection\" | \"getContainerWriterProjectionResult\"\n > {\n readonly recoverPendingPrincipalMutation?:\n | ((organizationId: string) => Promise<void>)\n | undefined;\n commitOrganizationGroupPolicy: (\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n ) => Promise<CommitOrganizationGroupPolicyResponse | null>;\n getCurrentPrincipalPolicy: (\n principalType: ManagedPrincipalKind,\n principalId: string,\n ) => Promise<PrincipalPolicyBundleResponse | null>;\n}\n\nexport interface VerifiedSharePrincipalPolicy {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly checkpointPolicies: readonly VerifiedPrincipalPolicy[];\n readonly dependencyBundles: readonly PrincipalPolicyBundleResponse[];\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicy;\n}\n\nasync function retainVerifiedSharePolicies(input: {\n bundle: PrincipalPolicyBundleResponse;\n execSql: ExecSql;\n organizationId: string;\n organizationPolicy: VerifiedExternalAdminPolicy | null;\n policy: VerifiedPrincipalPolicy;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<VerifiedPrincipalPolicy[]> {\n const retainedAt = new Date().toISOString();\n if (input.organizationPolicy) {\n for (const entry of externalAdminPolicyPersistenceEntries(\n input.organizationPolicy,\n )) {\n await retainVerifiedPrincipalPolicyBundle({\n ...entry,\n execSql: input.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n updatedAt: retainedAt,\n });\n }\n }\n await retainVerifiedPrincipalPolicyBundle({\n bundle: input.bundle,\n execSql: input.execSql,\n organizationId: input.organizationId,\n policy: input.policy,\n stillCurrent: input.stillCurrent,\n updatedAt: retainedAt,\n });\n return [\n ...(input.organizationPolicy\n ? externalAdminPolicyPersistenceEntries(input.organizationPolicy).map(\n (entry) => entry.policy,\n )\n : []),\n input.policy,\n ];\n}\n\n/**\n * Commits the verification a loadVerifiedGroupSharePrincipalPolicy call\n * deferred: advances the keying checkpoints for the verified policies and\n * caches the dependency bundles they were verified against.\n */\nexport async function advanceVerifiedSharePolicies(\n execSql: ExecSql,\n verified: Pick<\n VerifiedSharePrincipalPolicy,\n \"checkpointPolicies\" | \"dependencyBundles\" | \"organizationId\"\n >,\n stillCurrent?: (() => boolean) | undefined,\n): Promise<void> {\n await advanceKeyingCheckpointsAtomically({\n access: [],\n execSql,\n organizationId: verified.organizationId,\n policies: verified.checkpointPolicies,\n stillCurrent,\n });\n if (stillCurrent?.() === false) return;\n for (const bundle of verified.dependencyBundles) {\n await savePrincipalPolicyBundle(\n execSql,\n bundle,\n new Date().toISOString(),\n verified.organizationId,\n { stillCurrent },\n );\n if (stillCurrent?.() === false) return;\n }\n}\n\nfunction assertGroupPolicyTarget(\n bundle: PrincipalPolicyBundleResponse,\n groupId: string,\n): void {\n if (\n bundle.currentState.principalType !== \"group\" ||\n bundle.currentState.principalId !== groupId\n ) {\n throw new Error(\"Container share principal policy target mismatch\");\n }\n}\n\nfunction signerPublicKeyLoadErrorMessage(\n code: PrincipalPolicySignerPublicKeyLoadErrorCode,\n): string {\n switch (code) {\n case \"fingerprint-mismatch\":\n return \"principal policy signer key fingerprint mismatch\";\n case \"not-found\":\n return \"principal policy signer key could not be loaded\";\n }\n}\n\nasync function loadGroupSharePolicyBundle(input: {\n apiClient: ContainerManagedPrincipalShareApi;\n execSql: ExecSql;\n expectedGroupHead?: ReferencedPrincipalHead | undefined;\n groupId: string;\n localCheckpoint: PrincipalPolicyCheckpoint | null;\n}): Promise<PrincipalPolicyBundleResponse> {\n if (\n input.expectedGroupHead &&\n (input.expectedGroupHead.principalType !== \"group\" ||\n input.expectedGroupHead.principalId !== input.groupId)\n ) {\n throw new Error(\"Container share expected group policy target mismatch\");\n }\n const bundleFromCache = input.expectedGroupHead\n ? await loadPrincipalPolicyBundleForReference(\n input.execSql,\n input.expectedGroupHead,\n input.localCheckpoint,\n )\n : null;\n let bundle = bundleFromCache;\n bundle ??= await input.apiClient.getCurrentPrincipalPolicy(\n \"group\",\n input.groupId,\n );\n if (!bundle) {\n throw new Error(\"Container share principal policy could not be loaded\");\n }\n assertGroupPolicyTarget(bundle, input.groupId);\n if (\n input.expectedGroupHead &&\n !principalHeadMatchesReference(\n principalPolicyReferenceFromBundle(bundle),\n input.expectedGroupHead,\n )\n ) {\n throw new Error(\n \"Container share group policy does not match the signed organization directory\",\n );\n }\n return bundle;\n}\n\n/**\n * The chosen group label does not match the name in the group's verified\n * policy. A KeyingVerificationError (so it is reported as an incident), with\n * its own class so a caller can tell this refusal from every other\n * `object_mismatch` and say what happened.\n */\nexport class GroupShareNameMismatchError extends KeyingVerificationError {\n constructor(message: string) {\n super(\"object_mismatch\", message);\n this.name = \"GroupShareNameMismatchError\";\n }\n}\n\n/**\n * The share picker labels groups from the organization read model, which a\n * compromised server can relabel, so the name the user chose must equal the\n * name committed in the target's verified policy. Names compare by their\n * canonical key so look-alike spellings count as the same name. Uniqueness of\n * signed names within an organization is enforced where names enter — group\n * creation verifies every group in the signed directory — so a single\n * verified match identifies the group.\n */\nasync function assertShareGroupName(input: {\n readEncryptedName?: GroupPolicyNameReader | undefined;\n bundle: PrincipalPolicyBundleResponse;\n expectedGroupName: string;\n}): Promise<void> {\n // The label comes from the untrusted read model. Signed names never carry\n // an invisible code point, so a label that does is a look-alike that would\n // only match after canonicalization strips it; refuse it outright.\n const mismatch = await groupPolicyNameMismatch(\n input.bundle,\n input.expectedGroupName,\n input.readEncryptedName,\n );\n if (mismatch === \"forbidden_characters\") {\n throw new GroupShareNameMismatchError(\n \"Container share group name contains control or format characters\",\n );\n }\n if (mismatch === \"name_mismatch\") {\n throw new GroupShareNameMismatchError(\n \"Container share group name does not match the signed group policy\",\n );\n }\n}\n\nexport async function loadVerifiedGroupSharePrincipalPolicy(input: {\n readEncryptedName?: GroupPolicyNameReader | undefined;\n apiClient: ContainerManagedPrincipalShareApi;\n execSql: ExecSql;\n expectedGroupHead?: ReferencedPrincipalHead | undefined;\n /**\n * The display name the user chose the group by. The read model that labels\n * groups is a server projection; only the name committed in the signed\n * group payload can confirm the share lands on the group the user saw.\n */\n expectedGroupName?: string | undefined;\n groupId: string;\n organizationId: string;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<VerifiedSharePrincipalPolicy> {\n const organizationAdminPolicy = await loadOrganizationExternalAdminPolicy({\n execSql: input.execSql,\n getCurrentPrincipalPolicy: (principalType, principalId) =>\n input.apiClient.getCurrentPrincipalPolicy(principalType, principalId),\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n if (!organizationAdminPolicy) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n const committedGroupHead = requireOrganizationGroupHead(\n organizationAdminPolicy.descriptor,\n input.groupId,\n );\n if (\n input.expectedGroupHead &&\n !principalHeadMatchesReference(input.expectedGroupHead, committedGroupHead)\n ) {\n throw new Error(\n \"Container share expected group head conflicts with the signed organization directory\",\n );\n }\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n \"group\",\n input.groupId,\n );\n const bundle = await loadGroupSharePolicyBundle({\n ...input,\n expectedGroupHead: committedGroupHead,\n localCheckpoint,\n });\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in signerPublicKeys) {\n throw new Error(signerPublicKeyLoadErrorMessage(signerPublicKeys.error));\n }\n\n const verified =\n await verifyPrincipalPolicyBundleWithExternalOrganizationAdmins({\n bundle,\n expectedReference: committedGroupHead,\n loadExternalAuthority: async () =>\n organizationAdminPolicy.externalAuthority,\n localCheckpoint,\n signerPublicKeys: signerPublicKeys.signerPublicKeys,\n });\n if (!verified.ok) {\n throwKeyingVerificationErrorWithContext(\n verified.error,\n \"Container share principal policy verification failed\",\n );\n }\n assertGroupMetadataBinding(bundle, organizationAdminPolicy.descriptor);\n if (input.expectedGroupName !== undefined) {\n await assertShareGroupName({\n readEncryptedName: input.readEncryptedName,\n bundle,\n expectedGroupName: input.expectedGroupName,\n });\n }\n\n const checkpointPolicies = await retainVerifiedSharePolicies({\n bundle,\n execSql: input.execSql,\n organizationId: input.organizationId,\n organizationPolicy: organizationAdminPolicy,\n policy: verified.value,\n stillCurrent: input.stillCurrent,\n });\n return {\n bundle,\n checkpointPolicies,\n dependencyBundles: externalAdminPolicyPersistenceEntries(\n organizationAdminPolicy,\n ).map((entry) => entry.bundle),\n organizationId: input.organizationId,\n policy: verified.value,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sharePrincipalPolicy.js","sourceRoot":"","sources":["sharePrincipalPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ApiClient } from \"@tearleads/api-client\";\nimport {\n KeyingVerificationError,\n type PrincipalPolicyCheckpoint,\n type ReferencedPrincipalHead,\n type VerifiedPrincipalPolicy,\n} from \"@tearleads/crypto\";\nimport type { CommitOrganizationGroupPolicyRequest } from \"@tearleads/validators/request\";\nimport type {\n CommitOrganizationGroupPolicyResponse,\n PrincipalPolicyBundleResponse,\n} from \"@tearleads/validators/response\";\nimport type { ContainerShareApi } from \"../../../data/containers/shared/types\";\nimport { throwKeyingVerificationErrorWithContext } from \"../../../data/keyingProjectionVerification/error\";\nimport { advanceKeyingCheckpointsAtomically } from \"../../../data/persistence/keyingCheckpointAdvancePersistence\";\nimport { loadPrincipalPolicyCheckpoint } from \"../../../data/persistence/keyingCheckpointPersistence\";\nimport { savePrincipalPolicyBundle } from \"../../../data/persistence/principalPolicyPersistence\";\nimport { loadPrincipalPolicyBundleForReference } from \"../../../data/persistence/principalPolicyReferencePersistence\";\nimport { retainVerifiedPrincipalPolicyBundle } from \"../../../data/persistence/verifiedPrincipalPolicyRetentionPersistence\";\nimport {\n principalHeadMatchesReference,\n requireOrganizationGroupHead,\n} from \"../../../data/principals/organizationAuthorityDescriptor\";\nimport {\n principalPolicyReferenceFromBundle,\n verifyPrincipalPolicyBundleWithExternalOrganizationAdmins,\n} from \"../../../data/principals/principalPolicyAdminSigners\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../../data/trustedUserIdentity\";\nimport { assertGroupMetadataBinding } from \"../../organizations/groupMetadataBinding\";\nimport {\n type GroupPolicyNameReader,\n groupPolicyNameMismatch,\n} from \"../../organizations/principalPolicyRequest\";\nimport type { CurrentPrincipalPolicyReader } from \"../../principals/currentPrincipalPolicyReader\";\nimport {\n externalAdminPolicyPersistenceEntries,\n loadOrganizationExternalAdminPolicy,\n type VerifiedExternalAdminPolicy,\n} from \"../../principals/externalAdminPolicy\";\nimport {\n collectPrincipalPolicySignerPublicKeys,\n type PrincipalPolicySignerPublicKeyLoadErrorCode,\n} from \"../../principals/policyVerification\";\n\nexport interface ContainerManagedPrincipalShareApi\n extends ContainerShareApi,\n CurrentPrincipalPolicyReader,\n Pick<\n ApiClient,\n \"evictContainerWriterProjection\" | \"getContainerWriterProjectionResult\"\n > {\n readonly recoverPendingPrincipalMutation?:\n | ((organizationId: string) => Promise<void>)\n | undefined;\n commitOrganizationGroupPolicy: (\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n ) => Promise<CommitOrganizationGroupPolicyResponse | null>;\n}\n\nexport interface VerifiedSharePrincipalPolicy {\n readonly bundle: PrincipalPolicyBundleResponse;\n readonly checkpointPolicies: readonly VerifiedPrincipalPolicy[];\n readonly dependencyBundles: readonly PrincipalPolicyBundleResponse[];\n readonly organizationId: string;\n readonly policy: VerifiedPrincipalPolicy;\n}\n\nasync function retainVerifiedSharePolicies(input: {\n bundle: PrincipalPolicyBundleResponse;\n execSql: ExecSql;\n organizationId: string;\n organizationPolicy: VerifiedExternalAdminPolicy | null;\n policy: VerifiedPrincipalPolicy;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<VerifiedPrincipalPolicy[]> {\n const retainedAt = new Date().toISOString();\n if (input.organizationPolicy) {\n for (const entry of externalAdminPolicyPersistenceEntries(\n input.organizationPolicy,\n )) {\n await retainVerifiedPrincipalPolicyBundle({\n ...entry,\n execSql: input.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n updatedAt: retainedAt,\n });\n }\n }\n await retainVerifiedPrincipalPolicyBundle({\n bundle: input.bundle,\n execSql: input.execSql,\n organizationId: input.organizationId,\n policy: input.policy,\n stillCurrent: input.stillCurrent,\n updatedAt: retainedAt,\n });\n return [\n ...(input.organizationPolicy\n ? externalAdminPolicyPersistenceEntries(input.organizationPolicy).map(\n (entry) => entry.policy,\n )\n : []),\n input.policy,\n ];\n}\n\n/**\n * Commits the verification a loadVerifiedGroupSharePrincipalPolicy call\n * deferred: advances the keying checkpoints for the verified policies and\n * caches the dependency bundles they were verified against.\n */\nexport async function advanceVerifiedSharePolicies(\n execSql: ExecSql,\n verified: Pick<\n VerifiedSharePrincipalPolicy,\n \"checkpointPolicies\" | \"dependencyBundles\" | \"organizationId\"\n >,\n stillCurrent?: (() => boolean) | undefined,\n): Promise<void> {\n await advanceKeyingCheckpointsAtomically({\n access: [],\n execSql,\n organizationId: verified.organizationId,\n policies: verified.checkpointPolicies,\n stillCurrent,\n });\n if (stillCurrent?.() === false) return;\n for (const bundle of verified.dependencyBundles) {\n await savePrincipalPolicyBundle(\n execSql,\n bundle,\n new Date().toISOString(),\n verified.organizationId,\n { stillCurrent },\n );\n if (stillCurrent?.() === false) return;\n }\n}\n\nfunction assertGroupPolicyTarget(\n bundle: PrincipalPolicyBundleResponse,\n groupId: string,\n): void {\n if (\n bundle.currentState.principalType !== \"group\" ||\n bundle.currentState.principalId !== groupId\n ) {\n throw new Error(\"Container share principal policy target mismatch\");\n }\n}\n\nfunction signerPublicKeyLoadErrorMessage(\n code: PrincipalPolicySignerPublicKeyLoadErrorCode,\n): string {\n switch (code) {\n case \"fingerprint-mismatch\":\n return \"principal policy signer key fingerprint mismatch\";\n case \"not-found\":\n return \"principal policy signer key could not be loaded\";\n }\n}\n\nasync function loadGroupSharePolicyBundle(input: {\n apiClient: ContainerManagedPrincipalShareApi;\n execSql: ExecSql;\n expectedGroupHead?: ReferencedPrincipalHead | undefined;\n groupId: string;\n localCheckpoint: PrincipalPolicyCheckpoint | null;\n}): Promise<PrincipalPolicyBundleResponse> {\n if (\n input.expectedGroupHead &&\n (input.expectedGroupHead.principalType !== \"group\" ||\n input.expectedGroupHead.principalId !== input.groupId)\n ) {\n throw new Error(\"Container share expected group policy target mismatch\");\n }\n const bundleFromCache = input.expectedGroupHead\n ? await loadPrincipalPolicyBundleForReference(\n input.execSql,\n input.expectedGroupHead,\n input.localCheckpoint,\n )\n : null;\n let bundle = bundleFromCache;\n bundle ??= await input.apiClient.getCurrentPrincipalPolicy(\n \"group\",\n input.groupId,\n );\n if (!bundle) {\n throw new Error(\"Container share principal policy could not be loaded\");\n }\n assertGroupPolicyTarget(bundle, input.groupId);\n if (\n input.expectedGroupHead &&\n !principalHeadMatchesReference(\n principalPolicyReferenceFromBundle(bundle),\n input.expectedGroupHead,\n )\n ) {\n throw new Error(\n \"Container share group policy does not match the signed organization directory\",\n );\n }\n return bundle;\n}\n\n/**\n * The chosen group label does not match the name in the group's verified\n * policy. A KeyingVerificationError (so it is reported as an incident), with\n * its own class so a caller can tell this refusal from every other\n * `object_mismatch` and say what happened.\n */\nexport class GroupShareNameMismatchError extends KeyingVerificationError {\n constructor(message: string) {\n super(\"object_mismatch\", message);\n this.name = \"GroupShareNameMismatchError\";\n }\n}\n\n/**\n * The share picker labels groups from the organization read model, which a\n * compromised server can relabel, so the name the user chose must equal the\n * name committed in the target's verified policy. Names compare by their\n * canonical key so look-alike spellings count as the same name. Uniqueness of\n * signed names within an organization is enforced where names enter — group\n * creation verifies every group in the signed directory — so a single\n * verified match identifies the group.\n */\nasync function assertShareGroupName(input: {\n readEncryptedName?: GroupPolicyNameReader | undefined;\n bundle: PrincipalPolicyBundleResponse;\n expectedGroupName: string;\n}): Promise<void> {\n // The label comes from the untrusted read model. Signed names never carry\n // an invisible code point, so a label that does is a look-alike that would\n // only match after canonicalization strips it; refuse it outright.\n const mismatch = await groupPolicyNameMismatch(\n input.bundle,\n input.expectedGroupName,\n input.readEncryptedName,\n );\n if (mismatch === \"forbidden_characters\") {\n throw new GroupShareNameMismatchError(\n \"Container share group name contains control or format characters\",\n );\n }\n if (mismatch === \"name_mismatch\") {\n throw new GroupShareNameMismatchError(\n \"Container share group name does not match the signed group policy\",\n );\n }\n}\n\nexport async function loadVerifiedGroupSharePrincipalPolicy(input: {\n readEncryptedName?: GroupPolicyNameReader | undefined;\n apiClient: ContainerManagedPrincipalShareApi;\n execSql: ExecSql;\n expectedGroupHead?: ReferencedPrincipalHead | undefined;\n /**\n * The display name the user chose the group by. The read model that labels\n * groups is a server projection; only the name committed in the signed\n * group payload can confirm the share lands on the group the user saw.\n */\n expectedGroupName?: string | undefined;\n groupId: string;\n organizationId: string;\n resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n stillCurrent?: (() => boolean) | undefined;\n}): Promise<VerifiedSharePrincipalPolicy> {\n const organizationAdminPolicy = await loadOrganizationExternalAdminPolicy({\n currentPolicyReader: input.apiClient,\n execSql: input.execSql,\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n if (!organizationAdminPolicy) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n const committedGroupHead = requireOrganizationGroupHead(\n organizationAdminPolicy.descriptor,\n input.groupId,\n );\n if (\n input.expectedGroupHead &&\n !principalHeadMatchesReference(input.expectedGroupHead, committedGroupHead)\n ) {\n throw new Error(\n \"Container share expected group head conflicts with the signed organization directory\",\n );\n }\n const localCheckpoint = await loadPrincipalPolicyCheckpoint(\n input.execSql,\n \"group\",\n input.groupId,\n );\n const bundle = await loadGroupSharePolicyBundle({\n ...input,\n expectedGroupHead: committedGroupHead,\n localCheckpoint,\n });\n const signerPublicKeys = await collectPrincipalPolicySignerPublicKeys({\n bundle,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n });\n if (\"error\" in signerPublicKeys) {\n throw new Error(signerPublicKeyLoadErrorMessage(signerPublicKeys.error));\n }\n\n const verified =\n await verifyPrincipalPolicyBundleWithExternalOrganizationAdmins({\n bundle,\n expectedReference: committedGroupHead,\n loadExternalAuthority: async () =>\n organizationAdminPolicy.externalAuthority,\n localCheckpoint,\n signerPublicKeys: signerPublicKeys.signerPublicKeys,\n });\n if (!verified.ok) {\n throwKeyingVerificationErrorWithContext(\n verified.error,\n \"Container share principal policy verification failed\",\n );\n }\n assertGroupMetadataBinding(bundle, organizationAdminPolicy.descriptor);\n if (input.expectedGroupName !== undefined) {\n await assertShareGroupName({\n readEncryptedName: input.readEncryptedName,\n bundle,\n expectedGroupName: input.expectedGroupName,\n });\n }\n\n const checkpointPolicies = await retainVerifiedSharePolicies({\n bundle,\n execSql: input.execSql,\n organizationId: input.organizationId,\n organizationPolicy: organizationAdminPolicy,\n policy: verified.value,\n stillCurrent: input.stillCurrent,\n });\n return {\n bundle,\n checkpointPolicies,\n dependencyBundles: externalAdminPolicyPersistenceEntries(\n organizationAdminPolicy,\n ).map((entry) => entry.bundle),\n organizationId: input.organizationId,\n policy: verified.value,\n };\n}\n"]}
|
|
@@ -36,7 +36,7 @@ export async function createCurrentOrganizationMutationRetention(input) {
|
|
|
36
36
|
request: receipt.request,
|
|
37
37
|
response: receipt.response,
|
|
38
38
|
recovery: {
|
|
39
|
-
|
|
39
|
+
historyReader: input.historyReader,
|
|
40
40
|
expectedHead: principalPolicyReferenceFromBundle(receipt.response),
|
|
41
41
|
protection: scopedGroupHistoryProtection(input.protection, input.organizationId, input.authority.descriptor.adminGroupId),
|
|
42
42
|
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"currentOrganizationMutationRetention.js","sourceRoot":"","sources":["currentOrganizationMutationRetention.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"currentOrganizationMutationRetention.js","sourceRoot":"","sources":["currentOrganizationMutationRetention.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,4BAA4B,EAAE,MAAM,uDAAuD,CAAC;AACrG,OAAO,EAAE,kCAAkC,EAAE,MAAM,mDAAmD,CAAC;AAGvG,OAAO,EAAE,uCAAuC,EAAE,MAAM,oCAAoC,CAAC;AAE7F,OAAO,EAEL,mCAAmC,GACpC,MAAM,uCAAuC,CAAC;AAE/C,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,0CAA0C,CAAC,KAUhE;IACC,MAAM,WAAW,GAAG,MAAM,uCAAuC,CAAC;QAChE,GAAG,KAAK,CAAC,iBAAiB;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACpC,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,KAAK,EAClB,OAAqD,EACrD,EAAE;QACF,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QACxD,MAAM,mCAAmC,CAAC;YACxC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACpC,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,OAAO;YACP,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO;QACL,eAAe,EAAE,CACf,OAAkC,EAClC,QAAyC,EACzC,EAAE,CACF,MAAM,CAAC;YACL,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,iBAAiB,EAAE;SACtE,CAAC;QACJ,kBAAkB,EAAE,CAAC,OAKpB,EAAE,EAAE;YACH,MAAM,SAAS,GAAG;gBAChB,GAAG,kCAAkC,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;gBACrE,aAAa,EAAE,OAAgB;aAChC,CAAC;YACF,OAAO,MAAM,CAAC;gBACZ;oBACE,YAAY,EAAE,IAAI;oBAClB,WAAW,EAAE,IAAI;oBACjB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE;wBACR,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,YAAY,EAAE,kCAAkC,CAAC,OAAO,CAAC,QAAQ,CAAC;wBAClE,UAAU,EAAE,4BAA4B,CACtC,KAAK,CAAC,UAAU,EAChB,KAAK,CAAC,cAAc,EACpB,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CACxC;wBACD,0BAA0B,EACxB,KAAK,CAAC,OAAO,CAAC,0BAA0B;wBAC1C,qBAAqB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;4BAClC,WAAW,EAAE,SAAS;4BACtB,MAAM,EAAE;gCACN;oCACE,IAAI,EAAE,SAAS;oCACf,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU;iCACrD;6BACF;yBACF,CAAC;qBACH;iBACF;gBACD;oBACE,WAAW;oBACX,OAAO,EAAE,OAAO,CAAC,mBAAmB;oBACpC,QAAQ,EAAE,OAAO,CAAC,oBAAoB;oBACtC,QAAQ,EAAE,KAAK,CAAC,iBAAiB;iBAClC;aACF,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { PrincipalPolicyHistoryProgressOptions } from \"@tearleads/crypto\";\nimport type { PutPrincipalPolicyRequest } from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyMutationResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { scopedGroupHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport type { PrincipalPolicyPageReader } from \"../principals/principalPolicyHistoryReader\";\nimport type { PrincipalPolicyRecoveryRuntime } from \"../principals/runtimePolicyRecovery\";\nimport { captureAcknowledgedPrincipalPredecessor } from \"./acknowledgedPrincipalPredecessor\";\nimport type { loadCurrentOrganizationAuthority } from \"./currentOrganizationAuthority\";\nimport {\n type AcknowledgedPrincipalCurrentInput,\n retainAcknowledgedPrincipalCurrents,\n} from \"./retainAcknowledgedPrincipalCurrents\";\n\n/** Couple directory acknowledgements to any newly created group under the same lease. */\nexport async function createCurrentOrganizationMutationRetention(input: {\n readonly runtime: PrincipalPolicyRecoveryRuntime;\n readonly authority: Awaited<\n ReturnType<typeof loadCurrentOrganizationAuthority>\n >;\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly historyReader: PrincipalPolicyPageReader;\n readonly organizationId: string;\n readonly directoryRecovery: AcknowledgedPrincipalCurrentInput[\"recovery\"];\n readonly stillCurrent: () => boolean;\n}) {\n const predecessor = await captureAcknowledgedPrincipalPredecessor({\n ...input.directoryRecovery,\n execSql: input.runtime.infra.execSql,\n organizationId: input.organizationId,\n stillCurrent: input.stillCurrent,\n });\n const retain = async (\n entries: readonly AcknowledgedPrincipalCurrentInput[],\n ) => {\n assertProjectionVerificationCurrent(input.stillCurrent);\n await retainAcknowledgedPrincipalCurrents({\n execSql: input.runtime.infra.execSql,\n organizationId: input.organizationId,\n entries,\n stillCurrent: input.stillCurrent,\n });\n };\n return {\n retainDirectory: (\n request: PutPrincipalPolicyRequest,\n response: PrincipalPolicyMutationResponse,\n ) =>\n retain([\n { predecessor, request, response, recovery: input.directoryRecovery },\n ]),\n retainCreatedGroup: (receipt: {\n readonly request: PutPrincipalPolicyRequest;\n readonly response: PrincipalPolicyMutationResponse;\n readonly organizationRequest: PutPrincipalPolicyRequest;\n readonly organizationResponse: PrincipalPolicyMutationResponse;\n }) => {\n const adminHead = {\n ...principalPolicyReferenceFromBundle(input.authority.admins.current),\n principalType: \"group\" as const,\n };\n return retain([\n {\n initialGroup: true,\n predecessor: null,\n request: receipt.request,\n response: receipt.response,\n recovery: {\n historyReader: input.historyReader,\n expectedHead: principalPolicyReferenceFromBundle(receipt.response),\n protection: scopedGroupHistoryProtection(\n input.protection,\n input.organizationId,\n input.authority.descriptor.adminGroupId,\n ),\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n loadExternalAuthority: async () => ({\n currentHead: adminHead,\n states: [\n {\n head: adminHead,\n projection: input.authority.admins.policy.projection,\n },\n ],\n }),\n },\n },\n {\n predecessor,\n request: receipt.organizationRequest,\n response: receipt.organizationResponse,\n recovery: input.directoryRecovery,\n },\n ]);\n },\n };\n}\n"]}
|
|
@@ -2,13 +2,14 @@ import { assertProjectionVerificationCurrent } from "../../data/keyingProjection
|
|
|
2
2
|
import { readPrincipalHistoryProtection } from "../../data/principals/principalHistoryRuntime.js";
|
|
3
3
|
import { directoryHistoryProtection } from "../../data/principals/principalHistoryScopeProtection.js";
|
|
4
4
|
import { principalPolicyReferenceFromBundle } from "../../data/principals/principalPolicyAdminSigners.js";
|
|
5
|
+
import { apiPrincipalPolicyPageReader, } from "../principals/principalPolicyHistoryReader.js";
|
|
5
6
|
import { createRuntimePrincipalPolicyCurrentResolver, } from "../principals/runtimePolicyRecovery.js";
|
|
6
7
|
/** One lifetime fence and private custody boundary for every current-policy mutation. */
|
|
7
8
|
export function createCurrentPrincipalMutationLease(runtime) {
|
|
8
9
|
const lease = readPrincipalHistoryProtection(runtime);
|
|
9
10
|
const resolveCurrentPolicy = createRuntimePrincipalPolicyCurrentResolver(runtime);
|
|
10
|
-
const
|
|
11
|
-
if (!lease || !resolveCurrentPolicy || !
|
|
11
|
+
const historyReader = apiPrincipalPolicyPageReader(runtime.apiClient);
|
|
12
|
+
if (!lease || !resolveCurrentPolicy || !historyReader)
|
|
12
13
|
return undefined;
|
|
13
14
|
return async (callerCurrent, work) => lease(async ({ protection, stillCurrent: leaseCurrent }) => {
|
|
14
15
|
let active = true;
|
|
@@ -19,9 +20,9 @@ export function createCurrentPrincipalMutationLease(runtime) {
|
|
|
19
20
|
protection,
|
|
20
21
|
stillCurrent,
|
|
21
22
|
resolveCurrentPolicy,
|
|
22
|
-
|
|
23
|
+
historyReader,
|
|
23
24
|
directoryRecovery: (current) => ({
|
|
24
|
-
|
|
25
|
+
historyReader,
|
|
25
26
|
expectedHead: principalPolicyReferenceFromBundle(current),
|
|
26
27
|
protection: directoryHistoryProtection(protection),
|
|
27
28
|
resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"currentPrincipalMutationLease.js","sourceRoot":"","sources":["currentPrincipalMutationLease.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,0BAA0B,EAAE,MAAM,uDAAuD,CAAC;AACnG,OAAO,EAAE,kCAAkC,EAAE,MAAM,mDAAmD,CAAC;AACvG,OAAO,EACL,2CAA2C,GAE5C,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"currentPrincipalMutationLease.js","sourceRoot":"","sources":["currentPrincipalMutationLease.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,0BAA0B,EAAE,MAAM,uDAAuD,CAAC;AACnG,OAAO,EAAE,kCAAkC,EAAE,MAAM,mDAAmD,CAAC;AACvG,OAAO,EACL,4BAA4B,GAE7B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,2CAA2C,GAE5C,MAAM,qCAAqC,CAAC;AAoB7C,yFAAyF;AACzF,MAAM,UAAU,mCAAmC,CACjD,OAAuC;IAEvC,MAAM,KAAK,GAAG,8BAA8B,CAAC,OAAO,CAAC,CAAC;IACtD,MAAM,oBAAoB,GACxB,2CAA2C,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,4BAA4B,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC,KAAK,IAAI,CAAC,oBAAoB,IAAI,CAAC,aAAa;QAAE,OAAO,SAAS,CAAC;IACxE,OAAO,KAAK,EACV,aAA4B,EAC5B,IAAmE,EACvD,EAAE,CACd,KAAK,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,EAAE;QACzD,IAAI,MAAM,GAAG,IAAI,CAAC;QAClB,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC,MAAM,IAAI,YAAY,EAAE,IAAI,aAAa,EAAE,CAAC;QACvE,IAAI,CAAC;YACH,mCAAmC,CAAC,YAAY,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC;gBACxB,UAAU;gBACV,YAAY;gBACZ,oBAAoB;gBACpB,aAAa;gBACb,iBAAiB,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBAC/B,aAAa;oBACb,YAAY,EAAE,kCAAkC,CAAC,OAAO,CAAC;oBACzD,UAAU,EAAE,0BAA0B,CAAC,UAAU,CAAC;oBAClD,0BAA0B,EAAE,OAAO,CAAC,0BAA0B;iBAC/D,CAAC;aACH,CAAC,CAAC;YACH,mCAAmC,CAAC,YAAY,CAAC,CAAC;YAClD,OAAO,MAAM,CAAC;QAChB,CAAC;gBAAS,CAAC;YACT,MAAM,GAAG,KAAK,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import type { PrincipalPolicyPageCurrent } from \"@tearleads/api-client\";\nimport type { PrincipalPolicyHistoryProgressOptions } from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { readPrincipalHistoryProtection } from \"../../data/principals/principalHistoryRuntime\";\nimport { directoryHistoryProtection } from \"../../data/principals/principalHistoryScopeProtection\";\nimport { principalPolicyReferenceFromBundle } from \"../../data/principals/principalPolicyAdminSigners\";\nimport {\n apiPrincipalPolicyPageReader,\n type PrincipalPolicyPageReader,\n} from \"../principals/principalPolicyHistoryReader\";\nimport {\n createRuntimePrincipalPolicyCurrentResolver,\n type PrincipalPolicyRecoveryRuntime,\n} from \"../principals/runtimePolicyRecovery\";\nimport type { AcknowledgedPrincipalCurrentInput } from \"./retainAcknowledgedPrincipalCurrents\";\n\ninterface CurrentPrincipalMutationLeaseContext {\n readonly protection: PrincipalPolicyHistoryProgressOptions;\n readonly stillCurrent: () => boolean;\n readonly resolveCurrentPolicy: NonNullable<\n ReturnType<typeof createRuntimePrincipalPolicyCurrentResolver>\n >;\n readonly historyReader: PrincipalPolicyPageReader;\n readonly directoryRecovery: (\n current: PrincipalPolicyPageCurrent,\n ) => AcknowledgedPrincipalCurrentInput[\"recovery\"];\n}\n\ntype CurrentPrincipalMutationLease = <T>(\n callerCurrent: () => boolean,\n work: (context: CurrentPrincipalMutationLeaseContext) => Promise<T>,\n) => Promise<T>;\n\n/** One lifetime fence and private custody boundary for every current-policy mutation. */\nexport function createCurrentPrincipalMutationLease(\n runtime: PrincipalPolicyRecoveryRuntime,\n): CurrentPrincipalMutationLease | undefined {\n const lease = readPrincipalHistoryProtection(runtime);\n const resolveCurrentPolicy =\n createRuntimePrincipalPolicyCurrentResolver(runtime);\n const historyReader = apiPrincipalPolicyPageReader(runtime.apiClient);\n if (!lease || !resolveCurrentPolicy || !historyReader) return undefined;\n return async <T>(\n callerCurrent: () => boolean,\n work: (context: CurrentPrincipalMutationLeaseContext) => Promise<T>,\n ): Promise<T> =>\n lease(async ({ protection, stillCurrent: leaseCurrent }) => {\n let active = true;\n const stillCurrent = () => active && leaseCurrent() && callerCurrent();\n try {\n assertProjectionVerificationCurrent(stillCurrent);\n const result = await work({\n protection,\n stillCurrent,\n resolveCurrentPolicy,\n historyReader,\n directoryRecovery: (current) => ({\n historyReader,\n expectedHead: principalPolicyReferenceFromBundle(current),\n protection: directoryHistoryProtection(protection),\n resolveTrustedUserIdentity: runtime.resolveTrustedUserIdentity,\n }),\n });\n assertProjectionVerificationCurrent(stillCurrent);\n return result;\n } finally {\n active = false;\n }\n });\n}\n"]}
|
|
@@ -11,8 +11,8 @@ export async function deleteOrganizationGroup(input) {
|
|
|
11
11
|
await input.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);
|
|
12
12
|
assertProjectionVerificationCurrent(stillCurrent);
|
|
13
13
|
const externalAdminPolicy = await loadOrganizationExternalAdminPolicy({
|
|
14
|
+
currentPolicyReader: input.apiClient,
|
|
14
15
|
execSql: input.execSql,
|
|
15
|
-
getCurrentPrincipalPolicy: (principalType, principalId) => input.apiClient.getCurrentPrincipalPolicy(principalType, principalId),
|
|
16
16
|
organizationId: input.organizationId,
|
|
17
17
|
resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,
|
|
18
18
|
stillCurrent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deleteOrganizationGroup.js","sourceRoot":"","sources":["deleteOrganizationGroup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,gDAAgD,EAAE,MAAM,iEAAiE,CAAC;AAGnI,OAAO,EAAE,mCAAmC,EAAE,MAAM,mCAAmC,CAAC;AACxF,OAAO,EACL,2BAA2B,EAC3B,kCAAkC,GACnC,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACL,4CAA4C,EAC5C,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iBAAiB,EACjB,6BAA6B,GAC9B,MAAM,4BAA4B,CAAC;AAEpC,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAgB7C;IACC,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;IACxC,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,KAAK,CAAC,SAAS,CAAC,+BAA+B,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9E,mCAAmC,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,mBAAmB,GAAG,MAAM,mCAAmC,CAAC;QACpE,
|
|
1
|
+
{"version":3,"file":"deleteOrganizationGroup.js","sourceRoot":"","sources":["deleteOrganizationGroup.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SigningKeyPair } from \"@tearleads/crypto\";\nimport type { DeleteOrganizationGroupRequest } from \"@tearleads/validators/request\";\nimport type { DeleteOrganizationGroupResponse } from \"@tearleads/validators/response\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { persistLocallyAcknowledgedPrincipalPolicyBundles } from \"../../data/persistence/locallyAcknowledgedCheckpointPersistence\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport { loadOrganizationExternalAdminPolicy } from \"../principals/externalAdminPolicy\";\nimport {\n acknowledgeGroupPolicyState,\n buildAcknowledgedGroupPolicyBundle,\n} from \"./groupPolicyMutationAcknowledgement\";\nimport type { PrincipalPolicyReadApi } from \"./groupPolicyMutationContext\";\nimport { groupPolicyMutationHead } from \"./groupPolicyMutationHead\";\nimport {\n buildOrganizationGroupDirectoryPolicyRequest,\n removeOrganizationGroupHead,\n} from \"./organizationGroupDirectory\";\nimport {\n projectionUserIds,\n resolveRequiredUserIdentities,\n} from \"./trustedOrganizationUsers\";\n\nexport async function deleteOrganizationGroup(input: {\n readonly apiClient: PrincipalPolicyReadApi & {\n deleteOrganizationGroup: (\n organizationId: string,\n groupId: string,\n request: DeleteOrganizationGroupRequest,\n ) => Promise<DeleteOrganizationGroupResponse | null>;\n };\n readonly execSql: ExecSql;\n readonly groupId: string;\n readonly organizationId: string;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<DeleteOrganizationGroupResponse> {\n const stillCurrent = input.stillCurrent;\n assertProjectionVerificationCurrent(stillCurrent);\n await input.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);\n assertProjectionVerificationCurrent(stillCurrent);\n const externalAdminPolicy = await loadOrganizationExternalAdminPolicy({\n currentPolicyReader: input.apiClient,\n execSql: input.execSql,\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n if (!externalAdminPolicy?.signerUserIds.includes(input.signerUserId)) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n const adminProjection = externalAdminPolicy.adminBundle.currentProjection;\n const adminUsers = await resolveRequiredUserIdentities({\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n userIds: projectionUserIds(adminProjection),\n });\n const organizationRequest =\n await buildOrganizationGroupDirectoryPolicyRequest({\n adminProjection,\n adminUsers,\n currentPolicy: externalAdminPolicy.bundle,\n descriptor: externalAdminPolicy.descriptor,\n groupHeads: removeOrganizationGroupHead({\n descriptor: externalAdminPolicy.descriptor,\n groupId: input.groupId,\n }),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n const stored = await input.apiClient.deleteOrganizationGroup(\n input.organizationId,\n input.groupId,\n { organizationPolicy: organizationRequest },\n );\n assertProjectionVerificationCurrent(stillCurrent);\n if (!stored) {\n throw new Error(\"Group could not be deleted\");\n }\n if (\n stored.organizationId !== input.organizationId ||\n stored.groupId !== input.groupId\n ) {\n throw new Error(\"Group deletion response target mismatch\");\n }\n const organizationHead = await groupPolicyMutationHead(organizationRequest);\n const organizationPolicy = await acknowledgeGroupPolicyState({\n currentPolicy: externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy.currentState,\n });\n const organizationBundle = buildAcknowledgedGroupPolicyBundle({\n currentPolicy: externalAdminPolicy.bundle,\n expectedHead: organizationHead,\n request: organizationRequest,\n response: stored.organizationPolicy,\n });\n await persistLocallyAcknowledgedPrincipalPolicyBundles({\n entries: [{ bundle: organizationBundle, policy: organizationPolicy }],\n execSql: input.execSql,\n organizationId: input.organizationId,\n updatedAt: new Date().toISOString(),\n stillCurrent,\n });\n assertProjectionVerificationCurrent(stillCurrent);\n return stored;\n}\n"]}
|
|
@@ -8,8 +8,8 @@ export async function createOrganizationGroup(input) {
|
|
|
8
8
|
await input.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);
|
|
9
9
|
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
10
10
|
const externalAdminPolicy = await loadOrganizationExternalAdminPolicy({
|
|
11
|
+
currentPolicyReader: input.apiClient,
|
|
11
12
|
execSql: input.execSql,
|
|
12
|
-
getCurrentPrincipalPolicy: (principalType, principalId) => input.apiClient.getCurrentPrincipalPolicy(principalType, principalId),
|
|
13
13
|
organizationId: input.organizationId,
|
|
14
14
|
resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,
|
|
15
15
|
stillCurrent: input.stillCurrent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupCreation.js","sourceRoot":"","sources":["groupCreation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AAIpG,OAAO,EAAE,mCAAmC,EAAE,MAAM,mCAAmC,CAAC;AAExF,OAAO,EACL,gBAAgB,GAEjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAG1E,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAa7C;IACC,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,CAAC,SAAS,CAAC,+BAA+B,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC9E,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,mBAAmB,GAAG,MAAM,mCAAmC,CAAC;QACpE,
|
|
1
|
+
{"version":3,"file":"groupCreation.js","sourceRoot":"","sources":["groupCreation.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EncapsulationKeyPair, SigningKeyPair } from \"@tearleads/crypto\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport type { SecurityIncidentReporter } from \"../../data/securityIncidents\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport type { TrustedUserIdentityResolver } from \"../../data/trustedUserIdentity\";\nimport { loadOrganizationExternalAdminPolicy } from \"../principals/externalAdminPolicy\";\nimport type { createGroupMetadataAccess } from \"./groupMetadataAccess\";\nimport {\n cacheGroupPolicy,\n type OrganizationPrincipalPolicyApi,\n} from \"./groupPolicyMutationContext\";\nimport { commitCreatedGroupToDirectory } from \"./organizationGroupDirectory\";\nimport { buildInitialGroupPolicyRequest } from \"./principalPolicyRequest\";\nimport type { OrganizationGroupSummary } from \"./readModel\";\n\nexport async function createOrganizationGroup(input: {\n readonly metadataAccess: ReturnType<typeof createGroupMetadataAccess>;\n readonly apiClient: OrganizationPrincipalPolicyApi;\n readonly creatorEncapsulationKeyPair: EncapsulationKeyPair;\n readonly execSql: ExecSql;\n readonly name: string;\n readonly organizationId: string;\n readonly reportSecurityIncident: SecurityIncidentReporter;\n readonly resolveTrustedUserIdentity: TrustedUserIdentityResolver;\n readonly signerUserId: string;\n readonly signingFingerprint: string;\n readonly signingKeyPair: SigningKeyPair;\n readonly stillCurrent?: (() => boolean) | undefined;\n}): Promise<OrganizationGroupSummary> {\n assertProjectionVerificationCurrent(input.stillCurrent);\n await input.apiClient.recoverPendingPrincipalMutation?.(input.organizationId);\n assertProjectionVerificationCurrent(input.stillCurrent);\n const externalAdminPolicy = await loadOrganizationExternalAdminPolicy({\n currentPolicyReader: input.apiClient,\n execSql: input.execSql,\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!externalAdminPolicy) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n if (!externalAdminPolicy.signerUserIds.includes(input.signerUserId)) {\n throw new Error(\"Organization admin authority could not be verified\");\n }\n const request = await buildInitialGroupPolicyRequest({\n creatorEncapsulationKeyPair: input.creatorEncapsulationKeyPair,\n externalAuthority: externalAdminPolicy.externalAuthority.currentHead,\n groupId: crypto.randomUUID(),\n includeSignerAsAdmin: false,\n name: input.name,\n metadataKey: await input.metadataAccess.loadEncryptionKey(),\n signerUserId: input.signerUserId,\n signingFingerprint: input.signingFingerprint,\n signingKeyPair: input.signingKeyPair,\n });\n const { group, head: expectedHead } = await commitCreatedGroupToDirectory({\n ...input,\n externalAdminPolicy,\n readEncryptedName: input.metadataAccess.readName,\n request,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n await cacheGroupPolicy({\n acknowledgedMemberEnvelopes: {\n envelopes: request.initialGroupPolicy.memberEnvelopes,\n epoch: request.initialGroupPolicy.state.keyEpoch,\n principalId: request.groupId,\n principalType: \"group\",\n stateHash: expectedHead.stateHash,\n },\n apiClient: input.apiClient,\n execSql: input.execSql,\n expectedCurrentHead: expectedHead,\n externalAuthority: externalAdminPolicy.externalAuthority,\n groupId: group.groupId,\n localPolicyCheckpoint: {\n principalId: request.groupId,\n principalType: \"group\",\n stateHash: expectedHead.stateHash,\n version: expectedHead.version,\n },\n organizationId: input.organizationId,\n resolveTrustedUserIdentity: input.resolveTrustedUserIdentity,\n stillCurrent: input.stillCurrent,\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n return { ...group, name: input.name.trim(), nameUnreadable: false };\n}\n"]}
|