@openhi/constructs 0.0.104 → 0.0.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/lib/chunk-2PM2NGXI.mjs +31 -0
- package/lib/chunk-2PM2NGXI.mjs.map +1 -0
- package/lib/chunk-AGF3RAAZ.mjs +20 -0
- package/lib/chunk-AGF3RAAZ.mjs.map +1 -0
- package/lib/chunk-AO3E22CS.mjs +108 -0
- package/lib/chunk-AO3E22CS.mjs.map +1 -0
- package/lib/chunk-CHPEQRXU.mjs +45 -0
- package/lib/chunk-CHPEQRXU.mjs.map +1 -0
- package/lib/chunk-JUNL76HF.mjs +428 -0
- package/lib/chunk-JUNL76HF.mjs.map +1 -0
- package/lib/chunk-L6UAP4KP.mjs +27 -0
- package/lib/chunk-L6UAP4KP.mjs.map +1 -0
- package/lib/{chunk-3QS3WKRC.mjs → chunk-LZOMFHX3.mjs} +9 -2
- package/lib/chunk-QMIOLLAS.mjs +531 -0
- package/lib/chunk-QMIOLLAS.mjs.map +1 -0
- package/lib/chunk-SYBADQXI.mjs +607 -0
- package/lib/chunk-SYBADQXI.mjs.map +1 -0
- package/lib/chunk-VXX4I3EF.mjs +19 -0
- package/lib/chunk-VXX4I3EF.mjs.map +1 -0
- package/lib/{chunk-MLTYFMSE.mjs → chunk-VYDIGFIX.mjs} +74 -29
- package/lib/chunk-VYDIGFIX.mjs.map +1 -0
- package/lib/chunk-YU2HRNUP.mjs +33 -0
- package/lib/chunk-YU2HRNUP.mjs.map +1 -0
- package/lib/chunk-YZZDUJHI.mjs +37 -0
- package/lib/chunk-YZZDUJHI.mjs.map +1 -0
- package/lib/cors-options-lambda.handler.mjs +1 -1
- package/lib/data-store-postgres-replication.handler.mjs +1 -1
- package/lib/events-BfrkMoBD.d.mts +44 -0
- package/lib/events-BfrkMoBD.d.ts +44 -0
- package/lib/events-CVA3_eEB.d.mts +23 -0
- package/lib/events-CVA3_eEB.d.ts +23 -0
- package/lib/events-DGep6C7w.d.mts +207 -0
- package/lib/events-DGep6C7w.d.ts +207 -0
- package/lib/firehose-archive-transform.handler.mjs +1 -1
- package/lib/index.d.mts +508 -29
- package/lib/index.d.ts +773 -30
- package/lib/index.js +2536 -105
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +899 -106
- package/lib/index.mjs.map +1 -1
- package/lib/openhi-context-CaBH8SFo.d.mts +39 -0
- package/lib/openhi-context-CaBH8SFo.d.ts +39 -0
- package/lib/platform-deploy-bridge.handler.d.mts +14 -0
- package/lib/platform-deploy-bridge.handler.d.ts +14 -0
- package/lib/platform-deploy-bridge.handler.js +762 -0
- package/lib/platform-deploy-bridge.handler.js.map +1 -0
- package/lib/platform-deploy-bridge.handler.mjs +134 -0
- package/lib/platform-deploy-bridge.handler.mjs.map +1 -0
- package/lib/post-authentication.handler.mjs +1 -1
- package/lib/post-confirmation.handler.js +50 -904
- package/lib/post-confirmation.handler.js.map +1 -1
- package/lib/post-confirmation.handler.mjs +37 -112
- package/lib/post-confirmation.handler.mjs.map +1 -1
- package/lib/pre-token-generation.handler.js +135 -55
- package/lib/pre-token-generation.handler.js.map +1 -1
- package/lib/pre-token-generation.handler.mjs +25 -32
- package/lib/pre-token-generation.handler.mjs.map +1 -1
- package/lib/provision-default-workspace.handler.d.mts +13 -0
- package/lib/provision-default-workspace.handler.d.ts +13 -0
- package/lib/provision-default-workspace.handler.js +1172 -0
- package/lib/provision-default-workspace.handler.js.map +1 -0
- package/lib/provision-default-workspace.handler.mjs +175 -0
- package/lib/provision-default-workspace.handler.mjs.map +1 -0
- package/lib/rest-api-lambda.handler.js +114 -59
- package/lib/rest-api-lambda.handler.js.map +1 -1
- package/lib/rest-api-lambda.handler.mjs +60 -587
- package/lib/rest-api-lambda.handler.mjs.map +1 -1
- package/lib/seed-demo-data.handler.d.mts +107 -0
- package/lib/seed-demo-data.handler.d.ts +107 -0
- package/lib/seed-demo-data.handler.js +2037 -0
- package/lib/seed-demo-data.handler.js.map +1 -0
- package/lib/seed-demo-data.handler.mjs +23 -0
- package/lib/seed-demo-data.handler.mjs.map +1 -0
- package/lib/seed-system-data.handler.d.mts +64 -0
- package/lib/seed-system-data.handler.d.ts +64 -0
- package/lib/seed-system-data.handler.js +1631 -0
- package/lib/seed-system-data.handler.js.map +1 -0
- package/lib/seed-system-data.handler.mjs +135 -0
- package/lib/seed-system-data.handler.mjs.map +1 -0
- package/package.json +4 -2
- package/lib/chunk-MLTYFMSE.mjs.map +0 -1
- /package/lib/{chunk-3QS3WKRC.mjs.map → chunk-LZOMFHX3.mjs.map} +0 -0
package/lib/index.mjs
CHANGED
|
@@ -1,13 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SEED_SYSTEM_DATA_ACTOR_SYSTEM,
|
|
3
|
+
SEED_SYSTEM_DATA_CONSUMER_NAME,
|
|
4
|
+
SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR,
|
|
5
|
+
import_workflows as import_workflows2
|
|
6
|
+
} from "./chunk-AGF3RAAZ.mjs";
|
|
7
|
+
import {
|
|
8
|
+
DEMO_PERIOD,
|
|
9
|
+
DEMO_TENANT_SPECS,
|
|
10
|
+
DEMO_URN_SYSTEM,
|
|
11
|
+
DEV_USERS,
|
|
12
|
+
OPENHI_RESOURCE_URN_SYSTEM,
|
|
13
|
+
PLACEHOLDER_TENANT_ID,
|
|
14
|
+
PLACEHOLDER_WORKSPACE_ID,
|
|
15
|
+
PLATFORM_SCOPE_TENANT_ID,
|
|
16
|
+
SEED_DEMO_DATA_CONSUMER_NAME,
|
|
17
|
+
SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR,
|
|
18
|
+
demoBasePartitionKeys,
|
|
19
|
+
demoDevUserPartitionKeys,
|
|
20
|
+
demoMembershipId,
|
|
21
|
+
demoMembershipPartitionKey,
|
|
22
|
+
demoRoleAssignmentId,
|
|
23
|
+
demoRoleAssignmentPartitionKey,
|
|
24
|
+
demoRolesForUserInTenant,
|
|
25
|
+
demoScenarioIdentifier,
|
|
26
|
+
demoTenantPartitionKey,
|
|
27
|
+
demoUserPartitionKey,
|
|
28
|
+
demoWorkspacePartitionKey,
|
|
29
|
+
import_workflows,
|
|
30
|
+
openhiResourceIdentifier,
|
|
31
|
+
rolePartitionKey
|
|
32
|
+
} from "./chunk-QMIOLLAS.mjs";
|
|
1
33
|
import {
|
|
2
34
|
DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES,
|
|
3
35
|
DATA_STORE_CHANGE_DETAIL_TYPE,
|
|
4
36
|
DATA_STORE_CHANGE_EVENT_SOURCE,
|
|
5
37
|
buildFhirCurrentResourceChangeDetail
|
|
6
38
|
} from "./chunk-CEOAGPYY.mjs";
|
|
39
|
+
import "./chunk-L6UAP4KP.mjs";
|
|
40
|
+
import {
|
|
41
|
+
PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE,
|
|
42
|
+
USER_ONBOARDING_EVENT_SOURCE,
|
|
43
|
+
buildProvisionDefaultWorkspaceRequestedDetail
|
|
44
|
+
} from "./chunk-2PM2NGXI.mjs";
|
|
45
|
+
import {
|
|
46
|
+
BRIDGED_STATUSES,
|
|
47
|
+
CLOUDFORMATION_EVENT_SOURCE,
|
|
48
|
+
CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE,
|
|
49
|
+
CONTROL_EVENT_BUS_NAME_ENV_VAR,
|
|
50
|
+
OPENHI_REPO_TAG_KEY_ENV_VAR,
|
|
51
|
+
OPENHI_TAG_KEY_PREFIX_ENV_VAR,
|
|
52
|
+
PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM
|
|
53
|
+
} from "./chunk-VXX4I3EF.mjs";
|
|
54
|
+
import {
|
|
55
|
+
require_lib
|
|
56
|
+
} from "./chunk-SYBADQXI.mjs";
|
|
57
|
+
import "./chunk-AO3E22CS.mjs";
|
|
58
|
+
import "./chunk-YZZDUJHI.mjs";
|
|
59
|
+
import "./chunk-VYDIGFIX.mjs";
|
|
7
60
|
import {
|
|
8
61
|
__commonJS,
|
|
9
62
|
__toESM
|
|
10
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-LZOMFHX3.mjs";
|
|
11
64
|
|
|
12
65
|
// ../config/lib/open-hi-config.js
|
|
13
66
|
var require_open_hi_config = __commonJS({
|
|
@@ -45,7 +98,7 @@ var require_open_hi_config = __commonJS({
|
|
|
45
98
|
});
|
|
46
99
|
|
|
47
100
|
// ../config/lib/index.js
|
|
48
|
-
var
|
|
101
|
+
var require_lib2 = __commonJS({
|
|
49
102
|
"../config/lib/index.js"(exports) {
|
|
50
103
|
"use strict";
|
|
51
104
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -70,11 +123,11 @@ var require_lib = __commonJS({
|
|
|
70
123
|
});
|
|
71
124
|
|
|
72
125
|
// src/app/open-hi-app.ts
|
|
73
|
-
var import_config2 = __toESM(
|
|
126
|
+
var import_config2 = __toESM(require_lib2());
|
|
74
127
|
import { App } from "aws-cdk-lib";
|
|
75
128
|
|
|
76
129
|
// src/app/open-hi-environment.ts
|
|
77
|
-
var import_config = __toESM(
|
|
130
|
+
var import_config = __toESM(require_lib2());
|
|
78
131
|
import { Stage } from "aws-cdk-lib";
|
|
79
132
|
var OPEN_HI_ENVIRONMENT_SYMBOL = /* @__PURE__ */ Symbol.for(
|
|
80
133
|
"@openhi/constructs/core.OpenHiEnvironment"
|
|
@@ -276,7 +329,7 @@ var OpenHiApp = class _OpenHiApp extends App {
|
|
|
276
329
|
};
|
|
277
330
|
|
|
278
331
|
// src/app/open-hi-service.ts
|
|
279
|
-
var import_config3 = __toESM(
|
|
332
|
+
var import_config3 = __toESM(require_lib2());
|
|
280
333
|
import {
|
|
281
334
|
findGitBranch,
|
|
282
335
|
findGitRepoName,
|
|
@@ -284,6 +337,11 @@ import {
|
|
|
284
337
|
} from "@codedrifters/utils";
|
|
285
338
|
import { RemovalPolicy, Stack, Tags } from "aws-cdk-lib";
|
|
286
339
|
import { paramCase } from "change-case";
|
|
340
|
+
var OPENHI_TAG_SUFFIX_REPO_NAME = "repo-name";
|
|
341
|
+
var OPENHI_TAG_SUFFIX_BRANCH_NAME = "branch-name";
|
|
342
|
+
var OPENHI_TAG_SUFFIX_SERVICE_TYPE = "service-type";
|
|
343
|
+
var OPENHI_TAG_SUFFIX_STAGE_TYPE = "stage-type";
|
|
344
|
+
var openHiTagKey = (appName, suffix) => `${appName}:${suffix}`;
|
|
287
345
|
var OpenHiService = class extends Stack {
|
|
288
346
|
/**
|
|
289
347
|
* Creates a new OpenHI service stack.
|
|
@@ -351,11 +409,20 @@ var OpenHiService = class extends Stack {
|
|
|
351
409
|
`availability-zones:account=${account}:region=${region}`,
|
|
352
410
|
[`${region}a`, `${region}b`, `${region}c`]
|
|
353
411
|
);
|
|
354
|
-
Tags.of(this).add(`${appName}:repo-name`, repoName.slice(0, 255));
|
|
355
|
-
Tags.of(this).add(`${appName}:branch-name`, branchName.slice(0, 255));
|
|
356
|
-
Tags.of(this).add(`${appName}:service-type`, id.slice(0, 255));
|
|
357
412
|
Tags.of(this).add(
|
|
358
|
-
|
|
413
|
+
openHiTagKey(appName, OPENHI_TAG_SUFFIX_REPO_NAME),
|
|
414
|
+
repoName.slice(0, 255)
|
|
415
|
+
);
|
|
416
|
+
Tags.of(this).add(
|
|
417
|
+
openHiTagKey(appName, OPENHI_TAG_SUFFIX_BRANCH_NAME),
|
|
418
|
+
branchName.slice(0, 255)
|
|
419
|
+
);
|
|
420
|
+
Tags.of(this).add(
|
|
421
|
+
openHiTagKey(appName, OPENHI_TAG_SUFFIX_SERVICE_TYPE),
|
|
422
|
+
id.slice(0, 255)
|
|
423
|
+
);
|
|
424
|
+
Tags.of(this).add(
|
|
425
|
+
openHiTagKey(appName, OPENHI_TAG_SUFFIX_STAGE_TYPE),
|
|
359
426
|
ohEnv.ohStage.stageType.slice(0, 255)
|
|
360
427
|
);
|
|
361
428
|
}
|
|
@@ -711,14 +778,13 @@ import { Runtime as Runtime2 } from "aws-cdk-lib/aws-lambda";
|
|
|
711
778
|
import { NodejsFunction as NodejsFunction2 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
712
779
|
import { Construct as Construct2 } from "constructs";
|
|
713
780
|
var HANDLER_NAME2 = "post-confirmation.handler.js";
|
|
714
|
-
|
|
781
|
+
var resolveHandlerEntry2 = (dirname) => {
|
|
715
782
|
const sameDir = path2.join(dirname, HANDLER_NAME2);
|
|
716
783
|
if (fs2.existsSync(sameDir)) {
|
|
717
784
|
return sameDir;
|
|
718
785
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
}
|
|
786
|
+
return path2.join(dirname, "..", "..", "..", "lib", HANDLER_NAME2);
|
|
787
|
+
};
|
|
722
788
|
var PostConfirmationLambda = class extends Construct2 {
|
|
723
789
|
constructor(scope, props) {
|
|
724
790
|
super(scope, "post-confirmation-lambda");
|
|
@@ -727,7 +793,7 @@ var PostConfirmationLambda = class extends Construct2 {
|
|
|
727
793
|
runtime: Runtime2.NODEJS_LATEST,
|
|
728
794
|
memorySize: 1024,
|
|
729
795
|
environment: {
|
|
730
|
-
|
|
796
|
+
CONTROL_EVENT_BUS_NAME: props.controlEventBusName
|
|
731
797
|
}
|
|
732
798
|
});
|
|
733
799
|
}
|
|
@@ -939,6 +1005,204 @@ var DynamoDbDataStore = class extends Table {
|
|
|
939
1005
|
}
|
|
940
1006
|
};
|
|
941
1007
|
|
|
1008
|
+
// src/components/dynamodb/workflow-dedup-table.ts
|
|
1009
|
+
var import_workflows3 = __toESM(require_lib());
|
|
1010
|
+
import { Annotations } from "aws-cdk-lib";
|
|
1011
|
+
import { AttributeType as AttributeType2, BillingMode as BillingMode2, Table as Table2 } from "aws-cdk-lib/aws-dynamodb";
|
|
1012
|
+
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
1013
|
+
import { Construct as Construct5 } from "constructs";
|
|
1014
|
+
function getWorkflowDedupTableName(scope) {
|
|
1015
|
+
const stack = OpenHiService.of(scope);
|
|
1016
|
+
return `workflow-dedup-${stack.branchHash}`;
|
|
1017
|
+
}
|
|
1018
|
+
var _WorkflowDedupTable = class _WorkflowDedupTable extends Construct5 {
|
|
1019
|
+
constructor(scope, id, props = {}) {
|
|
1020
|
+
super(scope, id);
|
|
1021
|
+
this.registeredConsumers = /* @__PURE__ */ new Set();
|
|
1022
|
+
const service = OpenHiService.of(scope);
|
|
1023
|
+
const others = service.node.findAll().filter(
|
|
1024
|
+
(c) => c instanceof _WorkflowDedupTable && c !== this
|
|
1025
|
+
);
|
|
1026
|
+
if (others.length > 0) {
|
|
1027
|
+
throw new WorkflowDedupTableDuplicateError(
|
|
1028
|
+
`WorkflowDedupTable already exists at ${others[0].node.path}; only one shared dedup table is allowed per service stack (TR-015).`
|
|
1029
|
+
);
|
|
1030
|
+
}
|
|
1031
|
+
this.table = new Table2(this, "Table", {
|
|
1032
|
+
tableName: getWorkflowDedupTableName(scope),
|
|
1033
|
+
partitionKey: {
|
|
1034
|
+
name: "consumerName",
|
|
1035
|
+
type: AttributeType2.STRING
|
|
1036
|
+
},
|
|
1037
|
+
sortKey: {
|
|
1038
|
+
name: "sk",
|
|
1039
|
+
type: AttributeType2.STRING
|
|
1040
|
+
},
|
|
1041
|
+
billingMode: BillingMode2.PAY_PER_REQUEST,
|
|
1042
|
+
timeToLiveAttribute: "expiresAt",
|
|
1043
|
+
removalPolicy: props.removalPolicy ?? service.removalPolicy
|
|
1044
|
+
});
|
|
1045
|
+
new DiscoverableStringParameter(this, "table-name-param", {
|
|
1046
|
+
ssmParamName: _WorkflowDedupTable.TABLE_NAME_SSM_PARAM_NAME,
|
|
1047
|
+
stringValue: this.table.tableName
|
|
1048
|
+
});
|
|
1049
|
+
new DiscoverableStringParameter(this, "table-arn-param", {
|
|
1050
|
+
ssmParamName: _WorkflowDedupTable.TABLE_ARN_SSM_PARAM_NAME,
|
|
1051
|
+
stringValue: this.table.tableArn
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
/** Cross-stack lookup for the table name. */
|
|
1055
|
+
static tableNameFromLookup(scope) {
|
|
1056
|
+
return DiscoverableStringParameter.valueForLookupName(scope, {
|
|
1057
|
+
ssmParamName: _WorkflowDedupTable.TABLE_NAME_SSM_PARAM_NAME,
|
|
1058
|
+
serviceType: _WorkflowDedupTable.PUBLISHER_SERVICE_TYPE
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
/** Cross-stack lookup for the table ARN. */
|
|
1062
|
+
static tableArnFromLookup(scope) {
|
|
1063
|
+
return DiscoverableStringParameter.valueForLookupName(scope, {
|
|
1064
|
+
ssmParamName: _WorkflowDedupTable.TABLE_ARN_SSM_PARAM_NAME,
|
|
1065
|
+
serviceType: _WorkflowDedupTable.PUBLISHER_SERVICE_TYPE
|
|
1066
|
+
});
|
|
1067
|
+
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Cross-stack equivalent of {@link grantConsumer}. Use when the dedup
|
|
1070
|
+
* table is on a different stack than the consumer Lambda — the
|
|
1071
|
+
* grant resolves the table name + ARN via SSM at synth time, so the
|
|
1072
|
+
* consumer stack does not pick up a CloudFormation export dependency
|
|
1073
|
+
* on the global stack.
|
|
1074
|
+
*
|
|
1075
|
+
* Inverts the singleton-guard semantics of `grantConsumer`: there is
|
|
1076
|
+
* no synth-time check that the same `consumerName` was registered
|
|
1077
|
+
* twice across stacks. Consumer names are agreed by convention
|
|
1078
|
+
* (see TR-015); double-registration is operator error caught at
|
|
1079
|
+
* design time, not synth time.
|
|
1080
|
+
*/
|
|
1081
|
+
static grantConsumerFromLookup(scope, fn, consumerName, options = {}) {
|
|
1082
|
+
_WorkflowDedupTable.assertConsumerNameStatic(consumerName);
|
|
1083
|
+
const tableName = _WorkflowDedupTable.tableNameFromLookup(scope);
|
|
1084
|
+
const tableArn = _WorkflowDedupTable.tableArnFromLookup(scope);
|
|
1085
|
+
fn.addEnvironment(import_workflows3.WORKFLOW_DEDUP_TABLE_NAME_ENV_VAR, tableName);
|
|
1086
|
+
if (options.defaultTtlSeconds !== void 0) {
|
|
1087
|
+
fn.addEnvironment(
|
|
1088
|
+
"OPENHI_WORKFLOW_DEDUP_DEFAULT_TTL_SECONDS",
|
|
1089
|
+
String(options.defaultTtlSeconds)
|
|
1090
|
+
);
|
|
1091
|
+
}
|
|
1092
|
+
fn.addToRolePolicy(
|
|
1093
|
+
new PolicyStatement({
|
|
1094
|
+
effect: Effect.ALLOW,
|
|
1095
|
+
actions: [
|
|
1096
|
+
"dynamodb:PutItem",
|
|
1097
|
+
"dynamodb:UpdateItem",
|
|
1098
|
+
"dynamodb:GetItem",
|
|
1099
|
+
"dynamodb:Query"
|
|
1100
|
+
],
|
|
1101
|
+
resources: [tableArn],
|
|
1102
|
+
conditions: {
|
|
1103
|
+
"ForAllValues:StringEquals": {
|
|
1104
|
+
"dynamodb:LeadingKeys": [consumerName]
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
})
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Standalone consumer-name validator shared by the instance method
|
|
1112
|
+
* and `grantConsumerFromLookup` so the two grants enforce identical
|
|
1113
|
+
* invariants.
|
|
1114
|
+
*/
|
|
1115
|
+
static assertConsumerNameStatic(consumerName) {
|
|
1116
|
+
if (consumerName.length === 0) {
|
|
1117
|
+
throw new WorkflowDedupConsumerNameInvalidError(
|
|
1118
|
+
"consumerName must be non-empty."
|
|
1119
|
+
);
|
|
1120
|
+
}
|
|
1121
|
+
if (consumerName.length > import_workflows3.WORKFLOW_DEDUP_MAX_CONSUMER_NAME_LENGTH) {
|
|
1122
|
+
throw new WorkflowDedupConsumerNameInvalidError(
|
|
1123
|
+
`consumerName must be at most ${import_workflows3.WORKFLOW_DEDUP_MAX_CONSUMER_NAME_LENGTH} chars; got ${consumerName.length}.`
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1126
|
+
if (/\s/.test(consumerName)) {
|
|
1127
|
+
throw new WorkflowDedupConsumerNameInvalidError(
|
|
1128
|
+
"consumerName must not contain whitespace."
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Wire a Lambda consumer to this table. Injects the table-name env var
|
|
1134
|
+
* so the runtime `WorkflowDedupClient` can resolve it, then attaches a
|
|
1135
|
+
* per-consumer IAM grant scoped by `dynamodb:LeadingKeys` so the
|
|
1136
|
+
* consumer can only read/write its own partition.
|
|
1137
|
+
*/
|
|
1138
|
+
grantConsumer(fn, consumerName, options = {}) {
|
|
1139
|
+
this.assertConsumerName(consumerName);
|
|
1140
|
+
if (this.registeredConsumers.has(consumerName)) {
|
|
1141
|
+
Annotations.of(this).addWarning(
|
|
1142
|
+
`WorkflowDedupTable: consumerName "${consumerName}" registered more than once; subsequent grantConsumer calls add policy statements but do not re-inject the env var.`
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
this.registeredConsumers.add(consumerName);
|
|
1146
|
+
fn.addEnvironment(import_workflows3.WORKFLOW_DEDUP_TABLE_NAME_ENV_VAR, this.table.tableName);
|
|
1147
|
+
if (options.defaultTtlSeconds !== void 0) {
|
|
1148
|
+
fn.addEnvironment(
|
|
1149
|
+
"OPENHI_WORKFLOW_DEDUP_DEFAULT_TTL_SECONDS",
|
|
1150
|
+
String(options.defaultTtlSeconds)
|
|
1151
|
+
);
|
|
1152
|
+
}
|
|
1153
|
+
fn.addToRolePolicy(
|
|
1154
|
+
new PolicyStatement({
|
|
1155
|
+
effect: Effect.ALLOW,
|
|
1156
|
+
actions: [
|
|
1157
|
+
"dynamodb:PutItem",
|
|
1158
|
+
"dynamodb:UpdateItem",
|
|
1159
|
+
"dynamodb:GetItem",
|
|
1160
|
+
"dynamodb:Query"
|
|
1161
|
+
],
|
|
1162
|
+
resources: [this.table.tableArn],
|
|
1163
|
+
conditions: {
|
|
1164
|
+
"ForAllValues:StringEquals": {
|
|
1165
|
+
"dynamodb:LeadingKeys": [consumerName]
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
})
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1171
|
+
assertConsumerName(consumerName) {
|
|
1172
|
+
_WorkflowDedupTable.assertConsumerNameStatic(consumerName);
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
/** SSM param name (short) used by `DiscoverableStringParameter` for the table name lookup. */
|
|
1176
|
+
_WorkflowDedupTable.TABLE_NAME_SSM_PARAM_NAME = "workflow-dedup-table-name";
|
|
1177
|
+
/** SSM param name (short) used by `DiscoverableStringParameter` for the table ARN lookup. */
|
|
1178
|
+
_WorkflowDedupTable.TABLE_ARN_SSM_PARAM_NAME = "workflow-dedup-table-arn";
|
|
1179
|
+
/**
|
|
1180
|
+
* Service-type the publishing stack runs under. The cross-stack lookups
|
|
1181
|
+
* pin to this value so consumer stacks on a different service-type
|
|
1182
|
+
* (e.g. `data`, `auth`) resolve the parameter at the publisher's SSM
|
|
1183
|
+
* path instead of their own. Typed against `OpenHiServiceType` so a
|
|
1184
|
+
* future rename of the literal triggers a compile error; not pulled
|
|
1185
|
+
* from `OpenHiGlobalService.SERVICE_TYPE` because
|
|
1186
|
+
* `OpenHiGlobalService` already imports `WorkflowDedupTable` — a
|
|
1187
|
+
* back-import would create a circular dependency.
|
|
1188
|
+
*/
|
|
1189
|
+
_WorkflowDedupTable.PUBLISHER_SERVICE_TYPE = "global";
|
|
1190
|
+
var WorkflowDedupTable = _WorkflowDedupTable;
|
|
1191
|
+
var WorkflowDedupTableDuplicateError = class extends Error {
|
|
1192
|
+
/** @param message - human-readable description of the duplicate. */
|
|
1193
|
+
constructor(message) {
|
|
1194
|
+
super(message);
|
|
1195
|
+
this.name = "WorkflowDedupTableDuplicateError";
|
|
1196
|
+
}
|
|
1197
|
+
};
|
|
1198
|
+
var WorkflowDedupConsumerNameInvalidError = class extends Error {
|
|
1199
|
+
/** @param message - human-readable description of the invariant violation. */
|
|
1200
|
+
constructor(message) {
|
|
1201
|
+
super(message);
|
|
1202
|
+
this.name = "WorkflowDedupConsumerNameInvalidError";
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
|
|
942
1206
|
// src/components/event-bridge/data-event-bus.ts
|
|
943
1207
|
import { EventBus } from "aws-cdk-lib/aws-events";
|
|
944
1208
|
var DataEventBus = class _DataEventBus extends EventBus {
|
|
@@ -983,6 +1247,28 @@ var OpsEventBus = class _OpsEventBus extends EventBus2 {
|
|
|
983
1247
|
}
|
|
984
1248
|
};
|
|
985
1249
|
|
|
1250
|
+
// src/components/event-bridge/control-event-bus.ts
|
|
1251
|
+
import { EventBus as EventBus3 } from "aws-cdk-lib/aws-events";
|
|
1252
|
+
var ControlEventBus = class _ControlEventBus extends EventBus3 {
|
|
1253
|
+
/*****************************************************************************
|
|
1254
|
+
*
|
|
1255
|
+
* Return a name for this EventBus based on the stack environment hash. This
|
|
1256
|
+
* name is common across all stacks since it's using the environment hash in
|
|
1257
|
+
* its name.
|
|
1258
|
+
*
|
|
1259
|
+
****************************************************************************/
|
|
1260
|
+
static getEventBusName(scope) {
|
|
1261
|
+
const stack = OpenHiService.of(scope);
|
|
1262
|
+
return `controlv1${stack.branchHash}`;
|
|
1263
|
+
}
|
|
1264
|
+
constructor(scope, props) {
|
|
1265
|
+
super(scope, "control-event-bus-v1", {
|
|
1266
|
+
...props,
|
|
1267
|
+
eventBusName: _ControlEventBus.getEventBusName(scope)
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
|
|
986
1272
|
// src/components/postgres/data-store-postgres-replica.ts
|
|
987
1273
|
import fs5 from "fs";
|
|
988
1274
|
import path5 from "path";
|
|
@@ -992,7 +1278,7 @@ import { Runtime as Runtime5, StartingPosition } from "aws-cdk-lib/aws-lambda";
|
|
|
992
1278
|
import { KinesisEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
|
|
993
1279
|
import { NodejsFunction as NodejsFunction5 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
994
1280
|
import * as rds from "aws-cdk-lib/aws-rds";
|
|
995
|
-
import { Construct as
|
|
1281
|
+
import { Construct as Construct6 } from "constructs";
|
|
996
1282
|
var HANDLER_NAME5 = "data-store-postgres-replication.handler.js";
|
|
997
1283
|
var DEFAULT_DATABASE_NAME = "openhi";
|
|
998
1284
|
var SCHEMA_NAME_PATTERN = /^[a-z_][a-z0-9_]{0,62}$/;
|
|
@@ -1015,7 +1301,7 @@ function getPostgresReplicaSchemaName(branchHash) {
|
|
|
1015
1301
|
}
|
|
1016
1302
|
return candidate;
|
|
1017
1303
|
}
|
|
1018
|
-
var DataStorePostgresReplica = class extends
|
|
1304
|
+
var DataStorePostgresReplica = class extends Construct6 {
|
|
1019
1305
|
/**
|
|
1020
1306
|
* Resolve the cluster ARN published by an upstream {@link DataStorePostgresReplica}.
|
|
1021
1307
|
* Use from any stack that needs to grant `rds-data:ExecuteStatement` against
|
|
@@ -1170,8 +1456,8 @@ var ChildHostedZone = class extends HostedZone {
|
|
|
1170
1456
|
ChildHostedZone.SSM_PARAM_NAME = "CHILDHOSTEDZONE";
|
|
1171
1457
|
|
|
1172
1458
|
// src/components/route-53/root-hosted-zone.ts
|
|
1173
|
-
import { Construct as
|
|
1174
|
-
var RootHostedZone = class extends
|
|
1459
|
+
import { Construct as Construct7 } from "constructs";
|
|
1460
|
+
var RootHostedZone = class extends Construct7 {
|
|
1175
1461
|
};
|
|
1176
1462
|
|
|
1177
1463
|
// src/components/static-hosting/static-hosting.ts
|
|
@@ -1182,9 +1468,9 @@ import {
|
|
|
1182
1468
|
import { S3BucketOrigin } from "aws-cdk-lib/aws-cloudfront-origins";
|
|
1183
1469
|
import { Bucket as Bucket2 } from "aws-cdk-lib/aws-s3";
|
|
1184
1470
|
import { Duration as Duration5 } from "aws-cdk-lib/core";
|
|
1185
|
-
import { Construct as
|
|
1471
|
+
import { Construct as Construct8 } from "constructs";
|
|
1186
1472
|
var STATIC_HOSTING_SERVICE_TYPE = "website";
|
|
1187
|
-
var _StaticHosting = class _StaticHosting extends
|
|
1473
|
+
var _StaticHosting = class _StaticHosting extends Construct8 {
|
|
1188
1474
|
constructor(scope, id, props = {}) {
|
|
1189
1475
|
super(scope, id);
|
|
1190
1476
|
const stack = OpenHiService.of(scope);
|
|
@@ -1236,7 +1522,7 @@ _StaticHosting.SSM_PARAM_NAME_DISTRIBUTION_ARN = "STATIC_HOSTING_DISTRIBUTION_AR
|
|
|
1236
1522
|
var StaticHosting = _StaticHosting;
|
|
1237
1523
|
|
|
1238
1524
|
// src/services/open-hi-auth-service.ts
|
|
1239
|
-
var
|
|
1525
|
+
var import_config5 = __toESM(require_lib2());
|
|
1240
1526
|
import {
|
|
1241
1527
|
LambdaVersion,
|
|
1242
1528
|
UserPool as UserPool2,
|
|
@@ -1244,12 +1530,13 @@ import {
|
|
|
1244
1530
|
UserPoolDomain as UserPoolDomain2,
|
|
1245
1531
|
UserPoolOperation
|
|
1246
1532
|
} from "aws-cdk-lib/aws-cognito";
|
|
1247
|
-
import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
1533
|
+
import { Effect as Effect6, PolicyStatement as PolicyStatement6 } from "aws-cdk-lib/aws-iam";
|
|
1248
1534
|
import { Key as Key2 } from "aws-cdk-lib/aws-kms";
|
|
1249
|
-
import { Stack as
|
|
1535
|
+
import { Stack as Stack6 } from "aws-cdk-lib/core";
|
|
1250
1536
|
|
|
1251
1537
|
// src/services/open-hi-data-service.ts
|
|
1252
|
-
|
|
1538
|
+
var import_config4 = __toESM(require_lib2());
|
|
1539
|
+
import { StreamViewType, Table as Table3 } from "aws-cdk-lib/aws-dynamodb";
|
|
1253
1540
|
import * as kinesis from "aws-cdk-lib/aws-kinesis";
|
|
1254
1541
|
|
|
1255
1542
|
// src/services/open-hi-global-service.ts
|
|
@@ -1257,11 +1544,99 @@ import {
|
|
|
1257
1544
|
Certificate as Certificate2,
|
|
1258
1545
|
CertificateValidation
|
|
1259
1546
|
} from "aws-cdk-lib/aws-certificatemanager";
|
|
1260
|
-
import { EventBus as
|
|
1547
|
+
import { EventBus as EventBus4 } from "aws-cdk-lib/aws-events";
|
|
1261
1548
|
import {
|
|
1262
1549
|
HostedZone as HostedZone2
|
|
1263
1550
|
} from "aws-cdk-lib/aws-route53";
|
|
1264
1551
|
import { StringParameter as StringParameter3 } from "aws-cdk-lib/aws-ssm";
|
|
1552
|
+
|
|
1553
|
+
// src/workflows/control-plane/platform-deploy-bridge/platform-deploy-bridge.ts
|
|
1554
|
+
import { Construct as Construct10 } from "constructs";
|
|
1555
|
+
|
|
1556
|
+
// src/workflows/control-plane/platform-deploy-bridge/platform-deploy-bridge-lambda.ts
|
|
1557
|
+
import fs6 from "fs";
|
|
1558
|
+
import path6 from "path";
|
|
1559
|
+
import { Duration as Duration6, Stack as Stack3 } from "aws-cdk-lib";
|
|
1560
|
+
import { Rule } from "aws-cdk-lib/aws-events";
|
|
1561
|
+
import { LambdaFunction } from "aws-cdk-lib/aws-events-targets";
|
|
1562
|
+
import { Effect as Effect2, PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
|
|
1563
|
+
import { Runtime as Runtime6 } from "aws-cdk-lib/aws-lambda";
|
|
1564
|
+
import { NodejsFunction as NodejsFunction6 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
1565
|
+
import { Construct as Construct9 } from "constructs";
|
|
1566
|
+
var HANDLER_NAME6 = "platform-deploy-bridge.handler.js";
|
|
1567
|
+
function resolveHandlerEntry6(dirname) {
|
|
1568
|
+
const sameDir = path6.join(dirname, HANDLER_NAME6);
|
|
1569
|
+
if (fs6.existsSync(sameDir)) {
|
|
1570
|
+
return sameDir;
|
|
1571
|
+
}
|
|
1572
|
+
return path6.join(dirname, "..", "..", "..", "..", "lib", HANDLER_NAME6);
|
|
1573
|
+
}
|
|
1574
|
+
var PlatformDeployBridgeLambda = class extends Construct9 {
|
|
1575
|
+
constructor(scope, props) {
|
|
1576
|
+
super(scope, "platform-deploy-bridge-lambda");
|
|
1577
|
+
const service = OpenHiService.of(this);
|
|
1578
|
+
const repoTagKey = openHiTagKey(
|
|
1579
|
+
service.appName,
|
|
1580
|
+
OPENHI_TAG_SUFFIX_REPO_NAME
|
|
1581
|
+
);
|
|
1582
|
+
const tagKeyPrefix = `${service.appName}:`;
|
|
1583
|
+
const ownStackName = Stack3.of(this).stackName;
|
|
1584
|
+
const ownSuffix = `-${service.serviceId}-${Stack3.of(this).account}-${Stack3.of(this).region}`;
|
|
1585
|
+
const sharedPrefix = ownStackName.endsWith(ownSuffix) ? ownStackName.slice(0, -ownSuffix.length) : service.branchHash;
|
|
1586
|
+
const stackIdPrefix = `arn:aws:cloudformation:${Stack3.of(this).region}:${Stack3.of(this).account}:stack/${sharedPrefix}-`;
|
|
1587
|
+
this.lambda = new NodejsFunction6(this, "handler", {
|
|
1588
|
+
entry: resolveHandlerEntry6(__dirname),
|
|
1589
|
+
runtime: Runtime6.NODEJS_LATEST,
|
|
1590
|
+
memorySize: 256,
|
|
1591
|
+
timeout: Duration6.seconds(30),
|
|
1592
|
+
environment: {
|
|
1593
|
+
[CONTROL_EVENT_BUS_NAME_ENV_VAR]: props.controlEventBus.eventBusName,
|
|
1594
|
+
[OPENHI_REPO_TAG_KEY_ENV_VAR]: repoTagKey,
|
|
1595
|
+
[OPENHI_TAG_KEY_PREFIX_ENV_VAR]: tagKeyPrefix
|
|
1596
|
+
}
|
|
1597
|
+
});
|
|
1598
|
+
this.lambda.addToRolePolicy(
|
|
1599
|
+
new PolicyStatement2({
|
|
1600
|
+
effect: Effect2.ALLOW,
|
|
1601
|
+
actions: ["cloudformation:DescribeStacks"],
|
|
1602
|
+
resources: [
|
|
1603
|
+
`arn:aws:cloudformation:${Stack3.of(this).region}:${Stack3.of(this).account}:stack/*`
|
|
1604
|
+
]
|
|
1605
|
+
})
|
|
1606
|
+
);
|
|
1607
|
+
props.controlEventBus.grantPutEventsTo(this.lambda);
|
|
1608
|
+
this.rule = new Rule(this, "rule", {
|
|
1609
|
+
eventPattern: {
|
|
1610
|
+
source: [CLOUDFORMATION_EVENT_SOURCE],
|
|
1611
|
+
detailType: [CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE],
|
|
1612
|
+
detail: {
|
|
1613
|
+
"stack-id": [{ prefix: stackIdPrefix }],
|
|
1614
|
+
"status-details": {
|
|
1615
|
+
status: [...BRIDGED_STATUSES]
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
},
|
|
1619
|
+
targets: [
|
|
1620
|
+
new LambdaFunction(this.lambda, {
|
|
1621
|
+
retryAttempts: 2,
|
|
1622
|
+
maxEventAge: Duration6.hours(2)
|
|
1623
|
+
})
|
|
1624
|
+
]
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
};
|
|
1628
|
+
|
|
1629
|
+
// src/workflows/control-plane/platform-deploy-bridge/platform-deploy-bridge.ts
|
|
1630
|
+
var PlatformDeployBridge = class extends Construct10 {
|
|
1631
|
+
constructor(scope, props) {
|
|
1632
|
+
super(scope, "platform-deploy-bridge");
|
|
1633
|
+
this.bridgeLambda = new PlatformDeployBridgeLambda(this, {
|
|
1634
|
+
controlEventBus: props.controlEventBus
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
|
|
1639
|
+
// src/services/open-hi-global-service.ts
|
|
1265
1640
|
var _OpenHiGlobalService = class _OpenHiGlobalService extends OpenHiService {
|
|
1266
1641
|
/**
|
|
1267
1642
|
* Returns an IHostedZone from the given attributes (no SSM). Use when the zone is imported from config.
|
|
@@ -1300,7 +1675,7 @@ var _OpenHiGlobalService = class _OpenHiGlobalService extends OpenHiService {
|
|
|
1300
1675
|
* Returns the data event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
|
|
1301
1676
|
*/
|
|
1302
1677
|
static dataEventBusFromConstruct(scope) {
|
|
1303
|
-
return
|
|
1678
|
+
return EventBus4.fromEventBusName(
|
|
1304
1679
|
scope,
|
|
1305
1680
|
"data-event-bus",
|
|
1306
1681
|
DataEventBus.getEventBusName(scope)
|
|
@@ -1310,12 +1685,33 @@ var _OpenHiGlobalService = class _OpenHiGlobalService extends OpenHiService {
|
|
|
1310
1685
|
* Returns the ops event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
|
|
1311
1686
|
*/
|
|
1312
1687
|
static opsEventBusFromConstruct(scope) {
|
|
1313
|
-
return
|
|
1688
|
+
return EventBus4.fromEventBusName(
|
|
1314
1689
|
scope,
|
|
1315
1690
|
"ops-event-bus",
|
|
1316
1691
|
OpsEventBus.getEventBusName(scope)
|
|
1317
1692
|
);
|
|
1318
1693
|
}
|
|
1694
|
+
/**
|
|
1695
|
+
* Returns the control-plane event bus by name (deterministic per branch). Use from other stacks to obtain an IEventBus reference.
|
|
1696
|
+
*/
|
|
1697
|
+
static controlEventBusFromConstruct(scope) {
|
|
1698
|
+
return EventBus4.fromEventBusName(
|
|
1699
|
+
scope,
|
|
1700
|
+
"control-event-bus",
|
|
1701
|
+
ControlEventBus.getEventBusName(scope)
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Returns the workflow dedup table by name (deterministic per branch).
|
|
1706
|
+
* Use from other stacks to obtain an ITable reference. Consumer Lambdas
|
|
1707
|
+
* are typically wired via `WorkflowDedupTable.grantConsumer(fn, name)`
|
|
1708
|
+
* on the owning service's `workflowDedupTable` reference; the
|
|
1709
|
+
* `tableNameFromLookup` / `tableArnFromLookup` SSM helpers on the
|
|
1710
|
+
* construct cover cross-stack consumers that need only the name/ARN.
|
|
1711
|
+
*/
|
|
1712
|
+
static workflowDedupTableNameFromLookup(scope) {
|
|
1713
|
+
return WorkflowDedupTable.tableNameFromLookup(scope);
|
|
1714
|
+
}
|
|
1319
1715
|
get serviceType() {
|
|
1320
1716
|
return _OpenHiGlobalService.SERVICE_TYPE;
|
|
1321
1717
|
}
|
|
@@ -1328,6 +1724,9 @@ var _OpenHiGlobalService = class _OpenHiGlobalService extends OpenHiService {
|
|
|
1328
1724
|
this.rootWildcardCertificate = this.createRootWildcardCertificate();
|
|
1329
1725
|
this.dataEventBus = this.createDataEventBus();
|
|
1330
1726
|
this.opsEventBus = this.createOpsEventBus();
|
|
1727
|
+
this.controlEventBus = this.createControlEventBus();
|
|
1728
|
+
this.workflowDedupTable = this.createWorkflowDedupTable();
|
|
1729
|
+
this.platformDeployBridge = this.createPlatformDeployBridge();
|
|
1331
1730
|
}
|
|
1332
1731
|
/**
|
|
1333
1732
|
* Validates that config required for the Global stack is present.
|
|
@@ -1392,23 +1791,249 @@ var _OpenHiGlobalService = class _OpenHiGlobalService extends OpenHiService {
|
|
|
1392
1791
|
createOpsEventBus() {
|
|
1393
1792
|
return new OpsEventBus(this);
|
|
1394
1793
|
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Creates the control-plane event bus.
|
|
1796
|
+
* Override to customize.
|
|
1797
|
+
*/
|
|
1798
|
+
createControlEventBus() {
|
|
1799
|
+
return new ControlEventBus(this);
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Creates the platform deploy bridge that republishes CloudFormation
|
|
1803
|
+
* Stack Status Change events onto the control event bus.
|
|
1804
|
+
* Override to customize.
|
|
1805
|
+
*/
|
|
1806
|
+
createPlatformDeployBridge() {
|
|
1807
|
+
return new PlatformDeployBridge(this, {
|
|
1808
|
+
controlEventBus: this.controlEventBus
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Creates the shared workflow dedup table (TR-015 singleton).
|
|
1813
|
+
* Override to customize.
|
|
1814
|
+
*/
|
|
1815
|
+
createWorkflowDedupTable() {
|
|
1816
|
+
return new WorkflowDedupTable(this, "workflow-dedup-table");
|
|
1817
|
+
}
|
|
1395
1818
|
};
|
|
1396
1819
|
_OpenHiGlobalService.SERVICE_TYPE = "global";
|
|
1397
1820
|
var OpenHiGlobalService = _OpenHiGlobalService;
|
|
1398
1821
|
|
|
1399
|
-
// src/
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1822
|
+
// src/workflows/control-plane/seed-demo-data/seed-demo-data-lambda.ts
|
|
1823
|
+
import fs7 from "fs";
|
|
1824
|
+
import path7 from "path";
|
|
1825
|
+
import { CONTROL_PLANE_ROLE_IDS } from "@openhi/types";
|
|
1826
|
+
import { Duration as Duration7, Stack as Stack4 } from "aws-cdk-lib";
|
|
1827
|
+
import { Rule as Rule2 } from "aws-cdk-lib/aws-events";
|
|
1828
|
+
import { LambdaFunction as LambdaFunction2 } from "aws-cdk-lib/aws-events-targets";
|
|
1829
|
+
import { Effect as Effect3, PolicyStatement as PolicyStatement3 } from "aws-cdk-lib/aws-iam";
|
|
1830
|
+
import { Runtime as Runtime7 } from "aws-cdk-lib/aws-lambda";
|
|
1831
|
+
import { NodejsFunction as NodejsFunction7 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
1832
|
+
import { Construct as Construct11 } from "constructs";
|
|
1833
|
+
var HANDLER_NAME7 = "seed-demo-data.handler.js";
|
|
1834
|
+
function resolveHandlerEntry7(dirname) {
|
|
1835
|
+
const sameDir = path7.join(dirname, HANDLER_NAME7);
|
|
1836
|
+
if (fs7.existsSync(sameDir)) {
|
|
1837
|
+
return sameDir;
|
|
1406
1838
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1839
|
+
return path7.join(dirname, "..", "..", "..", "..", "lib", HANDLER_NAME7);
|
|
1840
|
+
}
|
|
1841
|
+
var SeedDemoDataLambda = class extends Construct11 {
|
|
1842
|
+
constructor(scope, props) {
|
|
1843
|
+
super(scope, "seed-demo-data-lambda");
|
|
1844
|
+
this.lambda = new NodejsFunction7(this, "handler", {
|
|
1845
|
+
entry: resolveHandlerEntry7(__dirname),
|
|
1846
|
+
runtime: Runtime7.NODEJS_LATEST,
|
|
1847
|
+
memorySize: 512,
|
|
1848
|
+
timeout: Duration7.minutes(2),
|
|
1849
|
+
environment: {
|
|
1850
|
+
DYNAMO_TABLE_NAME: props.dataStoreTable.tableName,
|
|
1851
|
+
[SEED_DEMO_DATA_USER_POOL_ID_ENV_VAR]: props.userPool.userPoolId
|
|
1852
|
+
}
|
|
1853
|
+
});
|
|
1854
|
+
const roleReadKeys = Object.values(CONTROL_PLANE_ROLE_IDS).map(
|
|
1855
|
+
rolePartitionKey
|
|
1856
|
+
);
|
|
1857
|
+
this.lambda.addToRolePolicy(
|
|
1858
|
+
new PolicyStatement3({
|
|
1859
|
+
effect: Effect3.ALLOW,
|
|
1860
|
+
actions: ["dynamodb:GetItem"],
|
|
1861
|
+
resources: [props.dataStoreTable.tableArn],
|
|
1862
|
+
conditions: {
|
|
1863
|
+
"ForAllValues:StringEquals": {
|
|
1864
|
+
"dynamodb:LeadingKeys": roleReadKeys
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
})
|
|
1868
|
+
);
|
|
1869
|
+
const writeKeys = [
|
|
1870
|
+
...demoBasePartitionKeys(),
|
|
1871
|
+
...demoDevUserPartitionKeys(DEV_USERS)
|
|
1872
|
+
];
|
|
1873
|
+
this.lambda.addToRolePolicy(
|
|
1874
|
+
new PolicyStatement3({
|
|
1875
|
+
effect: Effect3.ALLOW,
|
|
1876
|
+
actions: ["dynamodb:PutItem", "dynamodb:UpdateItem"],
|
|
1877
|
+
resources: [props.dataStoreTable.tableArn],
|
|
1878
|
+
conditions: {
|
|
1879
|
+
"ForAllValues:StringEquals": {
|
|
1880
|
+
"dynamodb:LeadingKeys": writeKeys
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
})
|
|
1884
|
+
);
|
|
1885
|
+
this.lambda.addToRolePolicy(
|
|
1886
|
+
new PolicyStatement3({
|
|
1887
|
+
effect: Effect3.ALLOW,
|
|
1888
|
+
actions: [
|
|
1889
|
+
"cognito-idp:AdminCreateUser",
|
|
1890
|
+
"cognito-idp:AdminGetUser",
|
|
1891
|
+
"cognito-idp:AdminSetUserPassword"
|
|
1892
|
+
],
|
|
1893
|
+
resources: [
|
|
1894
|
+
Stack4.of(this).formatArn({
|
|
1895
|
+
service: "cognito-idp",
|
|
1896
|
+
resource: "userpool",
|
|
1897
|
+
resourceName: props.userPool.userPoolId
|
|
1898
|
+
})
|
|
1899
|
+
]
|
|
1900
|
+
})
|
|
1901
|
+
);
|
|
1902
|
+
this.rule = new Rule2(this, "rule", {
|
|
1903
|
+
eventBus: props.controlEventBus,
|
|
1904
|
+
eventPattern: {
|
|
1905
|
+
source: [import_workflows.PlatformSystemDataSeededV1.source],
|
|
1906
|
+
detailType: [import_workflows.PlatformSystemDataSeededV1.detailType]
|
|
1907
|
+
},
|
|
1908
|
+
targets: [
|
|
1909
|
+
new LambdaFunction2(this.lambda, {
|
|
1910
|
+
retryAttempts: 2,
|
|
1911
|
+
maxEventAge: Duration7.hours(2)
|
|
1912
|
+
})
|
|
1913
|
+
]
|
|
1914
|
+
});
|
|
1915
|
+
}
|
|
1916
|
+
};
|
|
1917
|
+
|
|
1918
|
+
// src/workflows/control-plane/seed-demo-data/seed-demo-data-workflow.ts
|
|
1919
|
+
import { Construct as Construct12 } from "constructs";
|
|
1920
|
+
var SeedDemoDataWorkflow = class extends Construct12 {
|
|
1921
|
+
constructor(scope, props) {
|
|
1922
|
+
super(scope, "seed-demo-data-workflow");
|
|
1923
|
+
this.seedDemoData = new SeedDemoDataLambda(this, {
|
|
1924
|
+
controlEventBus: props.controlEventBus,
|
|
1925
|
+
dataStoreTable: props.dataStoreTable,
|
|
1926
|
+
userPool: props.userPool
|
|
1927
|
+
});
|
|
1928
|
+
WorkflowDedupTable.grantConsumerFromLookup(
|
|
1929
|
+
this,
|
|
1930
|
+
this.seedDemoData.lambda,
|
|
1931
|
+
SEED_DEMO_DATA_CONSUMER_NAME
|
|
1932
|
+
);
|
|
1933
|
+
}
|
|
1934
|
+
};
|
|
1935
|
+
|
|
1936
|
+
// src/workflows/control-plane/seed-system-data/seed-system-data-lambda.ts
|
|
1937
|
+
import fs8 from "fs";
|
|
1938
|
+
import path8 from "path";
|
|
1939
|
+
import { CONTROL_PLANE_ROLE_IDS as CONTROL_PLANE_ROLE_IDS2 } from "@openhi/types";
|
|
1940
|
+
import { Duration as Duration8, Stack as Stack5 } from "aws-cdk-lib";
|
|
1941
|
+
import { Rule as Rule3 } from "aws-cdk-lib/aws-events";
|
|
1942
|
+
import { LambdaFunction as LambdaFunction3 } from "aws-cdk-lib/aws-events-targets";
|
|
1943
|
+
import { Effect as Effect4, PolicyStatement as PolicyStatement4 } from "aws-cdk-lib/aws-iam";
|
|
1944
|
+
import { Runtime as Runtime8 } from "aws-cdk-lib/aws-lambda";
|
|
1945
|
+
import { NodejsFunction as NodejsFunction8 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
1946
|
+
import { Construct as Construct13 } from "constructs";
|
|
1947
|
+
var HANDLER_NAME8 = "seed-system-data.handler.js";
|
|
1948
|
+
function resolveHandlerEntry8(dirname) {
|
|
1949
|
+
const sameDir = path8.join(dirname, HANDLER_NAME8);
|
|
1950
|
+
if (fs8.existsSync(sameDir)) {
|
|
1951
|
+
return sameDir;
|
|
1952
|
+
}
|
|
1953
|
+
return path8.join(dirname, "..", "..", "..", "..", "lib", HANDLER_NAME8);
|
|
1954
|
+
}
|
|
1955
|
+
var SeedSystemDataLambda = class extends Construct13 {
|
|
1956
|
+
constructor(scope, props) {
|
|
1957
|
+
super(scope, "seed-system-data-lambda");
|
|
1958
|
+
this.lambda = new NodejsFunction8(this, "handler", {
|
|
1959
|
+
entry: resolveHandlerEntry8(__dirname),
|
|
1960
|
+
runtime: Runtime8.NODEJS_LATEST,
|
|
1961
|
+
memorySize: 512,
|
|
1962
|
+
timeout: Duration8.minutes(1),
|
|
1963
|
+
environment: {
|
|
1964
|
+
DYNAMO_TABLE_NAME: props.dataStoreTable.tableName,
|
|
1965
|
+
[SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR]: props.controlEventBus.eventBusName
|
|
1966
|
+
}
|
|
1967
|
+
});
|
|
1968
|
+
const roleArns = Object.values(CONTROL_PLANE_ROLE_IDS2).map(
|
|
1969
|
+
(id) => `role#id#${id}`
|
|
1970
|
+
);
|
|
1971
|
+
this.lambda.addToRolePolicy(
|
|
1972
|
+
new PolicyStatement4({
|
|
1973
|
+
effect: Effect4.ALLOW,
|
|
1974
|
+
actions: ["dynamodb:PutItem", "dynamodb:UpdateItem"],
|
|
1975
|
+
resources: [props.dataStoreTable.tableArn],
|
|
1976
|
+
conditions: {
|
|
1977
|
+
"ForAllValues:StringEquals": {
|
|
1978
|
+
"dynamodb:LeadingKeys": roleArns
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
})
|
|
1982
|
+
);
|
|
1983
|
+
props.controlEventBus.grantPutEventsTo(this.lambda);
|
|
1984
|
+
const hostStackName = Stack5.of(this).stackName;
|
|
1985
|
+
this.rule = new Rule3(this, "rule", {
|
|
1986
|
+
eventBus: props.controlEventBus,
|
|
1987
|
+
eventPattern: {
|
|
1988
|
+
source: [import_workflows2.PlatformDeploymentCompletedV1.source],
|
|
1989
|
+
detailType: [import_workflows2.PlatformDeploymentCompletedV1.detailType],
|
|
1990
|
+
detail: {
|
|
1991
|
+
payload: {
|
|
1992
|
+
stackName: [hostStackName]
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
},
|
|
1996
|
+
targets: [
|
|
1997
|
+
new LambdaFunction3(this.lambda, {
|
|
1998
|
+
retryAttempts: 2,
|
|
1999
|
+
maxEventAge: Duration8.hours(2)
|
|
2000
|
+
})
|
|
2001
|
+
]
|
|
2002
|
+
});
|
|
1409
2003
|
}
|
|
2004
|
+
};
|
|
2005
|
+
|
|
2006
|
+
// src/workflows/control-plane/seed-system-data/seed-system-data-workflow.ts
|
|
2007
|
+
import { Construct as Construct14 } from "constructs";
|
|
2008
|
+
var SeedSystemDataWorkflow = class extends Construct14 {
|
|
2009
|
+
constructor(scope, props) {
|
|
2010
|
+
super(scope, "seed-system-data-workflow");
|
|
2011
|
+
this.seedSystemData = new SeedSystemDataLambda(this, {
|
|
2012
|
+
controlEventBus: props.controlEventBus,
|
|
2013
|
+
dataStoreTable: props.dataStoreTable
|
|
2014
|
+
});
|
|
2015
|
+
WorkflowDedupTable.grantConsumerFromLookup(
|
|
2016
|
+
this,
|
|
2017
|
+
this.seedSystemData.lambda,
|
|
2018
|
+
SEED_SYSTEM_DATA_CONSUMER_NAME
|
|
2019
|
+
);
|
|
2020
|
+
}
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
// src/services/open-hi-data-service.ts
|
|
2024
|
+
var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
|
|
1410
2025
|
constructor(ohEnv, props = {}) {
|
|
1411
2026
|
super(ohEnv, _OpenHiDataService.SERVICE_TYPE, props);
|
|
2027
|
+
/**
|
|
2028
|
+
* Cached control-event-bus lookup. `OpenHiGlobalService.controlEventBusFromConstruct`
|
|
2029
|
+
* registers a child `EventBus.fromEventBusName` construct with a
|
|
2030
|
+
* fixed id under the scope it is passed, so calling it twice on the
|
|
2031
|
+
* same `OpenHiDataService` instance collides. The cache mirrors the
|
|
2032
|
+
* `private controlEventBus()` pattern already used in
|
|
2033
|
+
* `OpenHiAuthService`. Use {@link controlEventBus} from this class
|
|
2034
|
+
* — never call the static lookup from inside `OpenHiDataService`.
|
|
2035
|
+
*/
|
|
2036
|
+
this._controlEventBus = null;
|
|
1412
2037
|
this.props = props;
|
|
1413
2038
|
this.dataStoreChangeStream = new kinesis.Stream(
|
|
1414
2039
|
this,
|
|
@@ -1443,6 +2068,53 @@ var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
|
|
|
1443
2068
|
branchHash: this.branchHash
|
|
1444
2069
|
}
|
|
1445
2070
|
);
|
|
2071
|
+
this.seedSystemDataWorkflow = this.createSeedSystemDataWorkflow();
|
|
2072
|
+
this.seedDemoDataWorkflow = this.createSeedDemoDataWorkflow();
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Returns the data store table by name. Use from other stacks (e.g. REST API Lambda) to obtain an ITable reference.
|
|
2076
|
+
*/
|
|
2077
|
+
static dynamoDbDataStoreFromConstruct(scope, id = "dynamo-db-data-store") {
|
|
2078
|
+
return Table3.fromTableName(scope, id, getDynamoDbDataStoreTableName(scope));
|
|
2079
|
+
}
|
|
2080
|
+
get serviceType() {
|
|
2081
|
+
return _OpenHiDataService.SERVICE_TYPE;
|
|
2082
|
+
}
|
|
2083
|
+
/**
|
|
2084
|
+
* Lazily looks up the control event bus exactly once per
|
|
2085
|
+
* `OpenHiDataService` instance and caches the reference. Every
|
|
2086
|
+
* workflow that consumes the bus must read it through this method
|
|
2087
|
+
* — see {@link _controlEventBus} for the underlying collision risk.
|
|
2088
|
+
*/
|
|
2089
|
+
controlEventBus() {
|
|
2090
|
+
if (this._controlEventBus === null) {
|
|
2091
|
+
this._controlEventBus = OpenHiGlobalService.controlEventBusFromConstruct(this);
|
|
2092
|
+
}
|
|
2093
|
+
return this._controlEventBus;
|
|
2094
|
+
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Creates the seed-system-data workflow. Override to customize.
|
|
2097
|
+
*/
|
|
2098
|
+
createSeedSystemDataWorkflow() {
|
|
2099
|
+
return new SeedSystemDataWorkflow(this, {
|
|
2100
|
+
controlEventBus: this.controlEventBus(),
|
|
2101
|
+
dataStoreTable: this.dataStore
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
/**
|
|
2105
|
+
* Creates the seed-demo-data workflow — but only on non-prod
|
|
2106
|
+
* stages. Returns `undefined` on prod so the workflow literally
|
|
2107
|
+
* does not exist in prod stacks. Override to customize.
|
|
2108
|
+
*/
|
|
2109
|
+
createSeedDemoDataWorkflow() {
|
|
2110
|
+
if (this.ohEnv.ohStage.stageType === import_config4.OPEN_HI_STAGE.PROD) {
|
|
2111
|
+
return void 0;
|
|
2112
|
+
}
|
|
2113
|
+
return new SeedDemoDataWorkflow(this, {
|
|
2114
|
+
controlEventBus: this.controlEventBus(),
|
|
2115
|
+
dataStoreTable: this.dataStore,
|
|
2116
|
+
userPool: OpenHiAuthService.userPoolFromConstruct(this)
|
|
2117
|
+
});
|
|
1446
2118
|
}
|
|
1447
2119
|
/**
|
|
1448
2120
|
* Creates the single-table DynamoDB data store.
|
|
@@ -1458,6 +2130,75 @@ var _OpenHiDataService = class _OpenHiDataService extends OpenHiService {
|
|
|
1458
2130
|
_OpenHiDataService.SERVICE_TYPE = "data";
|
|
1459
2131
|
var OpenHiDataService = _OpenHiDataService;
|
|
1460
2132
|
|
|
2133
|
+
// src/workflows/control-plane/user-onboarding/provision-default-workspace-lambda.ts
|
|
2134
|
+
import fs9 from "fs";
|
|
2135
|
+
import path9 from "path";
|
|
2136
|
+
import { Duration as Duration9 } from "aws-cdk-lib";
|
|
2137
|
+
import { Rule as Rule4 } from "aws-cdk-lib/aws-events";
|
|
2138
|
+
import { LambdaFunction as LambdaFunction4 } from "aws-cdk-lib/aws-events-targets";
|
|
2139
|
+
import { Effect as Effect5, PolicyStatement as PolicyStatement5 } from "aws-cdk-lib/aws-iam";
|
|
2140
|
+
import { Runtime as Runtime9 } from "aws-cdk-lib/aws-lambda";
|
|
2141
|
+
import { NodejsFunction as NodejsFunction9 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
2142
|
+
import { Construct as Construct15 } from "constructs";
|
|
2143
|
+
var HANDLER_NAME9 = "provision-default-workspace.handler.js";
|
|
2144
|
+
function resolveHandlerEntry9(dirname) {
|
|
2145
|
+
const sameDir = path9.join(dirname, HANDLER_NAME9);
|
|
2146
|
+
if (fs9.existsSync(sameDir)) {
|
|
2147
|
+
return sameDir;
|
|
2148
|
+
}
|
|
2149
|
+
return path9.join(dirname, "..", "..", "..", "..", "lib", HANDLER_NAME9);
|
|
2150
|
+
}
|
|
2151
|
+
var ProvisionDefaultWorkspaceLambda = class extends Construct15 {
|
|
2152
|
+
constructor(scope, props) {
|
|
2153
|
+
super(scope, "provision-default-workspace-lambda");
|
|
2154
|
+
this.lambda = new NodejsFunction9(this, "handler", {
|
|
2155
|
+
entry: resolveHandlerEntry9(__dirname),
|
|
2156
|
+
runtime: Runtime9.NODEJS_LATEST,
|
|
2157
|
+
memorySize: 1024,
|
|
2158
|
+
environment: {
|
|
2159
|
+
DYNAMO_TABLE_NAME: props.dataStoreTable.tableName
|
|
2160
|
+
}
|
|
2161
|
+
});
|
|
2162
|
+
props.dataStoreTable.grant(
|
|
2163
|
+
this.lambda,
|
|
2164
|
+
"dynamodb:PutItem",
|
|
2165
|
+
"dynamodb:UpdateItem"
|
|
2166
|
+
);
|
|
2167
|
+
this.lambda.addToRolePolicy(
|
|
2168
|
+
new PolicyStatement5({
|
|
2169
|
+
effect: Effect5.ALLOW,
|
|
2170
|
+
actions: ["dynamodb:Query"],
|
|
2171
|
+
resources: [`${props.dataStoreTable.tableArn}/index/*`]
|
|
2172
|
+
})
|
|
2173
|
+
);
|
|
2174
|
+
this.rule = new Rule4(this, "rule", {
|
|
2175
|
+
eventBus: props.controlEventBus,
|
|
2176
|
+
eventPattern: {
|
|
2177
|
+
source: [USER_ONBOARDING_EVENT_SOURCE],
|
|
2178
|
+
detailType: [PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE]
|
|
2179
|
+
},
|
|
2180
|
+
targets: [
|
|
2181
|
+
new LambdaFunction4(this.lambda, {
|
|
2182
|
+
retryAttempts: 2,
|
|
2183
|
+
maxEventAge: Duration9.hours(2)
|
|
2184
|
+
})
|
|
2185
|
+
]
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
};
|
|
2189
|
+
|
|
2190
|
+
// src/workflows/control-plane/user-onboarding/user-onboarding-workflow.ts
|
|
2191
|
+
import { Construct as Construct16 } from "constructs";
|
|
2192
|
+
var UserOnboardingWorkflow = class extends Construct16 {
|
|
2193
|
+
constructor(scope, props) {
|
|
2194
|
+
super(scope, "user-onboarding-workflow");
|
|
2195
|
+
this.provisionDefaultWorkspace = new ProvisionDefaultWorkspaceLambda(this, {
|
|
2196
|
+
dataStoreTable: props.dataStoreTable,
|
|
2197
|
+
controlEventBus: props.controlEventBus
|
|
2198
|
+
});
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
|
|
1461
2202
|
// src/services/open-hi-auth-service.ts
|
|
1462
2203
|
var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
1463
2204
|
constructor(ohEnv, props = {}) {
|
|
@@ -1469,11 +2210,13 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1469
2210
|
* would collide.
|
|
1470
2211
|
*/
|
|
1471
2212
|
this._dataStoreTable = null;
|
|
2213
|
+
this._controlEventBus = null;
|
|
1472
2214
|
this.props = props;
|
|
1473
2215
|
this.userPoolKmsKey = this.createUserPoolKmsKey();
|
|
1474
2216
|
this.preTokenGenerationLambda = this.createPreTokenGenerationLambda();
|
|
1475
2217
|
this.postAuthenticationLambda = this.createPostAuthenticationLambda();
|
|
1476
2218
|
this.postConfirmationLambda = this.createPostConfirmationLambda();
|
|
2219
|
+
this.userOnboardingWorkflow = this.createUserOnboardingWorkflow();
|
|
1477
2220
|
this.userPool = this.createUserPool();
|
|
1478
2221
|
this.grantPreTokenGenerationPermissions();
|
|
1479
2222
|
this.grantPostAuthenticationPermissions();
|
|
@@ -1590,23 +2333,33 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1590
2333
|
}
|
|
1591
2334
|
/**
|
|
1592
2335
|
* Creates the Post Confirmation Lambda (Cognito trigger). On sign-up
|
|
1593
|
-
* confirmation,
|
|
1594
|
-
*
|
|
1595
|
-
* carrying the Cognito `sub` and current tenant/workspace pointers
|
|
1596
|
-
* (ADR 2026-03-17-01 invariants).
|
|
2336
|
+
* confirmation, publishes a control-plane workflow event; provisioning lives
|
|
2337
|
+
* behind EventBridge.
|
|
1597
2338
|
*/
|
|
1598
2339
|
createPostConfirmationLambda() {
|
|
1599
2340
|
const construct = new PostConfirmationLambda(this, {
|
|
1600
|
-
|
|
2341
|
+
controlEventBusName: this.controlEventBus().eventBusName
|
|
1601
2342
|
});
|
|
1602
2343
|
return construct.lambda;
|
|
1603
2344
|
}
|
|
2345
|
+
createUserOnboardingWorkflow() {
|
|
2346
|
+
return new UserOnboardingWorkflow(this, {
|
|
2347
|
+
controlEventBus: this.controlEventBus(),
|
|
2348
|
+
dataStoreTable: this.dataStoreTable()
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
1604
2351
|
dataStoreTable() {
|
|
1605
2352
|
if (this._dataStoreTable === null) {
|
|
1606
2353
|
this._dataStoreTable = OpenHiDataService.dynamoDbDataStoreFromConstruct(this);
|
|
1607
2354
|
}
|
|
1608
2355
|
return this._dataStoreTable;
|
|
1609
2356
|
}
|
|
2357
|
+
controlEventBus() {
|
|
2358
|
+
if (this._controlEventBus === null) {
|
|
2359
|
+
this._controlEventBus = OpenHiGlobalService.controlEventBusFromConstruct(this);
|
|
2360
|
+
}
|
|
2361
|
+
return this._controlEventBus;
|
|
2362
|
+
}
|
|
1610
2363
|
/**
|
|
1611
2364
|
* Creates the Cognito User Pool and exports its ID to SSM.
|
|
1612
2365
|
* Look up via {@link OpenHiAuthService.userPoolFromConstruct}.
|
|
@@ -1651,8 +2404,8 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1651
2404
|
const dynamoActions = ["dynamodb:GetItem", "dynamodb:Query"];
|
|
1652
2405
|
dataStoreTable.grant(this.preTokenGenerationLambda, ...dynamoActions);
|
|
1653
2406
|
this.preTokenGenerationLambda.addToRolePolicy(
|
|
1654
|
-
new
|
|
1655
|
-
effect:
|
|
2407
|
+
new PolicyStatement6({
|
|
2408
|
+
effect: Effect6.ALLOW,
|
|
1656
2409
|
actions: [...dynamoActions],
|
|
1657
2410
|
resources: [`${dataStoreTable.tableArn}/index/*`]
|
|
1658
2411
|
})
|
|
@@ -1673,10 +2426,10 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1673
2426
|
*/
|
|
1674
2427
|
grantPostAuthenticationPermissions() {
|
|
1675
2428
|
this.postAuthenticationLambda.addToRolePolicy(
|
|
1676
|
-
new
|
|
2429
|
+
new PolicyStatement6({
|
|
1677
2430
|
actions: ["cognito-idp:AdminUserGlobalSignOut"],
|
|
1678
2431
|
resources: [
|
|
1679
|
-
|
|
2432
|
+
Stack6.of(this).formatArn({
|
|
1680
2433
|
service: "cognito-idp",
|
|
1681
2434
|
resource: "userpool",
|
|
1682
2435
|
resourceName: "*"
|
|
@@ -1686,26 +2439,11 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1686
2439
|
);
|
|
1687
2440
|
}
|
|
1688
2441
|
/**
|
|
1689
|
-
* Grants the Post Confirmation Lambda
|
|
1690
|
-
*
|
|
1691
|
-
* Memberships, RoleAssignment, and User records on sign-up confirmation.
|
|
2442
|
+
* Grants the Post Confirmation Lambda publish-only access to the
|
|
2443
|
+
* control-plane event bus. Workflow Lambdas own DynamoDB writes.
|
|
1692
2444
|
*/
|
|
1693
2445
|
grantPostConfirmationPermissions() {
|
|
1694
|
-
|
|
1695
|
-
const dynamoActions = [
|
|
1696
|
-
"dynamodb:PutItem",
|
|
1697
|
-
"dynamodb:UpdateItem",
|
|
1698
|
-
"dynamodb:BatchWriteItem",
|
|
1699
|
-
"dynamodb:DescribeTable"
|
|
1700
|
-
];
|
|
1701
|
-
dataStoreTable.grant(this.postConfirmationLambda, ...dynamoActions);
|
|
1702
|
-
this.postConfirmationLambda.addToRolePolicy(
|
|
1703
|
-
new PolicyStatement({
|
|
1704
|
-
effect: Effect.ALLOW,
|
|
1705
|
-
actions: [...dynamoActions],
|
|
1706
|
-
resources: [`${dataStoreTable.tableArn}/index/*`]
|
|
1707
|
-
})
|
|
1708
|
-
);
|
|
2446
|
+
this.controlEventBus().grantPutEventsTo(this.postConfirmationLambda);
|
|
1709
2447
|
}
|
|
1710
2448
|
/**
|
|
1711
2449
|
* Creates the User Pool Client and exports its ID to SSM (AUTH service type).
|
|
@@ -1735,7 +2473,7 @@ var _OpenHiAuthService = class _OpenHiAuthService extends OpenHiService {
|
|
|
1735
2473
|
* via env vars to drive `InitiateAuth`.
|
|
1736
2474
|
*/
|
|
1737
2475
|
createFixtureSeederClient() {
|
|
1738
|
-
if (this.ohEnv.ohStage.stageType ===
|
|
2476
|
+
if (this.ohEnv.ohStage.stageType === import_config5.OPEN_HI_STAGE.PROD) {
|
|
1739
2477
|
return void 0;
|
|
1740
2478
|
}
|
|
1741
2479
|
const client = new CognitoFixtureSeederClient(this, {
|
|
@@ -1772,7 +2510,7 @@ _OpenHiAuthService.SERVICE_TYPE = "auth";
|
|
|
1772
2510
|
var OpenHiAuthService = _OpenHiAuthService;
|
|
1773
2511
|
|
|
1774
2512
|
// src/services/open-hi-rest-api-service.ts
|
|
1775
|
-
var
|
|
2513
|
+
var import_config6 = __toESM(require_lib2());
|
|
1776
2514
|
import {
|
|
1777
2515
|
CorsHttpMethod,
|
|
1778
2516
|
DomainName,
|
|
@@ -1784,62 +2522,62 @@ import {
|
|
|
1784
2522
|
} from "aws-cdk-lib/aws-apigatewayv2";
|
|
1785
2523
|
import { HttpUserPoolAuthorizer } from "aws-cdk-lib/aws-apigatewayv2-authorizers";
|
|
1786
2524
|
import { HttpLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations";
|
|
1787
|
-
import { Effect as
|
|
2525
|
+
import { Effect as Effect7, PolicyStatement as PolicyStatement7 } from "aws-cdk-lib/aws-iam";
|
|
1788
2526
|
import {
|
|
1789
2527
|
ARecord,
|
|
1790
2528
|
HostedZone as HostedZone3,
|
|
1791
2529
|
RecordTarget
|
|
1792
2530
|
} from "aws-cdk-lib/aws-route53";
|
|
1793
2531
|
import { ApiGatewayv2DomainProperties } from "aws-cdk-lib/aws-route53-targets";
|
|
1794
|
-
import { Duration as
|
|
2532
|
+
import { Duration as Duration10 } from "aws-cdk-lib/core";
|
|
1795
2533
|
|
|
1796
2534
|
// src/data/lambda/cors-options-lambda.ts
|
|
1797
|
-
import
|
|
1798
|
-
import
|
|
1799
|
-
import { Runtime as
|
|
1800
|
-
import { NodejsFunction as
|
|
1801
|
-
import { Construct as
|
|
1802
|
-
var
|
|
1803
|
-
function
|
|
1804
|
-
const sameDir =
|
|
1805
|
-
if (
|
|
2535
|
+
import fs10 from "fs";
|
|
2536
|
+
import path10 from "path";
|
|
2537
|
+
import { Runtime as Runtime10 } from "aws-cdk-lib/aws-lambda";
|
|
2538
|
+
import { NodejsFunction as NodejsFunction10 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
2539
|
+
import { Construct as Construct17 } from "constructs";
|
|
2540
|
+
var HANDLER_NAME10 = "cors-options-lambda.handler.js";
|
|
2541
|
+
function resolveHandlerEntry10(dirname) {
|
|
2542
|
+
const sameDir = path10.join(dirname, HANDLER_NAME10);
|
|
2543
|
+
if (fs10.existsSync(sameDir)) {
|
|
1806
2544
|
return sameDir;
|
|
1807
2545
|
}
|
|
1808
|
-
const fromLib =
|
|
2546
|
+
const fromLib = path10.join(dirname, "..", "..", "..", "lib", HANDLER_NAME10);
|
|
1809
2547
|
return fromLib;
|
|
1810
2548
|
}
|
|
1811
|
-
var CorsOptionsLambda = class extends
|
|
2549
|
+
var CorsOptionsLambda = class extends Construct17 {
|
|
1812
2550
|
constructor(scope, id = "cors-options-lambda") {
|
|
1813
2551
|
super(scope, id);
|
|
1814
|
-
this.lambda = new
|
|
1815
|
-
entry:
|
|
1816
|
-
runtime:
|
|
2552
|
+
this.lambda = new NodejsFunction10(this, "handler", {
|
|
2553
|
+
entry: resolveHandlerEntry10(__dirname),
|
|
2554
|
+
runtime: Runtime10.NODEJS_LATEST,
|
|
1817
2555
|
memorySize: 128
|
|
1818
2556
|
});
|
|
1819
2557
|
}
|
|
1820
2558
|
};
|
|
1821
2559
|
|
|
1822
2560
|
// src/data/lambda/rest-api-lambda.ts
|
|
1823
|
-
import
|
|
1824
|
-
import
|
|
1825
|
-
import { Runtime as
|
|
1826
|
-
import { NodejsFunction as
|
|
1827
|
-
import { Construct as
|
|
1828
|
-
var
|
|
1829
|
-
function
|
|
1830
|
-
const sameDir =
|
|
1831
|
-
if (
|
|
2561
|
+
import fs11 from "fs";
|
|
2562
|
+
import path11 from "path";
|
|
2563
|
+
import { Runtime as Runtime11 } from "aws-cdk-lib/aws-lambda";
|
|
2564
|
+
import { NodejsFunction as NodejsFunction11 } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
2565
|
+
import { Construct as Construct18 } from "constructs";
|
|
2566
|
+
var HANDLER_NAME11 = "rest-api-lambda.handler.js";
|
|
2567
|
+
function resolveHandlerEntry11(dirname) {
|
|
2568
|
+
const sameDir = path11.join(dirname, HANDLER_NAME11);
|
|
2569
|
+
if (fs11.existsSync(sameDir)) {
|
|
1832
2570
|
return sameDir;
|
|
1833
2571
|
}
|
|
1834
|
-
const fromLib =
|
|
2572
|
+
const fromLib = path11.join(dirname, "..", "..", "..", "lib", HANDLER_NAME11);
|
|
1835
2573
|
return fromLib;
|
|
1836
2574
|
}
|
|
1837
|
-
var RestApiLambda = class extends
|
|
2575
|
+
var RestApiLambda = class extends Construct18 {
|
|
1838
2576
|
constructor(scope, props) {
|
|
1839
2577
|
super(scope, "rest-api-lambda");
|
|
1840
|
-
this.lambda = new
|
|
1841
|
-
entry:
|
|
1842
|
-
runtime:
|
|
2578
|
+
this.lambda = new NodejsFunction11(this, "handler", {
|
|
2579
|
+
entry: resolveHandlerEntry11(__dirname),
|
|
2580
|
+
runtime: Runtime11.NODEJS_LATEST,
|
|
1843
2581
|
memorySize: 1024,
|
|
1844
2582
|
environment: {
|
|
1845
2583
|
DYNAMO_TABLE_NAME: props.dynamoTableName,
|
|
@@ -1981,8 +2719,8 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
1981
2719
|
postgresSchema
|
|
1982
2720
|
});
|
|
1983
2721
|
lambda.addToRolePolicy(
|
|
1984
|
-
new
|
|
1985
|
-
effect:
|
|
2722
|
+
new PolicyStatement7({
|
|
2723
|
+
effect: Effect7.ALLOW,
|
|
1986
2724
|
actions: [
|
|
1987
2725
|
"rds-data:ExecuteStatement",
|
|
1988
2726
|
"rds-data:BatchExecuteStatement"
|
|
@@ -1991,8 +2729,8 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
1991
2729
|
})
|
|
1992
2730
|
);
|
|
1993
2731
|
lambda.addToRolePolicy(
|
|
1994
|
-
new
|
|
1995
|
-
effect:
|
|
2732
|
+
new PolicyStatement7({
|
|
2733
|
+
effect: Effect7.ALLOW,
|
|
1996
2734
|
actions: ["secretsmanager:GetSecretValue"],
|
|
1997
2735
|
resources: [postgresSecretArn]
|
|
1998
2736
|
})
|
|
@@ -2010,15 +2748,15 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
2010
2748
|
];
|
|
2011
2749
|
dataStoreTable.grant(lambda, ...dynamoActions);
|
|
2012
2750
|
lambda.addToRolePolicy(
|
|
2013
|
-
new
|
|
2014
|
-
effect:
|
|
2751
|
+
new PolicyStatement7({
|
|
2752
|
+
effect: Effect7.ALLOW,
|
|
2015
2753
|
actions: [...dynamoActions],
|
|
2016
2754
|
resources: [`${dataStoreTable.tableArn}/index/*`]
|
|
2017
2755
|
})
|
|
2018
2756
|
);
|
|
2019
2757
|
lambda.addToRolePolicy(
|
|
2020
|
-
new
|
|
2021
|
-
effect:
|
|
2758
|
+
new PolicyStatement7({
|
|
2759
|
+
effect: Effect7.ALLOW,
|
|
2022
2760
|
actions: [
|
|
2023
2761
|
"ssm:GetParameter",
|
|
2024
2762
|
"ssm:GetParameters",
|
|
@@ -2077,7 +2815,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
2077
2815
|
const userPool = OpenHiAuthService.userPoolFromConstruct(this);
|
|
2078
2816
|
const userPoolClient = OpenHiAuthService.userPoolClientFromConstruct(this);
|
|
2079
2817
|
const userPoolClients = [userPoolClient];
|
|
2080
|
-
if (this.ohEnv.ohStage.stageType !==
|
|
2818
|
+
if (this.ohEnv.ohStage.stageType !== import_config6.OPEN_HI_STAGE.PROD) {
|
|
2081
2819
|
userPoolClients.push(
|
|
2082
2820
|
OpenHiAuthService.fixtureSeederClientFromConstruct(this)
|
|
2083
2821
|
);
|
|
@@ -2104,7 +2842,7 @@ var _OpenHiRestApiService = class _OpenHiRestApiService extends OpenHiService {
|
|
|
2104
2842
|
"Authorization"
|
|
2105
2843
|
],
|
|
2106
2844
|
allowCredentials: cors.allowCredentials ?? true,
|
|
2107
|
-
maxAge: cors.maxAge ??
|
|
2845
|
+
maxAge: cors.maxAge ?? Duration10.days(1),
|
|
2108
2846
|
...cors.exposeHeaders !== void 0 && {
|
|
2109
2847
|
exposeHeaders: cors.exposeHeaders
|
|
2110
2848
|
}
|
|
@@ -2168,21 +2906,38 @@ var _OpenHiGraphqlService = class _OpenHiGraphqlService extends OpenHiService {
|
|
|
2168
2906
|
};
|
|
2169
2907
|
_OpenHiGraphqlService.SERVICE_TYPE = "graphql-api";
|
|
2170
2908
|
var OpenHiGraphqlService = _OpenHiGraphqlService;
|
|
2909
|
+
var export_PlatformDeploymentCompletedV1 = import_workflows2.PlatformDeploymentCompletedV1;
|
|
2171
2910
|
export {
|
|
2911
|
+
BRIDGED_STATUSES,
|
|
2912
|
+
CLOUDFORMATION_EVENT_SOURCE,
|
|
2913
|
+
CLOUDFORMATION_STACK_STATUS_CHANGE_DETAIL_TYPE,
|
|
2914
|
+
CONTROL_EVENT_BUS_NAME_ENV_VAR,
|
|
2172
2915
|
ChildHostedZone,
|
|
2173
2916
|
CognitoFixtureSeederClient,
|
|
2174
2917
|
CognitoUserPool,
|
|
2175
2918
|
CognitoUserPoolClient,
|
|
2176
2919
|
CognitoUserPoolDomain,
|
|
2177
2920
|
CognitoUserPoolKmsKey,
|
|
2921
|
+
ControlEventBus,
|
|
2178
2922
|
DATA_STORE_CHANGE_DETAIL_MAX_UTF8_BYTES,
|
|
2179
2923
|
DATA_STORE_CHANGE_DETAIL_TYPE,
|
|
2180
2924
|
DATA_STORE_CHANGE_EVENT_SOURCE,
|
|
2925
|
+
DEMO_PERIOD,
|
|
2926
|
+
DEMO_TENANT_SPECS,
|
|
2927
|
+
DEMO_URN_SYSTEM,
|
|
2928
|
+
DEV_USERS,
|
|
2181
2929
|
DataEventBus,
|
|
2182
2930
|
DataStoreHistoricalArchive,
|
|
2183
2931
|
DataStorePostgresReplica,
|
|
2184
2932
|
DiscoverableStringParameter,
|
|
2185
2933
|
DynamoDbDataStore,
|
|
2934
|
+
OPENHI_REPO_TAG_KEY_ENV_VAR,
|
|
2935
|
+
OPENHI_RESOURCE_URN_SYSTEM,
|
|
2936
|
+
OPENHI_TAG_KEY_PREFIX_ENV_VAR,
|
|
2937
|
+
OPENHI_TAG_SUFFIX_BRANCH_NAME,
|
|
2938
|
+
OPENHI_TAG_SUFFIX_REPO_NAME,
|
|
2939
|
+
OPENHI_TAG_SUFFIX_SERVICE_TYPE,
|
|
2940
|
+
OPENHI_TAG_SUFFIX_STAGE_TYPE,
|
|
2186
2941
|
OpenHiApp,
|
|
2187
2942
|
OpenHiAuthService,
|
|
2188
2943
|
OpenHiDataService,
|
|
@@ -2193,21 +2948,59 @@ export {
|
|
|
2193
2948
|
OpenHiService,
|
|
2194
2949
|
OpenHiStage,
|
|
2195
2950
|
OpsEventBus,
|
|
2951
|
+
PLACEHOLDER_TENANT_ID,
|
|
2952
|
+
PLACEHOLDER_WORKSPACE_ID,
|
|
2953
|
+
PLATFORM_DEPLOY_BRIDGE_ACTOR_SYSTEM,
|
|
2954
|
+
PLATFORM_SCOPE_TENANT_ID,
|
|
2196
2955
|
POSTGRES_REPLICA_CLUSTER_ARN_SSM_NAME,
|
|
2197
2956
|
POSTGRES_REPLICA_DATABASE_NAME_SSM_NAME,
|
|
2198
2957
|
POSTGRES_REPLICA_SECRET_ARN_SSM_NAME,
|
|
2958
|
+
PROVISION_DEFAULT_WORKSPACE_DETAIL_TYPE,
|
|
2959
|
+
PlatformDeployBridge,
|
|
2960
|
+
PlatformDeployBridgeLambda,
|
|
2961
|
+
export_PlatformDeploymentCompletedV1 as PlatformDeploymentCompletedV1,
|
|
2199
2962
|
PostAuthenticationLambda,
|
|
2200
2963
|
PostConfirmationLambda,
|
|
2201
2964
|
PreTokenGenerationLambda,
|
|
2965
|
+
ProvisionDefaultWorkspaceLambda,
|
|
2202
2966
|
REST_API_BASE_URL_SSM_NAME,
|
|
2203
2967
|
RootGraphqlApi,
|
|
2204
2968
|
RootHostedZone,
|
|
2205
2969
|
RootHttpApi,
|
|
2206
2970
|
RootWildcardCertificate,
|
|
2971
|
+
SEED_DEMO_DATA_CONSUMER_NAME,
|
|
2972
|
+
SEED_SYSTEM_DATA_ACTOR_SYSTEM,
|
|
2973
|
+
SEED_SYSTEM_DATA_CONSUMER_NAME,
|
|
2974
|
+
SEED_SYSTEM_DATA_CONTROL_BUS_ENV_VAR,
|
|
2207
2975
|
STATIC_HOSTING_SERVICE_TYPE,
|
|
2976
|
+
SeedDemoDataLambda,
|
|
2977
|
+
SeedDemoDataWorkflow,
|
|
2978
|
+
SeedSystemDataLambda,
|
|
2979
|
+
SeedSystemDataWorkflow,
|
|
2208
2980
|
StaticHosting,
|
|
2981
|
+
USER_ONBOARDING_EVENT_SOURCE,
|
|
2982
|
+
UserOnboardingWorkflow,
|
|
2983
|
+
WorkflowDedupConsumerNameInvalidError,
|
|
2984
|
+
WorkflowDedupTable,
|
|
2985
|
+
WorkflowDedupTableDuplicateError,
|
|
2209
2986
|
buildFhirCurrentResourceChangeDetail,
|
|
2987
|
+
buildProvisionDefaultWorkspaceRequestedDetail,
|
|
2988
|
+
demoBasePartitionKeys,
|
|
2989
|
+
demoDevUserPartitionKeys,
|
|
2990
|
+
demoMembershipId,
|
|
2991
|
+
demoMembershipPartitionKey,
|
|
2992
|
+
demoRoleAssignmentId,
|
|
2993
|
+
demoRoleAssignmentPartitionKey,
|
|
2994
|
+
demoRolesForUserInTenant,
|
|
2995
|
+
demoScenarioIdentifier,
|
|
2996
|
+
demoTenantPartitionKey,
|
|
2997
|
+
demoUserPartitionKey,
|
|
2998
|
+
demoWorkspacePartitionKey,
|
|
2210
2999
|
getDynamoDbDataStoreTableName,
|
|
2211
|
-
getPostgresReplicaSchemaName
|
|
3000
|
+
getPostgresReplicaSchemaName,
|
|
3001
|
+
getWorkflowDedupTableName,
|
|
3002
|
+
openHiTagKey,
|
|
3003
|
+
openhiResourceIdentifier,
|
|
3004
|
+
rolePartitionKey
|
|
2212
3005
|
};
|
|
2213
3006
|
//# sourceMappingURL=index.mjs.map
|