@flipboxlabs/aws-audit-cdk 1.1.0

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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/dist/audit-config.d.ts +59 -0
  4. package/dist/audit-config.d.ts.map +1 -0
  5. package/dist/audit-config.js +27 -0
  6. package/dist/cloudwatch/construct.d.ts +20 -0
  7. package/dist/cloudwatch/construct.d.ts.map +1 -0
  8. package/dist/cloudwatch/construct.js +46 -0
  9. package/dist/cloudwatch/subscription.handler.d.ts +6 -0
  10. package/dist/cloudwatch/subscription.handler.d.ts.map +1 -0
  11. package/dist/cloudwatch/subscription.handler.js +34 -0
  12. package/dist/constants.d.ts +9 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/constants.js +1 -0
  15. package/dist/dynamodb/audit.d.ts +10 -0
  16. package/dist/dynamodb/audit.d.ts.map +1 -0
  17. package/dist/dynamodb/audit.js +114 -0
  18. package/dist/dynamodb/construct.d.ts +10 -0
  19. package/dist/dynamodb/construct.d.ts.map +1 -0
  20. package/dist/dynamodb/construct.js +10 -0
  21. package/dist/eventbridge/construct.d.ts +10 -0
  22. package/dist/eventbridge/construct.d.ts.map +1 -0
  23. package/dist/eventbridge/construct.js +13 -0
  24. package/dist/index.d.ts +53 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +52 -0
  27. package/dist/lib/index.d.ts +53 -0
  28. package/dist/lib/index.d.ts.map +1 -0
  29. package/dist/lib/index.js +52 -0
  30. package/dist/lib/nodejs.function.d.ts +6 -0
  31. package/dist/lib/nodejs.function.d.ts.map +1 -0
  32. package/dist/lib/nodejs.function.js +48 -0
  33. package/dist/rest-api/construct.d.ts +18 -0
  34. package/dist/rest-api/construct.d.ts.map +1 -0
  35. package/dist/rest-api/construct.js +34 -0
  36. package/dist/rest-api/index.d.ts +3 -0
  37. package/dist/rest-api/index.d.ts.map +1 -0
  38. package/dist/rest-api/index.js +2 -0
  39. package/dist/rest-api/resources/app/constants.d.ts +5 -0
  40. package/dist/rest-api/resources/app/constants.d.ts.map +1 -0
  41. package/dist/rest-api/resources/app/constants.js +4 -0
  42. package/dist/rest-api/resources/app/construct.d.ts +18 -0
  43. package/dist/rest-api/resources/app/construct.d.ts.map +1 -0
  44. package/dist/rest-api/resources/app/construct.js +18 -0
  45. package/dist/rest-api/resources/app/resources/objects/constants.d.ts +7 -0
  46. package/dist/rest-api/resources/app/resources/objects/constants.d.ts.map +1 -0
  47. package/dist/rest-api/resources/app/resources/objects/constants.js +6 -0
  48. package/dist/rest-api/resources/app/resources/objects/construct.d.ts +18 -0
  49. package/dist/rest-api/resources/app/resources/objects/construct.d.ts.map +1 -0
  50. package/dist/rest-api/resources/app/resources/objects/construct.js +48 -0
  51. package/dist/rest-api/resources/app/resources/objects/handler.d.ts +3 -0
  52. package/dist/rest-api/resources/app/resources/objects/handler.d.ts.map +1 -0
  53. package/dist/rest-api/resources/app/resources/objects/handler.js +40 -0
  54. package/dist/rest-api/resources/app/resources/objects/resources/rerun/constants.d.ts +4 -0
  55. package/dist/rest-api/resources/app/resources/objects/resources/rerun/constants.d.ts.map +1 -0
  56. package/dist/rest-api/resources/app/resources/objects/resources/rerun/constants.js +3 -0
  57. package/dist/rest-api/resources/app/resources/objects/resources/rerun/construct.d.ts +18 -0
  58. package/dist/rest-api/resources/app/resources/objects/resources/rerun/construct.d.ts.map +1 -0
  59. package/dist/rest-api/resources/app/resources/objects/resources/rerun/construct.js +38 -0
  60. package/dist/rest-api/resources/app/resources/objects/resources/rerun/handler.d.ts +3 -0
  61. package/dist/rest-api/resources/app/resources/objects/resources/rerun/handler.d.ts.map +1 -0
  62. package/dist/rest-api/resources/app/resources/objects/resources/rerun/handler.js +44 -0
  63. package/dist/rest-api/resources/app/resources/objects/resources/rerun/schema.d.ts +7 -0
  64. package/dist/rest-api/resources/app/resources/objects/resources/rerun/schema.d.ts.map +1 -0
  65. package/dist/rest-api/resources/app/resources/objects/resources/rerun/schema.js +10 -0
  66. package/dist/rest-api/resources/app/resources/objects/schema.d.ts +64 -0
  67. package/dist/rest-api/resources/app/resources/objects/schema.d.ts.map +1 -0
  68. package/dist/rest-api/resources/app/resources/objects/schema.js +16 -0
  69. package/dist/rest-api/resources/construct.d.ts +18 -0
  70. package/dist/rest-api/resources/construct.d.ts.map +1 -0
  71. package/dist/rest-api/resources/construct.js +10 -0
  72. package/dist/rest-api/resources/trace/constants.d.ts +4 -0
  73. package/dist/rest-api/resources/trace/constants.d.ts.map +1 -0
  74. package/dist/rest-api/resources/trace/constants.js +3 -0
  75. package/dist/rest-api/resources/trace/construct.d.ts +16 -0
  76. package/dist/rest-api/resources/trace/construct.d.ts.map +1 -0
  77. package/dist/rest-api/resources/trace/construct.js +38 -0
  78. package/dist/rest-api/resources/trace/handler.d.ts +3 -0
  79. package/dist/rest-api/resources/trace/handler.d.ts.map +1 -0
  80. package/dist/rest-api/resources/trace/handler.js +36 -0
  81. package/dist/rest-api/resources/trace/schema.d.ts +65 -0
  82. package/dist/rest-api/resources/trace/schema.d.ts.map +1 -0
  83. package/dist/rest-api/resources/trace/schema.js +14 -0
  84. package/dist/rest-api/utils.d.ts +7 -0
  85. package/dist/rest-api/utils.d.ts.map +1 -0
  86. package/dist/rest-api/utils.js +7 -0
  87. package/dist/test-config.d.ts +56 -0
  88. package/dist/test-config.d.ts.map +1 -0
  89. package/dist/test-config.js +24 -0
  90. package/package.json +102 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * AWS Audit CDK Library
