@tearleads/client-sdk 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/organizations/organizationGroupHistory.js +4 -7
- package/client/organizations/organizationGroupHistory.js.map +1 -1
- package/client/organizations/organizationReadModels.js +2 -86
- package/client/organizations/organizationReadModels.js.map +1 -1
- package/client/organizations/principalMutations.js +53 -133
- package/client/organizations/principalMutations.js.map +1 -1
- package/client/principalMutationDispatch.js +2 -2
- package/client/principalMutationDispatch.js.map +1 -1
- package/data/keyingProjectionVerification/principalPolicyVerification.js +5 -5
- package/data/keyingProjectionVerification/principalPolicyVerification.js.map +1 -1
- package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js +21 -7
- package/data/keyingProjectionVerification/resolvedPrincipalPolicy.js.map +1 -1
- package/data/keyingProjectionVerification/types.d.ts +1 -8
- package/data/keyingProjectionVerification/types.js +0 -9
- package/data/keyingProjectionVerification/types.js.map +1 -1
- package/data/keyingProjectionVerification.d.ts +1 -1
- package/data/keyingProjectionVerification.js.map +1 -1
- package/data/persistence/principalHistoryPrefixPersistence.d.ts +5 -1
- package/data/persistence/principalHistoryPrefixPersistence.js +22 -5
- package/data/persistence/principalHistoryPrefixPersistence.js.map +1 -1
- package/data/principals/principalMutationJournalShape.d.ts +1 -1
- package/data/principals/principalMutationJournalShape.js +2 -2
- package/data/principals/principalMutationJournalShape.js.map +1 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/container-state/groupGrantVerification.js +23 -74
- package/workflows/container-contents/container-state/groupGrantVerification.js.map +1 -1
- package/workflows/container-contents/container-state/groupShareEpoch.js +6 -23
- package/workflows/container-contents/container-state/groupShareEpoch.js.map +1 -1
- package/workflows/container-contents/container-state/remote.js +5 -3
- package/workflows/container-contents/container-state/remote.js.map +1 -1
- package/workflows/container-contents/container-state/types.js.map +1 -1
- package/workflows/container-contents/documentLinks.d.ts +1 -1
- package/workflows/container-contents/documentLinks.js.map +1 -1
- package/workflows/container-contents/documentPurge.d.ts +1 -1
- package/workflows/container-contents/documentPurge.js.map +1 -1
- package/workflows/container-contents/metadataRemoteSync.d.ts +1 -1
- package/workflows/container-contents/metadataRemoteSync.js.map +1 -1
- package/workflows/container-contents/remoteHydration/types.d.ts +2 -2
- package/workflows/container-contents/remoteHydration/types.js.map +1 -1
- package/workflows/container-contents/remoteHydration/verifiedDestination.js +6 -7
- package/workflows/container-contents/remoteHydration/verifiedDestination.js.map +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js +1 -1
- package/workflows/containers/child/runtimeCurrentGroupShare.js.map +1 -1
- package/workflows/organizations/groupMetadataRuntime.js +11 -8
- package/workflows/organizations/groupMetadataRuntime.js.map +1 -1
- package/workflows/organizations/organizationGroupNames.js +8 -55
- package/workflows/organizations/organizationGroupNames.js.map +1 -1
- package/workflows/organizations/principalOperationReceipt.js +1 -1
- package/workflows/organizations/principalOperationReceipt.js.map +1 -1
- package/workflows/organizations/runtimeGroupMetadataAuthority.js +16 -0
- package/workflows/organizations/runtimeGroupMetadataAuthority.js.map +1 -0
- package/workflows/principals/runtimePolicyWarmer.js +29 -27
- package/workflows/principals/runtimePolicyWarmer.js.map +1 -1
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
|
|
2
2
|
import { assertProjectionVerificationCurrent } from "../../data/keyingProjectionVerification/types.js";
|
|
3
3
|
import { loadLocalOrganizationPolicyReference } from "../../workflows/organizations/index.js";
|
|
4
4
|
import { buildOrganizationGroupPolicyHistoryPage } from "../../workflows/organizations/groupPolicyHistoryPage.js";
|
|
5
5
|
import { createRuntimePrincipalPolicyCurrentResolver } from "../../workflows/principals/runtimePolicyRecovery.js";
|
|
6
|
-
/**
|
|
6
|
+
/** All group history reads use the private paged verifier. */
|
|
7
7
|
export async function loadBoundedOrganizationGroupHistory(input) {
|
|
8
8
|
const { active } = input;
|
|
9
9
|
const resolve = createRuntimePrincipalPolicyCurrentResolver(active.runtime);
|
|
10
|
-
if (!resolve)
|
|
11
|
-
|
|
12
|
-
throw new KeyingVerificationError("invalid_shape", "This host cannot resolve a group history page cursor");
|
|
13
|
-
return undefined;
|
|
14
|
-
}
|
|
10
|
+
if (!resolve)
|
|
11
|
+
throw new ProjectionDependencyUnavailableError("Group history requires private paged recovery");
|
|
15
12
|
assertProjectionVerificationCurrent(input.stillCurrent);
|
|
16
13
|
const reference = await loadLocalOrganizationPolicyReference({
|
|
17
14
|
currentUserId: active.userId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationGroupHistory.js","sourceRoot":"","sources":["organizationGroupHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"organizationGroupHistory.js","sourceRoot":"","sources":["organizationGroupHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,+DAA+D,CAAC;AACrH,OAAO,EAAE,mCAAmC,EAAE,MAAM,+CAA+C,CAAC;AACpG,OAAO,EAAE,oCAAoC,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,uCAAuC,EAAE,MAAM,sDAAsD,CAAC;AAC/G,OAAO,EAAE,2CAA2C,EAAE,MAAM,kDAAkD,CAAC;AAG/G,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,mCAAmC,CAAC,KAKzD;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACzB,MAAM,OAAO,GAAG,2CAA2C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5E,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,oCAAoC,CAC5C,+CAA+C,CAChD,CAAC;IACJ,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,MAAM,oCAAoC,CAAC;QAC3D,aAAa,EAAE,MAAM,CAAC,MAAM;QAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;QACrC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,WAAW,EAAE,KAAK,CAAC,OAAO;QAC1B,aAAa,EAAE,OAAO;KACvB,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS;QACT,kBAAkB,EAAE,IAAI;QACxB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,WAAW,EACT,KAAK,CAAC,aAAa,KAAK,SAAS;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE;KAC7C,CAAC,CAAC;IACH,mCAAmC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ,CAAC,WAAW;QACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,OAAO,uCAAuC,CAAC;QAC7C,IAAI,EAAE,QAAQ,CAAC,WAAW;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { assertProjectionVerificationCurrent } from \"../../data/keyingProjectionVerification/types\";\nimport { loadLocalOrganizationPolicyReference } from \"../../workflows/organizations\";\nimport { buildOrganizationGroupPolicyHistoryPage } from \"../../workflows/organizations/groupPolicyHistoryPage\";\nimport { createRuntimePrincipalPolicyCurrentResolver } from \"../../workflows/principals/runtimePolicyRecovery\";\nimport type { ActiveOrganizationDataRuntime } from \"./organizationWorkflowRuntime\";\n\n/** All group history reads use the private paged verifier. */\nexport async function loadBoundedOrganizationGroupHistory(input: {\n readonly active: ActiveOrganizationDataRuntime;\n readonly groupId: string;\n readonly beforeVersion?: number | undefined;\n readonly stillCurrent: () => boolean;\n}) {\n const { active } = input;\n const resolve = createRuntimePrincipalPolicyCurrentResolver(active.runtime);\n if (!resolve)\n throw new ProjectionDependencyUnavailableError(\n \"Group history requires private paged recovery\",\n );\n assertProjectionVerificationCurrent(input.stillCurrent);\n const reference = await loadLocalOrganizationPolicyReference({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n principalId: input.groupId,\n principalType: \"group\",\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!reference) return null;\n const resolved = await resolve({\n organizationId: active.organizationId,\n reference,\n preferLocalCurrent: true,\n stillCurrent: input.stillCurrent,\n historyPage:\n input.beforeVersion === undefined\n ? {}\n : { beforeVersion: input.beforeVersion },\n });\n assertProjectionVerificationCurrent(input.stillCurrent);\n if (!resolved.historyPage)\n throw new Error(\"Verified history page is missing\");\n return buildOrganizationGroupPolicyHistoryPage({\n page: resolved.historyPage,\n groupId: input.groupId,\n organizationId: active.organizationId,\n });\n}\n"]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { loadLocalOrganizationContainerGrants, loadLocalOrganizationDirectoryAndGroups, loadLocalOrganizationGroupContainers, loadLocalOrganizationGroupMembers,
|
|
1
|
+
import { loadLocalOrganizationContainerGrants, loadLocalOrganizationDirectoryAndGroups, loadLocalOrganizationGroupContainers, loadLocalOrganizationGroupMembers, loadLocalOrganizationUserDetail, reconcileOrganizationDirectoryAndGroups, } from "../../workflows/organizations/index.js";
|
|
2
2
|
import { organizationAccessScopeKey, wasOrganizationPresentationAccessDeniedByServer, } from "../../workflows/organizations/organizationPresentationAccessState.js";
|
|
3
|
-
import { createRuntimePrincipalPolicyWarmer } from "../../workflows/principals/runtimePolicyWarmer.js";
|
|
4
3
|
import { recoverOrganizationAccess } from "./organizationAccessRestoration.js";
|
|
5
4
|
import { loadBoundedOrganizationGroupHistory } from "./organizationGroupHistory.js";
|
|
6
5
|
import { hydrateOrganizationGroupNamesForRuntime } from "./organizationGroupNameHydration.js";
|
|
@@ -10,7 +9,6 @@ const coordinatorsByRuntime = new WeakMap();
|
|
|
10
9
|
class OrganizationReadModelCoordinatorImpl {
|
|
11
10
|
runtimeService;
|
|
12
11
|
reconciliationsByScope = new WeakMap();
|
|
13
|
-
policyWarmersByScope = new WeakMap();
|
|
14
12
|
constructor(runtimeService) {
|
|
15
13
|
this.runtimeService = runtimeService;
|
|
16
14
|
}
|
|
@@ -23,75 +21,6 @@ class OrganizationReadModelCoordinatorImpl {
|
|
|
23
21
|
}
|
|
24
22
|
return byKey;
|
|
25
23
|
}
|
|
26
|
-
policyWarmerMap(active) {
|
|
27
|
-
const scope = active.runtime.state.domainScope;
|
|
28
|
-
let byKey = this.policyWarmersByScope.get(scope);
|
|
29
|
-
if (!byKey) {
|
|
30
|
-
byKey = new Map();
|
|
31
|
-
this.policyWarmersByScope.set(scope, byKey);
|
|
32
|
-
}
|
|
33
|
-
return byKey;
|
|
34
|
-
}
|
|
35
|
-
async warmPolicyReference(active, reference) {
|
|
36
|
-
if (!active.runtime.state.online) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const byKey = this.policyWarmerMap(active);
|
|
40
|
-
const key = `${active.organizationId}\0${reference.principalType}\0${reference.principalId}\0${reference.stateHash}`;
|
|
41
|
-
const existing = byKey.get(key);
|
|
42
|
-
if (existing) {
|
|
43
|
-
return existing;
|
|
44
|
-
}
|
|
45
|
-
const warming = createRuntimePrincipalPolicyWarmer(active.runtime)({
|
|
46
|
-
organizationId: active.organizationId,
|
|
47
|
-
references: [reference],
|
|
48
|
-
}).finally(() => {
|
|
49
|
-
if (byKey.get(key) === warming) {
|
|
50
|
-
byKey.delete(key);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
byKey.set(key, warming);
|
|
54
|
-
return warming;
|
|
55
|
-
}
|
|
56
|
-
async loadPolicyHistoryAfterWarm(input) {
|
|
57
|
-
try {
|
|
58
|
-
const local = await input.loadLocal();
|
|
59
|
-
if (local) {
|
|
60
|
-
return local;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
input.active.runtime.util.logError("Failed to load verified organization policy history", error);
|
|
65
|
-
}
|
|
66
|
-
if (!input.active.runtime.state.online) {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
let reference;
|
|
70
|
-
try {
|
|
71
|
-
reference = await loadLocalOrganizationPolicyReference({
|
|
72
|
-
currentUserId: input.active.userId,
|
|
73
|
-
execSql: input.active.runtime.infra.execSql,
|
|
74
|
-
organizationId: input.active.organizationId,
|
|
75
|
-
principalId: input.principalId,
|
|
76
|
-
principalType: input.principalType,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
input.active.runtime.util.logError("Failed to load organization policy-head projection", error);
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
if (!reference) {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
await this.warmPolicyReference(input.active, reference);
|
|
87
|
-
try {
|
|
88
|
-
return await input.loadLocal();
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
input.active.runtime.util.logError("Failed to reload verified organization policy history", error);
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
24
|
async loadLocal(organizationId) {
|
|
96
25
|
const active = activeOrganizationDataRuntime(this.runtimeService, organizationId);
|
|
97
26
|
if (!active) {
|
|
@@ -144,25 +73,12 @@ class OrganizationReadModelCoordinatorImpl {
|
|
|
144
73
|
return null;
|
|
145
74
|
}
|
|
146
75
|
const domainScope = active.runtime.state.domainScope;
|
|
147
|
-
|
|
76
|
+
return loadBoundedOrganizationGroupHistory({
|
|
148
77
|
active,
|
|
149
78
|
groupId,
|
|
150
79
|
beforeVersion,
|
|
151
80
|
stillCurrent: () => isOrganizationDataRuntimeCurrent(this.runtimeService, active, domainScope),
|
|
152
81
|
});
|
|
153
|
-
if (bounded !== undefined)
|
|
154
|
-
return bounded;
|
|
155
|
-
return this.loadPolicyHistoryAfterWarm({
|
|
156
|
-
active,
|
|
157
|
-
loadLocal: () => loadLocalOrganizationGroupPolicyHistory({
|
|
158
|
-
currentUserId: active.userId,
|
|
159
|
-
execSql: active.runtime.infra.execSql,
|
|
160
|
-
groupId,
|
|
161
|
-
organizationId: active.organizationId,
|
|
162
|
-
}),
|
|
163
|
-
principalId: groupId,
|
|
164
|
-
principalType: "group",
|
|
165
|
-
});
|
|
166
82
|
}
|
|
167
83
|
async loadOrganizationPolicyHistory(organizationId, beforeVersion) {
|
|
168
84
|
const active = activeOrganizationDataRuntime(this.runtimeService, organizationId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizationReadModels.js","sourceRoot":"","sources":["organizationReadModels.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../../data/domainScope\";\nimport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupMembers,\n loadLocalOrganizationGroupPolicyHistory,\n loadLocalOrganizationPolicyReference,\n loadLocalOrganizationUserDetail,\n type OrganizationContainerGrants,\n type OrganizationDirectoryAndGroups,\n type OrganizationGroupContainers,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationPolicyHistory,\n type OrganizationUserDetail,\n reconcileOrganizationDirectoryAndGroups,\n} from \"../../workflows/organizations\";\nimport {\n organizationAccessScopeKey,\n wasOrganizationPresentationAccessDeniedByServer,\n} from \"../../workflows/organizations/organizationPresentationAccessState\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../workflows/principals/runtimePolicyWarmer\";\nimport type { InternalRuntime } from \"../workflowRuntime\";\nimport { recoverOrganizationAccess } from \"./organizationAccessRestoration\";\nimport { loadBoundedOrganizationGroupHistory } from \"./organizationGroupHistory\";\nimport { hydrateOrganizationGroupNamesForRuntime } from \"./organizationGroupNameHydration\";\nimport { loadBoundedOrganizationHistory } from \"./organizationHistory\";\nimport {\n type ActiveOrganizationDataRuntime,\n activeOrganizationDataRuntime,\n isOrganizationDataRuntimeCurrent,\n} from \"./organizationWorkflowRuntime\";\n\nconst coordinatorsByRuntime = new WeakMap<\n InternalRuntime,\n OrganizationReadModelCoordinator\n>();\n\nexport interface OrganizationReadModelCoordinator {\n loadLocal(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null>;\n loadLocalGroupMembers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupMembers | null>;\n loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationGroupPolicyHistory | null>;\n loadOrganizationPolicyHistory(\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationPolicyHistory | null>;\n loadLocalGrants(\n organizationId?: string | undefined,\n ): Promise<OrganizationContainerGrants | null>;\n loadLocalGroupContainers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupContainers | null>;\n loadLocalUserDetail(\n userId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationUserDetail | null>;\n /**\n * Resolves `undefined` when the runtime declines without I/O (offline,\n * database not ready, organization mismatch) or when the feed failed with\n * no locally retained projection — passes that must not count as caught\n * up; `null` when the reconcile completed but produced nothing presentable\n * — including an authoritative denial that purged the projection, which\n * consumers must repaint.\n */\n reconcile(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n reconcileAfterMutation(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n}\n\nclass OrganizationReadModelCoordinatorImpl\n implements OrganizationReadModelCoordinator\n{\n private readonly reconciliationsByScope = new WeakMap<\n DomainScope,\n Map<string, Promise<OrganizationDirectoryAndGroups | null | undefined>>\n >();\n private readonly policyWarmersByScope = new WeakMap<\n DomainScope,\n Map<string, Promise<void>>\n >();\n\n constructor(private readonly runtimeService: InternalRuntime) {}\n\n private reconciliationMap(active: ActiveOrganizationDataRuntime) {\n const scope = active.runtime.state.domainScope;\n let byKey = this.reconciliationsByScope.get(scope);\n if (!byKey) {\n byKey = new Map();\n this.reconciliationsByScope.set(scope, byKey);\n }\n return byKey;\n }\n\n private policyWarmerMap(active: ActiveOrganizationDataRuntime) {\n const scope = active.runtime.state.domainScope;\n let byKey = this.policyWarmersByScope.get(scope);\n if (!byKey) {\n byKey = new Map();\n this.policyWarmersByScope.set(scope, byKey);\n }\n return byKey;\n }\n\n private async warmPolicyReference(\n active: ActiveOrganizationDataRuntime,\n reference: NonNullable<\n Awaited<ReturnType<typeof loadLocalOrganizationPolicyReference>>\n >,\n ): Promise<void> {\n if (!active.runtime.state.online) {\n return;\n }\n const byKey = this.policyWarmerMap(active);\n const key = `${active.organizationId}\\0${reference.principalType}\\0${reference.principalId}\\0${reference.stateHash}`;\n const existing = byKey.get(key);\n if (existing) {\n return existing;\n }\n const warming = createRuntimePrincipalPolicyWarmer(active.runtime)({\n organizationId: active.organizationId,\n references: [reference],\n }).finally(() => {\n if (byKey.get(key) === warming) {\n byKey.delete(key);\n }\n });\n byKey.set(key, warming);\n return warming;\n }\n\n private async loadPolicyHistoryAfterWarm<History>(input: {\n readonly active: ActiveOrganizationDataRuntime;\n readonly loadLocal: () => Promise<History | null>;\n readonly principalId: string;\n readonly principalType: \"group\" | \"organization\";\n }): Promise<History | null> {\n try {\n const local = await input.loadLocal();\n if (local) {\n return local;\n }\n } catch (error) {\n input.active.runtime.util.logError(\n \"Failed to load verified organization policy history\",\n error,\n );\n }\n if (!input.active.runtime.state.online) {\n return null;\n }\n\n let reference: Awaited<\n ReturnType<typeof loadLocalOrganizationPolicyReference>\n >;\n try {\n reference = await loadLocalOrganizationPolicyReference({\n currentUserId: input.active.userId,\n execSql: input.active.runtime.infra.execSql,\n organizationId: input.active.organizationId,\n principalId: input.principalId,\n principalType: input.principalType,\n });\n } catch (error) {\n input.active.runtime.util.logError(\n \"Failed to load organization policy-head projection\",\n error,\n );\n return null;\n }\n if (!reference) {\n return null;\n }\n\n await this.warmPolicyReference(input.active, reference);\n try {\n return await input.loadLocal();\n } catch (error) {\n input.active.runtime.util.logError(\n \"Failed to reload verified organization policy history\",\n error,\n );\n return null;\n }\n }\n\n async loadLocal(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationDirectoryAndGroups({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGrants(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationContainerGrants({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupContainers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupContainers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupMembers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupMembers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n const domainScope = active.runtime.state.domainScope;\n const bounded = await loadBoundedOrganizationGroupHistory({\n active,\n groupId,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n if (bounded !== undefined) return bounded;\n return this.loadPolicyHistoryAfterWarm({\n active,\n loadLocal: () =>\n loadLocalOrganizationGroupPolicyHistory({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n }),\n principalId: groupId,\n principalType: \"group\",\n });\n }\n\n async loadOrganizationPolicyHistory(\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) return null;\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationHistory({\n active,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadLocalUserDetail(userId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || userId.length === 0) {\n return null;\n }\n return loadLocalOrganizationUserDetail({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n userId,\n });\n }\n\n reconcile(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return Promise.resolve(undefined);\n }\n\n const byKey = this.reconciliationMap(active);\n const key = organizationAccessScopeKey(\n active.organizationId,\n active.userId,\n );\n const existing = byKey.get(key);\n if (existing) {\n return existing;\n }\n\n // Snapshot the server-denied flag before reconciling. A reconcile that\n // flips it back to readable means org access was just restored (e.g. the\n // user was re-added to a group), and any write lanes idled by\n // permission-denied submissions have no self re-arm — regaining access is\n // their retry signal, mirroring how billing recovery re-requests all\n // lanes. Only a genuine server denial counts: a local session reset also\n // marks scopes denied, and re-arming on its first reconcile would race the\n // startup sync passes (e.g. pending-create adoption between panes).\n const accessWasDenied = wasOrganizationPresentationAccessDeniedByServer(\n {\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n requesterUserId: active.userId,\n },\n \"readModel\",\n );\n const domainScope = active.runtime.state.domainScope;\n const stillCurrent = () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n );\n\n const reconciliation = reconcileOrganizationDirectoryAndGroups({\n apiClient: active.runtime.apiClient,\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n logError: active.runtime.util.logError,\n organizationId: active.organizationId,\n })\n .then(async (directoryAndGroups) => {\n if (!stillCurrent()) return null;\n // Feed success restores retry eligibility even if name decryption fails.\n const accessWasRestored =\n accessWasDenied &&\n directoryAndGroups !== null &&\n directoryAndGroups !== undefined;\n if (accessWasRestored)\n await recoverOrganizationAccess({\n active,\n domainScope,\n stillCurrent,\n });\n if (!stillCurrent()) return null;\n return hydrateOrganizationGroupNamesForRuntime(\n this.runtimeService,\n active,\n domainScope,\n directoryAndGroups,\n );\n })\n .finally(() => {\n if (byKey.get(key) === reconciliation) {\n byKey.delete(key);\n }\n });\n byKey.set(key, reconciliation);\n return reconciliation;\n }\n\n async reconcileAfterMutation(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return undefined;\n }\n const existing = this.reconciliationMap(active).get(\n organizationAccessScopeKey(active.organizationId, active.userId),\n );\n if (existing) {\n await existing.catch(() => null);\n }\n return this.reconcile(active.organizationId);\n }\n}\n\nexport function createOrganizationReadModelCoordinator(\n runtimeService: InternalRuntime,\n): OrganizationReadModelCoordinator {\n const existing = coordinatorsByRuntime.get(runtimeService);\n if (existing) {\n return existing;\n }\n\n const coordinator = new OrganizationReadModelCoordinatorImpl(runtimeService);\n coordinatorsByRuntime.set(runtimeService, coordinator);\n return coordinator;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"organizationReadModels.js","sourceRoot":"","sources":["organizationReadModels.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oCAAoC,EACpC,uCAAuC,EACvC,oCAAoC,EACpC,iCAAiC,EACjC,+BAA+B,EAQ/B,uCAAuC,GACxC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,0BAA0B,EAC1B,+CAA+C,GAChD,MAAM,mEAAmE,CAAC;AAE3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,mCAAmC,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,uCAAuC,EAAE,MAAM,kCAAkC,CAAC;AAC3F,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAEL,6BAA6B,EAC7B,gCAAgC,GACjC,MAAM,+BAA+B,CAAC;AAEvC,MAAM,qBAAqB,GAAG,IAAI,OAAO,EAGtC,CAAC;AA8CJ,MAAM,oCAAoC;IAOX;IAJZ,sBAAsB,GAAG,IAAI,OAAO,EAGlD,CAAC;IACJ,YAA6B,cAA+B;QAA/B,mBAAc,GAAd,cAAc,CAAiB;IAAG,CAAC;IAExD,iBAAiB,CAAC,MAAqC;QAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QAC/C,IAAI,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,cAAuB;QACrC,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,uCAAuC,CAAC;YAC7C,aAAa,EAAE,MAAM,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,cAAuB;QAC3C,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,oCAAoC,CAAC;YAC1C,aAAa,EAAE,MAAM,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,OAAe,EAAE,cAAuB;QACrE,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,oCAAoC,CAAC;YAC1C,aAAa,EAAE,MAAM,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,OAAO;YACP,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,OAAe,EAAE,cAAuB;QAClE,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,iCAAiC,CAAC;YACvC,aAAa,EAAE,MAAM,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,OAAO;YACP,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,OAAe,EACf,cAAuB,EACvB,aAAsB;QAEtB,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QACrD,OAAO,mCAAmC,CAAC;YACzC,MAAM;YACN,OAAO;YACP,aAAa;YACb,YAAY,EAAE,GAAG,EAAE,CACjB,gCAAgC,CAC9B,IAAI,CAAC,cAAc,EACnB,MAAM,EACN,WAAW,CACZ;SACJ,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,6BAA6B,CACjC,cAAuB,EACvB,aAAsB;QAEtB,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QACrD,OAAO,8BAA8B,CAAC;YACpC,MAAM;YACN,aAAa;YACb,YAAY,EAAE,GAAG,EAAE,CACjB,gCAAgC,CAC9B,IAAI,CAAC,cAAc,EACnB,MAAM,EACN,WAAW,CACZ;SACJ,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,MAAc,EAAE,cAAuB;QAC/D,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,+BAA+B,CAAC;YACrC,aAAa,EAAE,MAAM,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,MAAM;SACP,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CACP,cAAuB;QAEvB,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,0BAA0B,CACpC,MAAM,CAAC,cAAc,EACrB,MAAM,CAAC,MAAM,CACd,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,uEAAuE;QACvE,yEAAyE;QACzE,8DAA8D;QAC9D,0EAA0E;QAC1E,qEAAqE;QACrE,yEAAyE;QACzE,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,eAAe,GAAG,+CAA+C,CACrE;YACE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,eAAe,EAAE,MAAM,CAAC,MAAM;SAC/B,EACD,WAAW,CACZ,CAAC;QACF,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;QACrD,MAAM,YAAY,GAAG,GAAG,EAAE,CACxB,gCAAgC,CAC9B,IAAI,CAAC,cAAc,EACnB,MAAM,EACN,WAAW,CACZ,CAAC;QAEJ,MAAM,cAAc,GAAG,uCAAuC,CAAC;YAC7D,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;YACnC,aAAa,EAAE,MAAM,CAAC,MAAM;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO;YACrC,QAAQ,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ;YACtC,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC;aACC,IAAI,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE;YACjC,IAAI,CAAC,YAAY,EAAE;gBAAE,OAAO,IAAI,CAAC;YACjC,yEAAyE;YACzE,MAAM,iBAAiB,GACrB,eAAe;gBACf,kBAAkB,KAAK,IAAI;gBAC3B,kBAAkB,KAAK,SAAS,CAAC;YACnC,IAAI,iBAAiB;gBACnB,MAAM,yBAAyB,CAAC;oBAC9B,MAAM;oBACN,WAAW;oBACX,YAAY;iBACb,CAAC,CAAC;YACL,IAAI,CAAC,YAAY,EAAE;gBAAE,OAAO,IAAI,CAAC;YACjC,OAAO,uCAAuC,CAC5C,IAAI,CAAC,cAAc,EACnB,MAAM,EACN,WAAW,EACX,kBAAkB,CACnB,CAAC;QACJ,CAAC,CAAC;aACD,OAAO,CAAC,GAAG,EAAE;YACZ,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,cAAc,EAAE,CAAC;gBACtC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QACL,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC/B,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,cAAuB;QAEvB,MAAM,MAAM,GAAG,6BAA6B,CAC1C,IAAI,CAAC,cAAc,EACnB,cAAc,CACf,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,GAAG,CACjD,0BAA0B,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,CACjE,CAAC;QACF,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC;CACF;AAED,MAAM,UAAU,sCAAsC,CACpD,cAA+B;IAE/B,MAAM,QAAQ,GAAG,qBAAqB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC3D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,oCAAoC,CAAC,cAAc,CAAC,CAAC;IAC7E,qBAAqB,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;IACvD,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import type { DomainScope } from \"../../data/domainScope\";\nimport {\n loadLocalOrganizationContainerGrants,\n loadLocalOrganizationDirectoryAndGroups,\n loadLocalOrganizationGroupContainers,\n loadLocalOrganizationGroupMembers,\n loadLocalOrganizationUserDetail,\n type OrganizationContainerGrants,\n type OrganizationDirectoryAndGroups,\n type OrganizationGroupContainers,\n type OrganizationGroupMembers,\n type OrganizationGroupPolicyHistory,\n type OrganizationPolicyHistory,\n type OrganizationUserDetail,\n reconcileOrganizationDirectoryAndGroups,\n} from \"../../workflows/organizations\";\nimport {\n organizationAccessScopeKey,\n wasOrganizationPresentationAccessDeniedByServer,\n} from \"../../workflows/organizations/organizationPresentationAccessState\";\nimport type { InternalRuntime } from \"../workflowRuntime\";\nimport { recoverOrganizationAccess } from \"./organizationAccessRestoration\";\nimport { loadBoundedOrganizationGroupHistory } from \"./organizationGroupHistory\";\nimport { hydrateOrganizationGroupNamesForRuntime } from \"./organizationGroupNameHydration\";\nimport { loadBoundedOrganizationHistory } from \"./organizationHistory\";\nimport {\n type ActiveOrganizationDataRuntime,\n activeOrganizationDataRuntime,\n isOrganizationDataRuntimeCurrent,\n} from \"./organizationWorkflowRuntime\";\n\nconst coordinatorsByRuntime = new WeakMap<\n InternalRuntime,\n OrganizationReadModelCoordinator\n>();\n\nexport interface OrganizationReadModelCoordinator {\n loadLocal(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null>;\n loadLocalGroupMembers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupMembers | null>;\n loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationGroupPolicyHistory | null>;\n loadOrganizationPolicyHistory(\n organizationId?: string | undefined,\n beforeVersion?: number | undefined,\n ): Promise<OrganizationPolicyHistory | null>;\n loadLocalGrants(\n organizationId?: string | undefined,\n ): Promise<OrganizationContainerGrants | null>;\n loadLocalGroupContainers(\n groupId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationGroupContainers | null>;\n loadLocalUserDetail(\n userId: string,\n organizationId?: string | undefined,\n ): Promise<OrganizationUserDetail | null>;\n /**\n * Resolves `undefined` when the runtime declines without I/O (offline,\n * database not ready, organization mismatch) or when the feed failed with\n * no locally retained projection — passes that must not count as caught\n * up; `null` when the reconcile completed but produced nothing presentable\n * — including an authoritative denial that purged the projection, which\n * consumers must repaint.\n */\n reconcile(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n reconcileAfterMutation(\n organizationId?: string | undefined,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined>;\n}\n\nclass OrganizationReadModelCoordinatorImpl\n implements OrganizationReadModelCoordinator\n{\n private readonly reconciliationsByScope = new WeakMap<\n DomainScope,\n Map<string, Promise<OrganizationDirectoryAndGroups | null | undefined>>\n >();\n constructor(private readonly runtimeService: InternalRuntime) {}\n\n private reconciliationMap(active: ActiveOrganizationDataRuntime) {\n const scope = active.runtime.state.domainScope;\n let byKey = this.reconciliationsByScope.get(scope);\n if (!byKey) {\n byKey = new Map();\n this.reconciliationsByScope.set(scope, byKey);\n }\n return byKey;\n }\n\n async loadLocal(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationDirectoryAndGroups({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGrants(organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) {\n return null;\n }\n return loadLocalOrganizationContainerGrants({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupContainers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupContainers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadLocalGroupMembers(groupId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n return loadLocalOrganizationGroupMembers({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n groupId,\n organizationId: active.organizationId,\n });\n }\n\n async loadGroupPolicyHistory(\n groupId: string,\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || groupId.length === 0) {\n return null;\n }\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationGroupHistory({\n active,\n groupId,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadOrganizationPolicyHistory(\n organizationId?: string,\n beforeVersion?: number,\n ) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active) return null;\n const domainScope = active.runtime.state.domainScope;\n return loadBoundedOrganizationHistory({\n active,\n beforeVersion,\n stillCurrent: () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n ),\n });\n }\n\n async loadLocalUserDetail(userId: string, organizationId?: string) {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active || userId.length === 0) {\n return null;\n }\n return loadLocalOrganizationUserDetail({\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n userId,\n });\n }\n\n reconcile(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return Promise.resolve(undefined);\n }\n\n const byKey = this.reconciliationMap(active);\n const key = organizationAccessScopeKey(\n active.organizationId,\n active.userId,\n );\n const existing = byKey.get(key);\n if (existing) {\n return existing;\n }\n\n // Snapshot the server-denied flag before reconciling. A reconcile that\n // flips it back to readable means org access was just restored (e.g. the\n // user was re-added to a group), and any write lanes idled by\n // permission-denied submissions have no self re-arm — regaining access is\n // their retry signal, mirroring how billing recovery re-requests all\n // lanes. Only a genuine server denial counts: a local session reset also\n // marks scopes denied, and re-arming on its first reconcile would race the\n // startup sync passes (e.g. pending-create adoption between panes).\n const accessWasDenied = wasOrganizationPresentationAccessDeniedByServer(\n {\n execSql: active.runtime.infra.execSql,\n organizationId: active.organizationId,\n requesterUserId: active.userId,\n },\n \"readModel\",\n );\n const domainScope = active.runtime.state.domainScope;\n const stillCurrent = () =>\n isOrganizationDataRuntimeCurrent(\n this.runtimeService,\n active,\n domainScope,\n );\n\n const reconciliation = reconcileOrganizationDirectoryAndGroups({\n apiClient: active.runtime.apiClient,\n currentUserId: active.userId,\n execSql: active.runtime.infra.execSql,\n logError: active.runtime.util.logError,\n organizationId: active.organizationId,\n })\n .then(async (directoryAndGroups) => {\n if (!stillCurrent()) return null;\n // Feed success restores retry eligibility even if name decryption fails.\n const accessWasRestored =\n accessWasDenied &&\n directoryAndGroups !== null &&\n directoryAndGroups !== undefined;\n if (accessWasRestored)\n await recoverOrganizationAccess({\n active,\n domainScope,\n stillCurrent,\n });\n if (!stillCurrent()) return null;\n return hydrateOrganizationGroupNamesForRuntime(\n this.runtimeService,\n active,\n domainScope,\n directoryAndGroups,\n );\n })\n .finally(() => {\n if (byKey.get(key) === reconciliation) {\n byKey.delete(key);\n }\n });\n byKey.set(key, reconciliation);\n return reconciliation;\n }\n\n async reconcileAfterMutation(\n organizationId?: string,\n ): Promise<OrganizationDirectoryAndGroups | null | undefined> {\n const active = activeOrganizationDataRuntime(\n this.runtimeService,\n organizationId,\n );\n if (!active?.runtime.state.online) {\n return undefined;\n }\n const existing = this.reconciliationMap(active).get(\n organizationAccessScopeKey(active.organizationId, active.userId),\n );\n if (existing) {\n await existing.catch(() => null);\n }\n return this.reconcile(active.organizationId);\n }\n}\n\nexport function createOrganizationReadModelCoordinator(\n runtimeService: InternalRuntime,\n): OrganizationReadModelCoordinator {\n const existing = coordinatorsByRuntime.get(runtimeService);\n if (existing) {\n return existing;\n }\n\n const coordinator = new OrganizationReadModelCoordinatorImpl(runtimeService);\n coordinatorsByRuntime.set(runtimeService, coordinator);\n return coordinator;\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ProjectionDependencyUnavailableError } from "../../data/keyingProjectionVerification/dependencyUnavailable.js";
|
|
1
2
|
import { runWithSecurityIncidentReporting } from "../../data/keyingProjectionVerification/error.js";
|
|
2
|
-
import {
|
|
3
|
+
import { revokeOrganizationContainerGrant } from "../../workflows/organizations/index.js";
|
|
3
4
|
import { createCurrentOrganizationGroup } from "../../workflows/organizations/createCurrentOrganizationGroup.js";
|
|
4
5
|
import { createSelectedCurrentGroupMetadataContainerVerifier } from "../../workflows/organizations/currentGroupMetadataAuthority.js";
|
|
5
6
|
import { deleteCurrentOrganizationGroup } from "../../workflows/organizations/deleteCurrentOrganizationGroup.js";
|
|
@@ -8,7 +9,6 @@ import { createRuntimeCurrentOrganizationMutation } from "../../workflows/organi
|
|
|
8
9
|
import { createRuntimePrincipalPolicyWarmer } from "../../workflows/principals/runtimePolicyWarmer.js";
|
|
9
10
|
import { createCurrentPrincipalMutation } from "./currentPrincipalMutations.js";
|
|
10
11
|
import { syncOrganizationMetadataProfile } from "./organizationMetadataProfileSync.js";
|
|
11
|
-
import { preparePrincipalContainerMutations } from "./principalContainerMutations.js";
|
|
12
12
|
function requireSigningContext(runtime) {
|
|
13
13
|
if (!runtime.auth.organizationId ||
|
|
14
14
|
!runtime.auth.userId ||
|
|
@@ -37,45 +37,18 @@ export async function addUserToOrganizationGroup(input) {
|
|
|
37
37
|
operation: "group.member.add",
|
|
38
38
|
organizationId: signingContext.organizationId,
|
|
39
39
|
}, async () => {
|
|
40
|
-
let memberGroupId = null;
|
|
41
40
|
const mutateCurrent = createCurrentPrincipalMutation({
|
|
42
41
|
...signingContext,
|
|
43
42
|
runtime: input.runtime,
|
|
44
43
|
stillCurrent: input.stillCurrent,
|
|
45
44
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
memberGroupId = current?.memberGroupId ?? null;
|
|
54
|
-
const bundle = current?.response ??
|
|
55
|
-
(await addOrganizationGroupUser({
|
|
56
|
-
apiClient: input.runtime.apiClient,
|
|
57
|
-
beforePolicyCommit: (_head, authority) => {
|
|
58
|
-
memberGroupId = authority.memberGroupId;
|
|
59
|
-
},
|
|
60
|
-
currentUserSecretKey: requireEncapsulationKeyPair(input.runtime)
|
|
61
|
-
.secretKey,
|
|
62
|
-
execSql: input.runtime.infra.execSql,
|
|
63
|
-
expectedGroupName: input.expectedGroupName,
|
|
64
|
-
readEncryptedName: createRuntimeGroupMetadataAccess(input.runtime, signingContext.organizationId, input.stillCurrent).readName,
|
|
65
|
-
groupId: input.groupId,
|
|
66
|
-
prepareContainerMutations: ({ currentPolicy, nextPolicy }) => preparePrincipalContainerMutations({
|
|
67
|
-
currentPolicy,
|
|
68
|
-
groupId: input.groupId,
|
|
69
|
-
nextPolicy,
|
|
70
|
-
organizationId: signingContext.organizationId,
|
|
71
|
-
runtime: input.runtime,
|
|
72
|
-
stillCurrent: input.stillCurrent,
|
|
73
|
-
}),
|
|
74
|
-
reportSecurityIncident: input.runtime.util.reportSecurityIncident,
|
|
75
|
-
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
76
|
-
targetUserId: input.targetUserId,
|
|
77
|
-
...signingContext,
|
|
78
|
-
}));
|
|
45
|
+
if (!mutateCurrent)
|
|
46
|
+
throw new ProjectionDependencyUnavailableError("Principal history recovery is unavailable");
|
|
47
|
+
const { memberGroupId, response: bundle } = await mutateCurrent(input.groupId, {
|
|
48
|
+
kind: "add",
|
|
49
|
+
expectedGroupName: input.expectedGroupName,
|
|
50
|
+
targetUserId: input.targetUserId,
|
|
51
|
+
});
|
|
79
52
|
if (input.groupId === memberGroupId) {
|
|
80
53
|
await syncOrganizationMetadataProfile({
|
|
81
54
|
containerContents: input.containerContents,
|
|
@@ -97,33 +70,23 @@ export function createGroupForOrganization(input) {
|
|
|
97
70
|
}, () => {
|
|
98
71
|
const creatorEncapsulationKeyPair = requireEncapsulationKeyPair(input.runtime);
|
|
99
72
|
const mutate = createRuntimeCurrentOrganizationMutation(input.runtime);
|
|
100
|
-
if (mutate)
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
creatorEncapsulationKeyPair,
|
|
106
|
-
execSql: input.runtime.infra.execSql,
|
|
107
|
-
name: input.name,
|
|
108
|
-
metadataAccess: createRuntimeGroupMetadataAccess(input.runtime, signingContext.organizationId, context.stillCurrent, createSelectedCurrentGroupMetadataContainerVerifier({
|
|
109
|
-
authority: context,
|
|
110
|
-
organizationId: signingContext.organizationId,
|
|
111
|
-
stillCurrent: context.stillCurrent,
|
|
112
|
-
})),
|
|
113
|
-
reportSecurityIncident: input.runtime.util.reportSecurityIncident,
|
|
114
|
-
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
115
|
-
}));
|
|
116
|
-
return createOrganizationGroup({
|
|
117
|
-
stillCurrent: input.stillCurrent,
|
|
73
|
+
if (!mutate)
|
|
74
|
+
throw new ProjectionDependencyUnavailableError("Principal history recovery is unavailable");
|
|
75
|
+
return mutate({ ...signingContext, stillCurrent: input.stillCurrent }, (context) => createCurrentOrganizationGroup({
|
|
76
|
+
...signingContext,
|
|
77
|
+
context,
|
|
118
78
|
apiClient: input.runtime.apiClient,
|
|
119
79
|
creatorEncapsulationKeyPair,
|
|
120
80
|
execSql: input.runtime.infra.execSql,
|
|
121
81
|
name: input.name,
|
|
122
|
-
metadataAccess: createRuntimeGroupMetadataAccess(input.runtime, signingContext.organizationId,
|
|
82
|
+
metadataAccess: createRuntimeGroupMetadataAccess(input.runtime, signingContext.organizationId, context.stillCurrent, createSelectedCurrentGroupMetadataContainerVerifier({
|
|
83
|
+
authority: context,
|
|
84
|
+
organizationId: signingContext.organizationId,
|
|
85
|
+
stillCurrent: context.stillCurrent,
|
|
86
|
+
})),
|
|
123
87
|
reportSecurityIncident: input.runtime.util.reportSecurityIncident,
|
|
124
88
|
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
125
|
-
|
|
126
|
-
});
|
|
89
|
+
}));
|
|
127
90
|
});
|
|
128
91
|
}
|
|
129
92
|
export function deleteGroupForOrganization(input) {
|
|
@@ -135,22 +98,15 @@ export function deleteGroupForOrganization(input) {
|
|
|
135
98
|
organizationId: signingContext.organizationId,
|
|
136
99
|
}, () => {
|
|
137
100
|
const mutate = createRuntimeCurrentOrganizationMutation(input.runtime);
|
|
138
|
-
if (mutate)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
apiClient: input.runtime.apiClient,
|
|
144
|
-
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
145
|
-
}));
|
|
146
|
-
return deleteOrganizationGroup({
|
|
147
|
-
stillCurrent: input.stillCurrent,
|
|
148
|
-
apiClient: input.runtime.apiClient,
|
|
149
|
-
execSql: input.runtime.infra.execSql,
|
|
101
|
+
if (!mutate)
|
|
102
|
+
throw new ProjectionDependencyUnavailableError("Principal history recovery is unavailable");
|
|
103
|
+
return mutate({ ...signingContext, stillCurrent: input.stillCurrent }, (context) => deleteCurrentOrganizationGroup({
|
|
104
|
+
...signingContext,
|
|
105
|
+
context,
|
|
150
106
|
groupId: input.groupId,
|
|
107
|
+
apiClient: input.runtime.apiClient,
|
|
151
108
|
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
152
|
-
|
|
153
|
-
});
|
|
109
|
+
}));
|
|
154
110
|
});
|
|
155
111
|
}
|
|
156
112
|
export async function removeUserFromOrganizationGroup(input) {
|
|
@@ -161,42 +117,18 @@ export async function removeUserFromOrganizationGroup(input) {
|
|
|
161
117
|
operation: "group.member.remove",
|
|
162
118
|
organizationId: signingContext.organizationId,
|
|
163
119
|
}, async () => {
|
|
164
|
-
let memberGroupId = null;
|
|
165
120
|
const mutateCurrent = createCurrentPrincipalMutation({
|
|
166
121
|
...signingContext,
|
|
167
122
|
runtime: input.runtime,
|
|
168
123
|
stillCurrent: input.stillCurrent,
|
|
169
124
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
memberGroupId = current?.memberGroupId ?? null;
|
|
178
|
-
const bundle = current?.response ??
|
|
179
|
-
(await removeOrganizationGroupUser({
|
|
180
|
-
apiClient: input.runtime.apiClient,
|
|
181
|
-
beforePolicyCommit: (_head, authority) => {
|
|
182
|
-
memberGroupId = authority.memberGroupId;
|
|
183
|
-
},
|
|
184
|
-
execSql: input.runtime.infra.execSql,
|
|
185
|
-
expectedGroupName: input.expectedGroupName,
|
|
186
|
-
readEncryptedName: createRuntimeGroupMetadataAccess(input.runtime, signingContext.organizationId, input.stillCurrent).readName,
|
|
187
|
-
groupId: input.groupId,
|
|
188
|
-
prepareContainerMutations: ({ currentPolicy, nextPolicy }) => preparePrincipalContainerMutations({
|
|
189
|
-
currentPolicy,
|
|
190
|
-
groupId: input.groupId,
|
|
191
|
-
nextPolicy,
|
|
192
|
-
organizationId: signingContext.organizationId,
|
|
193
|
-
runtime: input.runtime,
|
|
194
|
-
stillCurrent: input.stillCurrent,
|
|
195
|
-
}),
|
|
196
|
-
removedUserId: input.removedUserId,
|
|
197
|
-
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
198
|
-
...signingContext,
|
|
199
|
-
}));
|
|
125
|
+
if (!mutateCurrent)
|
|
126
|
+
throw new ProjectionDependencyUnavailableError("Principal history recovery is unavailable");
|
|
127
|
+
const { memberGroupId, response: bundle } = await mutateCurrent(input.groupId, {
|
|
128
|
+
kind: "remove",
|
|
129
|
+
expectedGroupName: input.expectedGroupName,
|
|
130
|
+
removedUserId: input.removedUserId,
|
|
131
|
+
});
|
|
200
132
|
if (input.groupId === memberGroupId) {
|
|
201
133
|
await syncOrganizationMetadataProfile({
|
|
202
134
|
containerContents: input.containerContents,
|
|
@@ -220,37 +152,22 @@ export async function revokeOrganizationGrant(input) {
|
|
|
220
152
|
operation: "principal.grant.revoke",
|
|
221
153
|
organizationId: signingContext.organizationId,
|
|
222
154
|
}, async () => {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
stillCurrent: input.stillCurrent,
|
|
227
|
-
});
|
|
228
|
-
const current = input.subjectType === "group" && mutateCurrent
|
|
229
|
-
? await mutateCurrent(input.subjectId, {
|
|
230
|
-
kind: "revoke",
|
|
231
|
-
revokedContainerId: input.containerId,
|
|
232
|
-
})
|
|
233
|
-
: undefined;
|
|
234
|
-
const response = current?.response ??
|
|
235
|
-
(input.subjectType === "group"
|
|
236
|
-
? await rotateOrganizationGroupForAccessSetShrink({
|
|
237
|
-
apiClient: input.runtime.apiClient,
|
|
238
|
-
execSql: input.runtime.infra.execSql,
|
|
239
|
-
groupId: input.subjectId,
|
|
240
|
-
revokedContainerId: input.containerId,
|
|
241
|
-
prepareContainerMutations: ({ currentPolicy, nextPolicy }) => preparePrincipalContainerMutations({
|
|
242
|
-
currentPolicy,
|
|
243
|
-
groupId: input.subjectId,
|
|
244
|
-
nextPolicy,
|
|
245
|
-
organizationId: signingContext.organizationId,
|
|
246
|
-
revokedContainerId: input.containerId,
|
|
247
|
-
runtime: input.runtime,
|
|
248
|
-
stillCurrent: input.stillCurrent,
|
|
249
|
-
}),
|
|
250
|
-
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
155
|
+
const revoke = async () => {
|
|
156
|
+
if (input.subjectType === "group") {
|
|
157
|
+
const mutateCurrent = createCurrentPrincipalMutation({
|
|
251
158
|
...signingContext,
|
|
252
|
-
|
|
253
|
-
|
|
159
|
+
runtime: input.runtime,
|
|
160
|
+
stillCurrent: input.stillCurrent,
|
|
161
|
+
});
|
|
162
|
+
if (!mutateCurrent)
|
|
163
|
+
throw new ProjectionDependencyUnavailableError("Principal history recovery is unavailable");
|
|
164
|
+
return (await mutateCurrent(input.subjectId, {
|
|
165
|
+
kind: "revoke",
|
|
166
|
+
revokedContainerId: input.containerId,
|
|
167
|
+
})).response;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return revokeOrganizationContainerGrant({
|
|
254
171
|
stillCurrent: input.stillCurrent,
|
|
255
172
|
reportSecurityIncident: input.runtime.util.reportSecurityIncident,
|
|
256
173
|
apiClient: input.runtime.apiClient,
|
|
@@ -264,7 +181,10 @@ export async function revokeOrganizationGrant(input) {
|
|
|
264
181
|
resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,
|
|
265
182
|
warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(input.runtime),
|
|
266
183
|
...signingContext,
|
|
267
|
-
})
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const response = await revoke();
|
|
268
188
|
await input.readModelCoordinator.reconcileAfterMutation(signingContext.organizationId);
|
|
269
189
|
return response;
|
|
270
190
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"principalMutations.js","sourceRoot":"","sources":["principalMutations.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerGrantSubjectType } from \"@tearleads/crypto\";\nimport { runWithSecurityIncidentReporting } from \"../../data/keyingProjectionVerification/error\";\nimport {\n addOrganizationGroupUser,\n createOrganizationGroup,\n deleteOrganizationGroup,\n removeOrganizationGroupUser,\n revokeOrganizationContainerGrant,\n rotateOrganizationGroupForAccessSetShrink,\n} from \"../../workflows/organizations\";\nimport { createCurrentOrganizationGroup } from \"../../workflows/organizations/createCurrentOrganizationGroup\";\nimport { createSelectedCurrentGroupMetadataContainerVerifier } from \"../../workflows/organizations/currentGroupMetadataAuthority\";\nimport { deleteCurrentOrganizationGroup } from \"../../workflows/organizations/deleteCurrentOrganizationGroup\";\nimport { createRuntimeGroupMetadataAccess } from \"../../workflows/organizations/groupMetadataRuntime\";\nimport { createRuntimeCurrentOrganizationMutation } from \"../../workflows/organizations/runtimeCurrentOrganizationMutation\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../workflows/principals/runtimePolicyWarmer\";\nimport type { ContainerContents } from \"../containerContents\";\nimport type { InternalWorkflowRuntimeInput } from \"../workflowRuntime\";\nimport { createCurrentPrincipalMutation } from \"./currentPrincipalMutations\";\nimport { syncOrganizationMetadataProfile } from \"./organizationMetadataProfileSync\";\nimport type { OrganizationReadModelCoordinator } from \"./organizationReadModels\";\nimport { preparePrincipalContainerMutations } from \"./principalContainerMutations\";\n\nexport interface OrganizationGrantRef {\n containerId: string;\n subjectId: string;\n subjectType: ContainerGrantSubjectType;\n}\n\nexport interface OrganizationGroupUserMutationInput {\n groupId: string;\n expectedGroupName: string;\n}\n\nexport interface AddOrganizationGroupUserInput\n extends OrganizationGroupUserMutationInput {\n targetUserId: string;\n}\n\nexport interface RemoveOrganizationGroupUserInput\n extends OrganizationGroupUserMutationInput {\n removedUserId: string;\n}\n\ninterface OrganizationSigningContext {\n organizationId: string;\n signerUserId: string;\n signingFingerprint: string;\n signingKeyPair: NonNullable<\n InternalWorkflowRuntimeInput[\"crypto\"][\"signingKeyPair\"]\n >;\n}\n\nfunction requireSigningContext(\n runtime: InternalWorkflowRuntimeInput,\n): OrganizationSigningContext {\n if (\n !runtime.auth.organizationId ||\n !runtime.auth.userId ||\n !runtime.crypto.signingFingerprint ||\n !runtime.crypto.signingKeyPair\n ) {\n throw new Error(\"Organization signing context is unavailable\");\n }\n\n return {\n organizationId: runtime.auth.organizationId,\n signerUserId: runtime.auth.userId,\n signingFingerprint: runtime.crypto.signingFingerprint,\n signingKeyPair: runtime.crypto.signingKeyPair,\n };\n}\n\nfunction requireEncapsulationKeyPair(\n runtime: InternalWorkflowRuntimeInput,\n): NonNullable<InternalWorkflowRuntimeInput[\"crypto\"][\"encapsulationKeyPair\"]> {\n if (!runtime.crypto.encapsulationKeyPair) {\n throw new Error(\"Organization encryption context is unavailable\");\n }\n\n return runtime.crypto.encapsulationKeyPair;\n}\n\ninterface PrincipalMutationRuntime {\n readonly stillCurrent: () => boolean;\n readonly containerContents: ContainerContents;\n readonly readModelCoordinator: OrganizationReadModelCoordinator;\n readonly runtime: InternalWorkflowRuntimeInput;\n}\n\nexport async function addUserToOrganizationGroup(\n input: PrincipalMutationRuntime & AddOrganizationGroupUserInput,\n) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.groupId,\n objectKind: \"principal\",\n operation: \"group.member.add\",\n organizationId: signingContext.organizationId,\n },\n async () => {\n let memberGroupId: string | null = null;\n const mutateCurrent = createCurrentPrincipalMutation({\n ...signingContext,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n const current = mutateCurrent\n ? await mutateCurrent(input.groupId, {\n kind: \"add\",\n expectedGroupName: input.expectedGroupName,\n targetUserId: input.targetUserId,\n })\n : undefined;\n memberGroupId = current?.memberGroupId ?? null;\n const bundle =\n current?.response ??\n (await addOrganizationGroupUser({\n apiClient: input.runtime.apiClient,\n beforePolicyCommit: (_head, authority) => {\n memberGroupId = authority.memberGroupId;\n },\n currentUserSecretKey: requireEncapsulationKeyPair(input.runtime)\n .secretKey,\n execSql: input.runtime.infra.execSql,\n expectedGroupName: input.expectedGroupName,\n readEncryptedName: createRuntimeGroupMetadataAccess(\n input.runtime,\n signingContext.organizationId,\n input.stillCurrent,\n ).readName,\n groupId: input.groupId,\n prepareContainerMutations: ({ currentPolicy, nextPolicy }) =>\n preparePrincipalContainerMutations({\n currentPolicy,\n groupId: input.groupId,\n nextPolicy,\n organizationId: signingContext.organizationId,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n }),\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n targetUserId: input.targetUserId,\n ...signingContext,\n }));\n if (input.groupId === memberGroupId) {\n await syncOrganizationMetadataProfile({\n containerContents: input.containerContents,\n log: input.runtime.util.log,\n organizationId: signingContext.organizationId,\n });\n }\n await input.readModelCoordinator.reconcileAfterMutation(\n signingContext.organizationId,\n );\n return bundle;\n },\n );\n}\n\nexport function createGroupForOrganization(input: {\n readonly name: string;\n readonly runtime: InternalWorkflowRuntimeInput;\n readonly stillCurrent: () => boolean;\n}) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: signingContext.organizationId,\n objectKind: \"principal\",\n operation: \"group.create\",\n organizationId: signingContext.organizationId,\n },\n () => {\n const creatorEncapsulationKeyPair = requireEncapsulationKeyPair(\n input.runtime,\n );\n const mutate = createRuntimeCurrentOrganizationMutation(input.runtime);\n if (mutate)\n return mutate(\n { ...signingContext, stillCurrent: input.stillCurrent },\n (context) =>\n createCurrentOrganizationGroup({\n ...signingContext,\n context,\n apiClient: input.runtime.apiClient,\n creatorEncapsulationKeyPair,\n execSql: input.runtime.infra.execSql,\n name: input.name,\n metadataAccess: createRuntimeGroupMetadataAccess(\n input.runtime,\n signingContext.organizationId,\n context.stillCurrent,\n createSelectedCurrentGroupMetadataContainerVerifier({\n authority: context,\n organizationId: signingContext.organizationId,\n stillCurrent: context.stillCurrent,\n }),\n ),\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n }),\n );\n return createOrganizationGroup({\n stillCurrent: input.stillCurrent,\n apiClient: input.runtime.apiClient,\n creatorEncapsulationKeyPair,\n execSql: input.runtime.infra.execSql,\n name: input.name,\n metadataAccess: createRuntimeGroupMetadataAccess(\n input.runtime,\n signingContext.organizationId,\n input.stillCurrent,\n ),\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n ...signingContext,\n });\n },\n );\n}\n\nexport function deleteGroupForOrganization(input: {\n readonly groupId: string;\n readonly runtime: InternalWorkflowRuntimeInput;\n readonly stillCurrent: () => boolean;\n}) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.groupId,\n objectKind: \"principal\",\n operation: \"group.delete\",\n organizationId: signingContext.organizationId,\n },\n () => {\n const mutate = createRuntimeCurrentOrganizationMutation(input.runtime);\n if (mutate)\n return mutate(\n { ...signingContext, stillCurrent: input.stillCurrent },\n (context) =>\n deleteCurrentOrganizationGroup({\n ...signingContext,\n context,\n groupId: input.groupId,\n apiClient: input.runtime.apiClient,\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n }),\n );\n return deleteOrganizationGroup({\n stillCurrent: input.stillCurrent,\n apiClient: input.runtime.apiClient,\n execSql: input.runtime.infra.execSql,\n groupId: input.groupId,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n ...signingContext,\n });\n },\n );\n}\n\nexport async function removeUserFromOrganizationGroup(\n input: PrincipalMutationRuntime & RemoveOrganizationGroupUserInput,\n) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.groupId,\n objectKind: \"principal\",\n operation: \"group.member.remove\",\n organizationId: signingContext.organizationId,\n },\n async () => {\n let memberGroupId: string | null = null;\n const mutateCurrent = createCurrentPrincipalMutation({\n ...signingContext,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n const current = mutateCurrent\n ? await mutateCurrent(input.groupId, {\n kind: \"remove\",\n expectedGroupName: input.expectedGroupName,\n removedUserId: input.removedUserId,\n })\n : undefined;\n memberGroupId = current?.memberGroupId ?? null;\n const bundle =\n current?.response ??\n (await removeOrganizationGroupUser({\n apiClient: input.runtime.apiClient,\n beforePolicyCommit: (_head, authority) => {\n memberGroupId = authority.memberGroupId;\n },\n execSql: input.runtime.infra.execSql,\n expectedGroupName: input.expectedGroupName,\n readEncryptedName: createRuntimeGroupMetadataAccess(\n input.runtime,\n signingContext.organizationId,\n input.stillCurrent,\n ).readName,\n groupId: input.groupId,\n prepareContainerMutations: ({ currentPolicy, nextPolicy }) =>\n preparePrincipalContainerMutations({\n currentPolicy,\n groupId: input.groupId,\n nextPolicy,\n organizationId: signingContext.organizationId,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n }),\n removedUserId: input.removedUserId,\n resolveTrustedUserIdentity: input.runtime.resolveTrustedUserIdentity,\n ...signingContext,\n }));\n if (input.groupId === memberGroupId) {\n await syncOrganizationMetadataProfile({\n containerContents: input.containerContents,\n log: input.runtime.util.log,\n organizationId: signingContext.organizationId,\n });\n }\n await input.readModelCoordinator.reconcileAfterMutation(\n signingContext.organizationId,\n );\n return bundle;\n },\n );\n}\n\nexport async function revokeOrganizationGrant(\n input: PrincipalMutationRuntime & OrganizationGrantRef,\n) {\n const signingContext = requireSigningContext(input.runtime);\n const encapsulationKeyPair = requireEncapsulationKeyPair(input.runtime);\n if (input.runtime.infra.dbStatus !== \"ready\") {\n throw new Error(\"Organization local database is unavailable\");\n }\n\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.subjectId,\n objectKind: \"principal\",\n operation: \"principal.grant.revoke\",\n organizationId: signingContext.organizationId,\n },\n async () => {\n const mutateCurrent = createCurrentPrincipalMutation({\n ...signingContext,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n const current =\n input.subjectType === \"group\" && mutateCurrent\n ? await mutateCurrent(input.subjectId, {\n kind: \"revoke\",\n revokedContainerId: input.containerId,\n })\n : undefined;\n const response =\n current?.response ??\n (input.subjectType === \"group\"\n ? await rotateOrganizationGroupForAccessSetShrink({\n apiClient: input.runtime.apiClient,\n execSql: input.runtime.infra.execSql,\n groupId: input.subjectId,\n revokedContainerId: input.containerId,\n prepareContainerMutations: ({ currentPolicy, nextPolicy }) =>\n preparePrincipalContainerMutations({\n currentPolicy,\n groupId: input.subjectId,\n nextPolicy,\n organizationId: signingContext.organizationId,\n revokedContainerId: input.containerId,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n }),\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n ...signingContext,\n })\n : await revokeOrganizationContainerGrant({\n stillCurrent: input.stillCurrent,\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n apiClient: input.runtime.apiClient,\n containerId: input.containerId,\n encapsulationKeyPair,\n execSql: input.runtime.infra.execSql,\n revokedSubject: {\n subjectId: input.subjectId,\n subjectType: input.subjectType,\n },\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n warmReferencedPrincipalPolicies:\n createRuntimePrincipalPolicyWarmer(input.runtime),\n ...signingContext,\n }));\n await input.readModelCoordinator.reconcileAfterMutation(\n signingContext.organizationId,\n );\n return response;\n },\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"principalMutations.js","sourceRoot":"","sources":["principalMutations.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerGrantSubjectType } from \"@tearleads/crypto\";\nimport { ProjectionDependencyUnavailableError } from \"../../data/keyingProjectionVerification/dependencyUnavailable\";\nimport { runWithSecurityIncidentReporting } from \"../../data/keyingProjectionVerification/error\";\nimport { revokeOrganizationContainerGrant } from \"../../workflows/organizations\";\nimport { createCurrentOrganizationGroup } from \"../../workflows/organizations/createCurrentOrganizationGroup\";\nimport { createSelectedCurrentGroupMetadataContainerVerifier } from \"../../workflows/organizations/currentGroupMetadataAuthority\";\nimport { deleteCurrentOrganizationGroup } from \"../../workflows/organizations/deleteCurrentOrganizationGroup\";\nimport { createRuntimeGroupMetadataAccess } from \"../../workflows/organizations/groupMetadataRuntime\";\nimport { createRuntimeCurrentOrganizationMutation } from \"../../workflows/organizations/runtimeCurrentOrganizationMutation\";\nimport { createRuntimePrincipalPolicyWarmer } from \"../../workflows/principals/runtimePolicyWarmer\";\nimport type { ContainerContents } from \"../containerContents\";\nimport type { InternalWorkflowRuntimeInput } from \"../workflowRuntime\";\nimport { createCurrentPrincipalMutation } from \"./currentPrincipalMutations\";\nimport { syncOrganizationMetadataProfile } from \"./organizationMetadataProfileSync\";\nimport type { OrganizationReadModelCoordinator } from \"./organizationReadModels\";\n\nexport interface OrganizationGrantRef {\n containerId: string;\n subjectId: string;\n subjectType: ContainerGrantSubjectType;\n}\n\nexport interface OrganizationGroupUserMutationInput {\n groupId: string;\n expectedGroupName: string;\n}\n\nexport interface AddOrganizationGroupUserInput\n extends OrganizationGroupUserMutationInput {\n targetUserId: string;\n}\n\nexport interface RemoveOrganizationGroupUserInput\n extends OrganizationGroupUserMutationInput {\n removedUserId: string;\n}\n\ninterface OrganizationSigningContext {\n organizationId: string;\n signerUserId: string;\n signingFingerprint: string;\n signingKeyPair: NonNullable<\n InternalWorkflowRuntimeInput[\"crypto\"][\"signingKeyPair\"]\n >;\n}\n\nfunction requireSigningContext(\n runtime: InternalWorkflowRuntimeInput,\n): OrganizationSigningContext {\n if (\n !runtime.auth.organizationId ||\n !runtime.auth.userId ||\n !runtime.crypto.signingFingerprint ||\n !runtime.crypto.signingKeyPair\n ) {\n throw new Error(\"Organization signing context is unavailable\");\n }\n\n return {\n organizationId: runtime.auth.organizationId,\n signerUserId: runtime.auth.userId,\n signingFingerprint: runtime.crypto.signingFingerprint,\n signingKeyPair: runtime.crypto.signingKeyPair,\n };\n}\n\nfunction requireEncapsulationKeyPair(\n runtime: InternalWorkflowRuntimeInput,\n): NonNullable<InternalWorkflowRuntimeInput[\"crypto\"][\"encapsulationKeyPair\"]> {\n if (!runtime.crypto.encapsulationKeyPair) {\n throw new Error(\"Organization encryption context is unavailable\");\n }\n\n return runtime.crypto.encapsulationKeyPair;\n}\n\ninterface PrincipalMutationRuntime {\n readonly stillCurrent: () => boolean;\n readonly containerContents: ContainerContents;\n readonly readModelCoordinator: OrganizationReadModelCoordinator;\n readonly runtime: InternalWorkflowRuntimeInput;\n}\n\nexport async function addUserToOrganizationGroup(\n input: PrincipalMutationRuntime & AddOrganizationGroupUserInput,\n) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.groupId,\n objectKind: \"principal\",\n operation: \"group.member.add\",\n organizationId: signingContext.organizationId,\n },\n async () => {\n const mutateCurrent = createCurrentPrincipalMutation({\n ...signingContext,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (!mutateCurrent)\n throw new ProjectionDependencyUnavailableError(\n \"Principal history recovery is unavailable\",\n );\n const { memberGroupId, response: bundle } = await mutateCurrent(\n input.groupId,\n {\n kind: \"add\",\n expectedGroupName: input.expectedGroupName,\n targetUserId: input.targetUserId,\n },\n );\n if (input.groupId === memberGroupId) {\n await syncOrganizationMetadataProfile({\n containerContents: input.containerContents,\n log: input.runtime.util.log,\n organizationId: signingContext.organizationId,\n });\n }\n await input.readModelCoordinator.reconcileAfterMutation(\n signingContext.organizationId,\n );\n return bundle;\n },\n );\n}\n\nexport function createGroupForOrganization(input: {\n readonly name: string;\n readonly runtime: InternalWorkflowRuntimeInput;\n readonly stillCurrent: () => boolean;\n}) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: signingContext.organizationId,\n objectKind: \"principal\",\n operation: \"group.create\",\n organizationId: signingContext.organizationId,\n },\n () => {\n const creatorEncapsulationKeyPair = requireEncapsulationKeyPair(\n input.runtime,\n );\n const mutate = createRuntimeCurrentOrganizationMutation(input.runtime);\n if (!mutate)\n throw new ProjectionDependencyUnavailableError(\n \"Principal history recovery is unavailable\",\n );\n return mutate(\n { ...signingContext, stillCurrent: input.stillCurrent },\n (context) =>\n createCurrentOrganizationGroup({\n ...signingContext,\n context,\n apiClient: input.runtime.apiClient,\n creatorEncapsulationKeyPair,\n execSql: input.runtime.infra.execSql,\n name: input.name,\n metadataAccess: createRuntimeGroupMetadataAccess(\n input.runtime,\n signingContext.organizationId,\n context.stillCurrent,\n createSelectedCurrentGroupMetadataContainerVerifier({\n authority: context,\n organizationId: signingContext.organizationId,\n stillCurrent: context.stillCurrent,\n }),\n ),\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n }),\n );\n },\n );\n}\n\nexport function deleteGroupForOrganization(input: {\n readonly groupId: string;\n readonly runtime: InternalWorkflowRuntimeInput;\n readonly stillCurrent: () => boolean;\n}) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.groupId,\n objectKind: \"principal\",\n operation: \"group.delete\",\n organizationId: signingContext.organizationId,\n },\n () => {\n const mutate = createRuntimeCurrentOrganizationMutation(input.runtime);\n if (!mutate)\n throw new ProjectionDependencyUnavailableError(\n \"Principal history recovery is unavailable\",\n );\n return mutate(\n { ...signingContext, stillCurrent: input.stillCurrent },\n (context) =>\n deleteCurrentOrganizationGroup({\n ...signingContext,\n context,\n groupId: input.groupId,\n apiClient: input.runtime.apiClient,\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n }),\n );\n },\n );\n}\n\nexport async function removeUserFromOrganizationGroup(\n input: PrincipalMutationRuntime & RemoveOrganizationGroupUserInput,\n) {\n const signingContext = requireSigningContext(input.runtime);\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.groupId,\n objectKind: \"principal\",\n operation: \"group.member.remove\",\n organizationId: signingContext.organizationId,\n },\n async () => {\n const mutateCurrent = createCurrentPrincipalMutation({\n ...signingContext,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (!mutateCurrent)\n throw new ProjectionDependencyUnavailableError(\n \"Principal history recovery is unavailable\",\n );\n const { memberGroupId, response: bundle } = await mutateCurrent(\n input.groupId,\n {\n kind: \"remove\",\n expectedGroupName: input.expectedGroupName,\n removedUserId: input.removedUserId,\n },\n );\n if (input.groupId === memberGroupId) {\n await syncOrganizationMetadataProfile({\n containerContents: input.containerContents,\n log: input.runtime.util.log,\n organizationId: signingContext.organizationId,\n });\n }\n await input.readModelCoordinator.reconcileAfterMutation(\n signingContext.organizationId,\n );\n return bundle;\n },\n );\n}\n\nexport async function revokeOrganizationGrant(\n input: PrincipalMutationRuntime & OrganizationGrantRef,\n) {\n const signingContext = requireSigningContext(input.runtime);\n const encapsulationKeyPair = requireEncapsulationKeyPair(input.runtime);\n if (input.runtime.infra.dbStatus !== \"ready\") {\n throw new Error(\"Organization local database is unavailable\");\n }\n\n return runWithSecurityIncidentReporting(\n input.runtime.util.reportSecurityIncident,\n {\n objectId: input.subjectId,\n objectKind: \"principal\",\n operation: \"principal.grant.revoke\",\n organizationId: signingContext.organizationId,\n },\n async () => {\n const revoke = async () => {\n if (input.subjectType === \"group\") {\n const mutateCurrent = createCurrentPrincipalMutation({\n ...signingContext,\n runtime: input.runtime,\n stillCurrent: input.stillCurrent,\n });\n if (!mutateCurrent)\n throw new ProjectionDependencyUnavailableError(\n \"Principal history recovery is unavailable\",\n );\n return (\n await mutateCurrent(input.subjectId, {\n kind: \"revoke\",\n revokedContainerId: input.containerId,\n })\n ).response;\n } else {\n return revokeOrganizationContainerGrant({\n stillCurrent: input.stillCurrent,\n reportSecurityIncident: input.runtime.util.reportSecurityIncident,\n apiClient: input.runtime.apiClient,\n containerId: input.containerId,\n encapsulationKeyPair,\n execSql: input.runtime.infra.execSql,\n revokedSubject: {\n subjectId: input.subjectId,\n subjectType: input.subjectType,\n },\n resolveTrustedUserIdentity:\n input.runtime.resolveTrustedUserIdentity,\n warmReferencedPrincipalPolicies: createRuntimePrincipalPolicyWarmer(\n input.runtime,\n ),\n ...signingContext,\n });\n }\n };\n const response = await revoke();\n await input.readModelCoordinator.reconcileAfterMutation(\n signingContext.organizationId,\n );\n return response;\n },\n );\n}\n"]}
|