3
+ *
4
+ * Provides constructs for deploying audit infrastructure. Import and compose
5
+ * the constructs in your own stack as needed.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import * as cdk from "aws-cdk-lib";
10
+ * import type { Construct } from "constructs";
11
+ * import type { CDKConfig } from "@flipboxlabs/aws-audit-cdk";
12
+ *
13
+ * // Import constructs from the bootstrap directory
14
+ * import CloudWatch from "@flipboxlabs/aws-audit-cdk/bootstrap/cloudwatch/construct";
15
+ * import DynamoDB from "@flipboxlabs/aws-audit-cdk/bootstrap/dynamodb/construct";
16
+ * import EventBridge from "@flipboxlabs/aws-audit-cdk/bootstrap/eventbridge/construct";
17
+ * import RestAPI from "@flipboxlabs/aws-audit-cdk/bootstrap/rest-api/construct";
18
+ *
19
+ * interface Props {
20
+ * config: CDKConfig;
21
+ * }
22
+ *
23
+ * export class AuditStack extends cdk.NestedStack {
24
+ * constructor(scope: Construct, id: string, props: Props) {
25
+ * super(scope, id, { description: "Audit" });
26
+ *
27
+ * // DynamoDB (storage)
28
+ * const { table } = new DynamoDB(this, "DynamoDB", { config: props.config });
29
+ *
30
+ * // EventBridge (events)
31
+ * const { eventBus } = new EventBridge(this, "EventBridge", {
32
+ * config: props.config,
33
+ * });
34
+ *
35
+ * // CloudWatch (logging subscription)
36
+ * new CloudWatch(this, "CloudWatch", {
37
+ * config: props.config,
38
+ * table,
39
+ * eventBus,
40
+ * });
41
+ *
42
+ * // REST API (optional)
43
+ * new RestAPI(this, "RestAPI", {
44
+ * config: props.config,
45
+ * table,
46
+ * eventBus,
47
+ * });
48
+ * }
49
+ * }
50
+ * ```
51
+ */
52
+ export * from "./nodejs.function.js";
@@ -0,0 +1,6 @@
1
+ import type { CDKConfig } from "@flipboxlabs/aws-audit-cdk";
2
+ import * as cdk from "aws-cdk-lib";
3
+ import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
4
+ import type { Construct } from "constructs";
5
+ export declare const ESMNodeFunctionFactory: (config: CDKConfig) => (scope: Construct, id: string, props: nodejs.NodejsFunctionProps) => cdk.aws_lambda_nodejs.NodejsFunction;
6
+ //# sourceMappingURL=nodejs.function.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodejs.function.d.ts","sourceRoot":"","sources":["../../src/lib/nodejs.function.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AAGnC,OAAO,KAAK,MAAM,MAAM,+BAA+B,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,eAAO,MAAM,sBAAsB,GACjC,QAAQ,SAAS,MACjB,OAAO,SAAS,EAAE,IAAI,MAAM,EAAE,OAAO,MAAM,CAAC,mBAAmB,yCAyD/D,CAAC"}
@@ -0,0 +1,48 @@
1
+ import * as cdk from "aws-cdk-lib";
2
+ import * as iam from "aws-cdk-lib/aws-iam";
3
+ import * as lambda from "aws-cdk-lib/aws-lambda";
4
+ import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
5
+ import * as logs from "aws-cdk-lib/aws-logs";
6
+ export const ESMNodeFunctionFactory = (config) => (scope, id, props) => {
7
+ const nodejsFunction = new nodejs.NodejsFunction(scope, id, {
8
+ tracing: lambda.Tracing.ACTIVE,
9
+ timeout: props.timeout || cdk.Duration.seconds(10),
10
+ logRetention: props.logRetention || logs.RetentionDays.ONE_WEEK,
11
+ memorySize: props.memorySize || 512,
12
+ architecture: props.architecture || lambda.Architecture.ARM_64,
13
+ runtime: lambda.Runtime.NODEJS_20_X,
14
+ bundling: {
15
+ minify: true,
16
+ metafile: false,
17
+ externalModules: ["aws-sdk", "@aws-sdk/*"],
18
+ format: nodejs.OutputFormat.ESM,
19
+ platform: "node",
20
+ target: "esnext",
21
+ mainFields: ["module", "main"],
22
+ esbuildArgs: {
23
+ "--conditions": "module",
24
+ "--tree-shaking": "true",
25
+ },
26
+ banner: "import { createRequire } from 'module';const require = createRequire(import.meta.url);",
27
+ },
28
+ role: props.role ||
29
+ new iam.Role(scope, `${id}-FunctionRole`, {
30
+ assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
31
+ managedPolicies: [
32
+ iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"),
33
+ ],
34
+ }),
35
+ ...props,
36
+ environment: {
37
+ ...props.environment,
38
+ ENVIRONMENT: config.env,
39
+ AWS_ACCOUNT: config.aws.account,
40
+ POWERTOOLS_LOG_LEVEL: "WARN",
41
+ },
42
+ });
43
+ if (config.service) {
44
+ nodejsFunction.addEnvironment("SERVICE", config.service);
45
+ }
46
+ nodejsFunction.addLayers(lambda.LayerVersion.fromLayerVersionArn(scope, `${id}InsightLayer`, `arn:aws:lambda:${cdk.Stack.of(scope).region}:580247275435:layer:LambdaInsightsExtension-Arm64:2`));
47
+ return nodejsFunction;
48
+ };
@@ -0,0 +1,18 @@
1
+ import type { CDKConfig } from "@flipboxlabs/aws-audit-cdk";
2
+ import * as apigateway from "aws-cdk-lib/aws-apigateway";
3
+ import type * as dynamodb from "aws-cdk-lib/aws-dynamodb";
4
+ import type * as events from "aws-cdk-lib/aws-events";
5
+ import { Construct } from "constructs";
6
+ type Props = {
7
+ config: CDKConfig;
8
+ table: dynamodb.ITable;
9
+ eventBus: events.IEventBus;
10
+ /** Override REST API props. */
11
+ restApi?: Partial<apigateway.RestApiProps>;
12
+ };
13
+ export declare class RestApiConstruct extends Construct {
14
+ readonly restApi: apigateway.RestApi;
15
+ constructor(scope: Construct, id: string, props: Props);
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=construct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct.d.ts","sourceRoot":"","sources":["../../src/rest-api/construct.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,KAAK,KAAK,GAAG;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC;IAC3B,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;CAC3C,CAAC;AAIF,qBAAa,gBAAiB,SAAQ,SAAS;IAC9C,SAAgB,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC;gBAEhC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CA6BtD"}
@@ -0,0 +1,34 @@
1
+ import * as apigateway from "aws-cdk-lib/aws-apigateway";
2
+ import { Construct } from "constructs";
3
+ import { RestApiResourcesConstruct as Resources } from "./resources/construct.js";
4
+ const DEFAULT_STAGE_NAME_V1 = "v1";
5
+ export class RestApiConstruct extends Construct {
6
+ restApi;
7
+ constructor(scope, id, props) {
8
+ super(scope, id);
9
+ this.restApi = new apigateway.RestApi(this, "RESTApi", {
10
+ restApiName: [
11
+ props.config.env.toUpperCase(),
12
+ props.config.service,
13
+ "Audit",
14
+ ].join("-"),
15
+ disableExecuteApiEndpoint: false,
16
+ retainDeployments: true,
17
+ ...props.restApi,
18
+ deployOptions: {
19
+ stageName: DEFAULT_STAGE_NAME_V1,
20
+ loggingLevel: apigateway.MethodLoggingLevel.INFO,
21
+ metricsEnabled: true,
22
+ description: "Version 1",
23
+ dataTraceEnabled: true,
24
+ ...props.restApi?.deployOptions,
25
+ },
26
+ });
27
+ new Resources(this, "Resources", {
28
+ ...props,
29
+ restApi: {
30
+ resource: this.restApi.root,
31
+ },
32
+ });
33
+ }
34
+ }
@@ -0,0 +1,3 @@
1
+ export { RestApiConstruct } from "./construct.js";
2
+ export { RestApiResourcesConstruct } from "./resources/construct.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rest-api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { RestApiConstruct } from "./construct.js";
2
+ export { RestApiResourcesConstruct } from "./resources/construct.js";
@@ -0,0 +1,5 @@
1
+ export declare const API_RESOURCE: {
2
+ RESOURCE: string;
3
+ RESOURCE_WILDCARD: string;
4
+ };
5
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../src/rest-api/resources/app/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;CAGxB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export const API_RESOURCE = {
2
+ RESOURCE: "apps",
3
+ RESOURCE_WILDCARD: "app",
4
+ };
@@ -0,0 +1,18 @@
1
+ import type { CDKConfig } from "@flipboxlabs/aws-audit-cdk";
2
+ import type * as apigateway from "aws-cdk-lib/aws-apigateway";
3
+ import type * as dynamodb from "aws-cdk-lib/aws-dynamodb";
4
+ import type * as events from "aws-cdk-lib/aws-events";
5
+ import { Construct } from "constructs";
6
+ type Props = {
7
+ config: CDKConfig;
8
+ table: dynamodb.ITable;
9
+ eventBus: events.IEventBus;
10
+ restApi: {
11
+ resource: apigateway.IResource;
12
+ };
13
+ };
14
+ export default class extends Construct {
15
+ constructor(scope: Construct, id: string, props: Props);
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=construct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct.d.ts","sourceRoot":"","sources":["../../../../src/rest-api/resources/app/construct.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,KAAK,UAAU,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,KAAK,KAAK,GAAG;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC;IAC3B,OAAO,EAAE;QACR,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC;KAC/B,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,OAAO,MAAO,SAAQ,SAAS;gBACzB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CActD"}
@@ -0,0 +1,18 @@
1
+ import { Construct } from "constructs";
2
+ import { API_RESOURCE } from "./constants.js";
3
+ import Objects from "./resources/objects/construct.js";
4
+ export default class extends Construct {
5
+ constructor(scope, id, props) {
6
+ super(scope, id);
7
+ new Objects(this, "Objects", {
8
+ config: props.config,
9
+ table: props.table,
10
+ eventBus: props.eventBus,
11
+ restApi: {
12
+ resource: props.restApi.resource
13
+ .addResource(API_RESOURCE.RESOURCE)
14
+ .addResource(`{${API_RESOURCE.RESOURCE_WILDCARD}}`),
15
+ },
16
+ });
17
+ }
18
+ }
@@ -0,0 +1,7 @@
1
+ export declare const API_RESOURCE: {
2
+ RESOURCE: string;
3
+ RESOURCE_WILDCARD: string;
4
+ RESOURCE_WILDCARD_ITEM: string;
5
+ RESOURCE_WILDCARD_ITEM_AUDIT: string;
6
+ };
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../src/rest-api/resources/app/resources/objects/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;;;;CAKxB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const API_RESOURCE = {
2
+ RESOURCE: "objects",
3
+ RESOURCE_WILDCARD: "object",
4
+ RESOURCE_WILDCARD_ITEM: "item",
5
+ RESOURCE_WILDCARD_ITEM_AUDIT: "audit",
6
+ };
@@ -0,0 +1,18 @@
1
+ import type { CDKConfig } from "@flipboxlabs/aws-audit-cdk";
2
+ import * as apigateway from "aws-cdk-lib/aws-apigateway";
3
+ import type * as dynamodb from "aws-cdk-lib/aws-dynamodb";
4
+ import type * as events from "aws-cdk-lib/aws-events";
5
+ import { Construct } from "constructs";
6
+ type Props = {
7
+ config: CDKConfig;
8
+ table: dynamodb.ITable;
9
+ eventBus: events.IEventBus;
10
+ restApi: {
11
+ resource: apigateway.IResource;
12
+ };
13
+ };
14
+ export default class extends Construct {
15
+ constructor(scope: Construct, id: string, props: Props);
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=construct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct.d.ts","sourceRoot":"","sources":["../../../../../../src/rest-api/resources/app/resources/objects/construct.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAKvC,KAAK,KAAK,GAAG;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC;IAC3B,OAAO,EAAE;QACR,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC;KAC/B,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,OAAO,MAAO,SAAQ,SAAS;gBACzB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAuDtD"}
@@ -0,0 +1,48 @@
1
+ import * as url from "node:url";
2
+ import * as apigateway from "aws-cdk-lib/aws-apigateway";
3
+ import { Construct } from "constructs";
4
+ import { ESMNodeFunctionFactory } from "../../../../../lib/index.js";
5
+ import { API_RESOURCE } from "./constants.js";
6
+ import ReRun from "./resources/rerun/construct.js";
7
+ export default class extends Construct {
8
+ constructor(scope, id, props) {
9
+ super(scope, id);
10
+ const ref = [
11
+ props.config.env.toUpperCase(),
12
+ "REST-API",
13
+ props.config.service,
14
+ "Resources",
15
+ ].join("-");
16
+ // Lambda
17
+ const lambda = ESMNodeFunctionFactory(props.config)(this, "NodeFunction", {
18
+ functionName: ref,
19
+ entry: url.fileURLToPath(new URL("handler.ts", import.meta.url).toString()),
20
+ currentVersionOptions: {
21
+ retryAttempts: 1,
22
+ },
23
+ });
24
+ // Logger / Metrics / Tracing
25
+ lambda.addEnvironment("POWERTOOLS_SERVICE_NAME", "Resource");
26
+ // Audit
27
+ props.table.grantReadWriteData(lambda);
28
+ // Integration
29
+ const integration = new apigateway.LambdaIntegration(lambda);
30
+ const RESOURCE = props.restApi.resource
31
+ .addResource(API_RESOURCE.RESOURCE)
32
+ .addResource(`{${API_RESOURCE.RESOURCE_WILDCARD}}`);
33
+ const ITEM_RESOURCE = RESOURCE.addResource(`{${API_RESOURCE.RESOURCE_WILDCARD_ITEM}}`);
34
+ // /apps/{app}/objects/{object}/{item}
35
+ ITEM_RESOURCE.addMethod("GET", integration, {
36
+ apiKeyRequired: true,
37
+ operationName: "List audit items for resource",
38
+ });
39
+ new ReRun(this, "ReRun", {
40
+ config: props.config,
41
+ table: props.table,
42
+ eventBus: props.eventBus,
43
+ restApi: {
44
+ resource: ITEM_RESOURCE.addResource(`{${API_RESOURCE.RESOURCE_WILDCARD_ITEM_AUDIT}}`),
45
+ },
46
+ });
47
+ }
48
+ }
@@ -0,0 +1,3 @@
1
+ import type { Context } from "aws-lambda";
2
+ export declare const handler: (event: unknown, context: Context) => Promise<unknown>;
3
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../src/rest-api/resources/app/resources/objects/handler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA4D1C,eAAO,MAAM,OAAO,GACnB,OAAO,OAAO,EACd,SAAS,OAAO,KACd,OAAO,CAAC,OAAO,CAAgC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { Router } from "@aws-lambda-powertools/event-handler/http";
2
+ import { Logger } from "@aws-lambda-powertools/logger";
3
+ import { AuditService } from "@flipboxlabs/aws-audit-sdk";
4
+ import { auditConfig, } from "../../../../../audit-config.js";
5
+ import { API_RESOURCE as BASE_API_RESOURCE } from "../../constants.js";
6
+ import { API_RESOURCE } from "./constants.js";
7
+ import { PathSchema, QuerySchema, ResponseSchema } from "./schema.js";
8
+ const logger = new Logger({
9
+ logRecordOrder: ["level", "message"],
10
+ });
11
+ const app = new Router();
12
+ const audits = new AuditService(logger, auditConfig);
13
+ app.get(`/${BASE_API_RESOURCE.RESOURCE}/:${BASE_API_RESOURCE.RESOURCE_WILDCARD}/${API_RESOURCE.RESOURCE}/:${API_RESOURCE.RESOURCE_WILDCARD}/:${API_RESOURCE.RESOURCE_WILDCARD_ITEM}`, async (reqCtx) => {
14
+ const { [BASE_API_RESOURCE.RESOURCE_WILDCARD]: appId, [API_RESOURCE.RESOURCE_WILDCARD]: objectType, [API_RESOURCE.RESOURCE_WILDCARD_ITEM]: itemId, } = reqCtx.valid.req.path;
15
+ const query = reqCtx.valid.req.query;
16
+ const pagination = query["pagination[pageSize]"] || query["pagination[nextToken]"]
17
+ ? {
18
+ pageSize: query["pagination[pageSize]"],
19
+ nextToken: query["pagination[nextToken]"],
20
+ }
21
+ : undefined;
22
+ return audits.listItems({
23
+ resource: {
24
+ type: objectType,
25
+ id: itemId,
26
+ },
27
+ app: appId,
28
+ }, pagination);
29
+ }, {
30
+ validation: {
31
+ req: {
32
+ path: PathSchema,
33
+ query: QuerySchema,
34
+ },
35
+ res: {
36
+ body: ResponseSchema,
37
+ },
38
+ },
39
+ });
40
+ export const handler = async (event, context) => app.resolve(event, context);
@@ -0,0 +1,4 @@
1
+ export declare const API_RESOURCE: {
2
+ RESOURCE: string;
3
+ };
4
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../../../../../../src/rest-api/resources/app/resources/objects/resources/rerun/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;CAExB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const API_RESOURCE = {
2
+ RESOURCE: "rerun",
3
+ };
@@ -0,0 +1,18 @@
1
+ import type { CDKConfig } from "@flipboxlabs/aws-audit-cdk";
2
+ import * as apigateway from "aws-cdk-lib/aws-apigateway";
3
+ import type * as dynamodb from "aws-cdk-lib/aws-dynamodb";
4
+ import type * as events from "aws-cdk-lib/aws-events";
5
+ import { Construct } from "constructs";
6
+ type Props = {
7
+ config: CDKConfig;
8
+ table: dynamodb.ITable;
9
+ eventBus: events.IEventBus;
10
+ restApi: {
11
+ resource: apigateway.IResource;
12
+ };
13
+ };
14
+ export default class extends Construct {
15
+ constructor(scope: Construct, id: string, props: Props);
16
+ }
17
+ export {};
18
+ //# sourceMappingURL=construct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"construct.d.ts","sourceRoot":"","sources":["../../../../../../../../src/rest-api/resources/app/resources/objects/resources/rerun/construct.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,KAAK,QAAQ,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,KAAK,MAAM,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,KAAK,KAAK,GAAG;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,SAAS,CAAC;IAC3B,OAAO,EAAE;QACR,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC;KAC/B,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,OAAO,MAAO,SAAQ,SAAS;gBACzB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAyCtD"}
@@ -0,0 +1,38 @@
1
+ import * as url from "node:url";
2
+ import * as apigateway from "aws-cdk-lib/aws-apigateway";
3
+ import { Construct } from "constructs";
4
+ import { ESMNodeFunctionFactory } from "../../../../../../../lib/index.js";
5
+ import { API_RESOURCE } from "./constants.js";
6
+ export default class extends Construct {
7
+ constructor(scope, id, props) {
8
+ super(scope, id);
9
+ const ref = [
10
+ props.config.env.toUpperCase(),
11
+ "REST-API",
12
+ props.config.service,
13
+ "Resource-Rerun",
14
+ ].join("-");
15
+ // Lambda
16
+ const lambda = ESMNodeFunctionFactory(props.config)(this, "NodeFunction", {
17
+ functionName: ref,
18
+ entry: url.fileURLToPath(new URL("handler.ts", import.meta.url).toString()),
19
+ currentVersionOptions: {
20
+ retryAttempts: 1,
21
+ },
22
+ });
23
+ // Logger / Metrics / Tracing
24
+ lambda.addEnvironment("POWERTOOLS_SERVICE_NAME", "ResourceRerun");
25
+ // Audit
26
+ props.table.grantReadWriteData(lambda);
27
+ // Put events
28
+ props.eventBus.grantPutEventsTo(lambda);
29
+ // Integration
30
+ const integration = new apigateway.LambdaIntegration(lambda);
31
+ const RESOURCE = props.restApi.resource.addResource(API_RESOURCE.RESOURCE);
32
+ // /apps/{app}/objects/{object}/{item}/{audit}/rerun
33
+ RESOURCE.addMethod("POST", integration, {
34
+ apiKeyRequired: true,
35
+ operationName: "Rerun the event",
36
+ });
37
+ }
38
+ }
@@ -0,0 +1,3 @@
1
+ import type { Context } from "aws-lambda";
2
+ export declare const handler: (event: unknown, context: Context) => Promise<unknown>;
3
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../../../src/rest-api/resources/app/resources/objects/resources/rerun/handler.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAgE1C,eAAO,MAAM,OAAO,GACnB,OAAO,OAAO,EACd,SAAS,OAAO,KACd,OAAO,CAAC,OAAO,CAAgC,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { BadRequestError, Router, } from "@aws-lambda-powertools/event-handler/http";
2
+ import { Logger } from "@aws-lambda-powertools/logger";
3
+ import { EventBridgeClient } from "@aws-sdk/client-eventbridge";
4
+ import { AuditService, BatchHandler, EventBridge, } from "@flipboxlabs/aws-audit-sdk";
5
+ import { auditConfig, } from "../../../../../../../audit-config.js";
6
+ import { API_RESOURCE as BASE_API_RESOURCE } from "../../../../constants.js";
7
+ import { API_RESOURCE as ITEM_API_RESOURCE } from "../../constants.js";
8
+ import { API_RESOURCE } from "./constants.js";
9
+ import { PathSchema } from "./schema.js";
10
+ const logger = new Logger({
11
+ logRecordOrder: ["level", "message"],
12
+ });
13
+ const app = new Router();
14
+ const audits = new AuditService(logger, auditConfig);
15
+ const eventBus = new BatchHandler(logger, new EventBridgeClient({ logger: logger }));
16
+ app.post(`/${BASE_API_RESOURCE.RESOURCE}/:${BASE_API_RESOURCE.RESOURCE_WILDCARD}/${ITEM_API_RESOURCE.RESOURCE}/:${ITEM_API_RESOURCE.RESOURCE_WILDCARD}/:${ITEM_API_RESOURCE.RESOURCE_WILDCARD_ITEM}/:${ITEM_API_RESOURCE.RESOURCE_WILDCARD_ITEM_AUDIT}/${API_RESOURCE.RESOURCE}`, async (reqCtx) => {
17
+ const { [BASE_API_RESOURCE.RESOURCE_WILDCARD]: appId, [ITEM_API_RESOURCE.RESOURCE_WILDCARD]: resourceType, [ITEM_API_RESOURCE.RESOURCE_WILDCARD_ITEM_AUDIT]: auditId, } = reqCtx.valid.req.path;
18
+ const item = await audits.getItem({
19
+ app: appId,
20
+ resourceType: resourceType,
21
+ id: auditId,
22
+ });
23
+ if (!item.rerunable || !item.event) {
24
+ throw new BadRequestError("Item is not rerunable");
25
+ }
26
+ await eventBus.putEvents([
27
+ {
28
+ Source: item.event.source,
29
+ EventBusName: EventBridge.Bus.Name(),
30
+ Detail: JSON.stringify(item.event.detail),
31
+ DetailType: item.event["detail-type"],
32
+ },
33
+ ]);
34
+ return new Response(undefined, {
35
+ status: 204,
36
+ });
37
+ }, {
38
+ validation: {
39
+ req: {
40
+ path: PathSchema,
41
+ },
42
+ },
43
+ });
44
+ export const handler = async (event, context) => app.resolve(event, context);
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ export declare const PathSchema: z.ZodObject<{
3
+ [x: string]: z.ZodEnum<{
4
+ [x: string]: string;
5
+ }> | z.ZodString;
6
+ }, z.core.$strip>;
7
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../../../../../src/rest-api/resources/app/resources/objects/resources/rerun/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,UAAU;;;;iBAKrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ import { auditConfig } from "../../../../../../../audit-config.js";
3
+ import { API_RESOURCE as BASE_API_RESOURCE } from "../../../../constants.js";
4
+ import { API_RESOURCE as ITEM_API_RESOURCE } from "../../constants.js";
5
+ export const PathSchema = z.object({
6
+ [BASE_API_RESOURCE.RESOURCE_WILDCARD]: auditConfig.schemas.app,
7
+ [ITEM_API_RESOURCE.RESOURCE_WILDCARD]: auditConfig.schemas.resourceType,
8
+ [ITEM_API_RESOURCE.RESOURCE_WILDCARD_ITEM]: z.string(),
9
+ [ITEM_API_RESOURCE.RESOURCE_WILDCARD_ITEM_AUDIT]: z.string(),
10
+ });
@@ -0,0 +1,64 @@
1
+ import { z } from "zod";
2
+ export declare const PathSchema: z.ZodObject<{
3
+ [x: string]: z.ZodEnum<{
4
+ [x: string]: string;
5
+ }> | z.ZodString;
6
+ }, z.core.$strip>;
7
+ export declare const QuerySchema: z.ZodObject<{
8
+ "pagination[pageSize]": z.ZodOptional<z.ZodCoercedNumber<unknown>>;
9
+ "pagination[nextToken]": z.ZodOptional<z.ZodString>;
10
+ }, z.core.$strip>;
11
+ export declare const ResponseSchema: z.ZodObject<{
12
+ items: z.ZodArray<z.ZodObject<{
13
+ id: z.ZodString;
14
+ tenantId: z.ZodOptional<z.ZodString>;
15
+ status: z.ZodEnum<{
16
+ success: "success";
17
+ warn: "warn";
18
+ fail: "fail";
19
+ skip: "skip";
20
+ }>;
21
+ tier: z.ZodDefault<z.ZodNumber>;
22
+ target: z.ZodObject<{
23
+ app: z.ZodString;
24
+ id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
25
+ type: z.ZodString;
26
+ }, z.core.$strip>;
27
+ source: z.ZodOptional<z.ZodObject<{
28
+ app: z.ZodString;
29
+ id: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>;
30
+ type: z.ZodString;
31
+ }, z.core.$strip>>;
32
+ context: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<string | number | boolean | {
33
+ [key: string]: string | number | boolean | /*elided*/ any;
34
+ }, unknown, z.core.$ZodTypeInternals<string | number | boolean | {
35
+ [key: string]: string | number | boolean | /*elided*/ any;
36
+ }, unknown>>>>;
37
+ operation: z.ZodString;
38
+ message: z.ZodOptional<z.ZodString>;
39
+ rerunable: z.ZodOptional<z.ZodBoolean>;
40
+ trace: z.ZodOptional<z.ZodString>;
41
+ event: z.ZodOptional<z.ZodObject<{
42
+ source: z.ZodOptional<z.ZodString>;
43
+ "detail-type": z.ZodOptional<z.ZodString>;
44
+ detail: z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodAny>]>>, z.ZodTransform<string | undefined, string | Record<string, any> | undefined>>;
45
+ }, z.core.$strip>>;
46
+ error: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<any, string>>, z.ZodPipe<z.ZodCustom<Error, Error>, z.ZodTransform<any, Error>>, z.ZodRecord<z.ZodAny, z.ZodAny>]>>;
47
+ attempts: z.ZodOptional<z.ZodArray<z.ZodObject<{
48
+ number: z.ZodNumber;
49
+ status: z.ZodEnum<{
50
+ success: "success";
51
+ warn: "warn";
52
+ fail: "fail";
53
+ skip: "skip";
54
+ }>;
55
+ error: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodString, z.ZodTransform<any, string>>, z.ZodPipe<z.ZodCustom<Error, Error>, z.ZodTransform<any, Error>>, z.ZodRecord<z.ZodAny, z.ZodAny>]>>;
56
+ at: z.ZodDefault<z.ZodPipe<z.ZodUnion<readonly [z.ZodISODateTime, z.ZodCustom<Date, Date>]>, z.ZodTransform<string, string | Date>>>;
57
+ }, z.core.$strip>>>;
58
+ }, z.core.$strip>>;
59
+ pagination: z.ZodOptional<z.ZodObject<{
60
+ pageSize: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
61
+ nextToken: z.ZodOptional<z.ZodNullable<z.ZodString>>;
62
+ }, z.core.$strip>>;
63
+ }, z.core.$strip>;
64
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../../../src/rest-api/resources/app/resources/objects/schema.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,UAAU;;;;iBAIrB,CAAC;AAGH,eAAO,MAAM,WAAW;;;iBAGtB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAiD,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { AuditPayloadSchema, PaginationCollectionSchema, } from "@flipboxlabs/aws-audit-sdk";
2
+ import { z } from "zod";
3
+ import { auditConfig } from "../../../../../audit-config.js";
4
+ import { API_RESOURCE as BASE_API_RESOURCE } from "../../constants.js";
5
+ import { API_RESOURCE } from "./constants.js";
6
+ export const PathSchema = z.object({
7
+ [BASE_API_RESOURCE.RESOURCE_WILDCARD]: auditConfig.schemas.app,
8
+ [API_RESOURCE.RESOURCE_WILDCARD]: auditConfig.schemas.resourceType,
9
+ [API_RESOURCE.RESOURCE_WILDCARD_ITEM]: z.string(),
10
+ });
11
+ // Query params use flat keys matching API Gateway's bracket notation
12
+ export const QuerySchema = z.object({
13
+ "pagination[pageSize]": z.coerce.number().optional(),
14
+ "pagination[nextToken]": z.string().optional(),
15
+ });
16
+ export const ResponseSchema = PaginationCollectionSchema(AuditPayloadSchema);