@digitraffic/common 2024.3.22-2 → 2024.3.28-1

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.
@@ -0,0 +1,25 @@
1
+ import { AclBuilder } from "../../aws/infra/acl-builder.mjs";
2
+ import { App, Stack } from "aws-cdk-lib";
3
+ describe("acl-builder tests", () => {
4
+ function createBuilder() {
5
+ const app = new App();
6
+ const stack = new Stack(app);
7
+ return new AclBuilder(stack);
8
+ }
9
+ test("no rules", () => {
10
+ expect(() => createBuilder().build()).toThrow();
11
+ });
12
+ test("default rules", () => {
13
+ const acl = createBuilder().withAWSManagedRules().build();
14
+ expect(acl.rules).toHaveLength(4);
15
+ });
16
+ test("two aws rules", () => {
17
+ const acl = createBuilder().withAWSManagedRules(["CommonRuleSet", "AmazonIpReputationList"]).build();
18
+ expect(acl.rules).toHaveLength(2);
19
+ });
20
+ test("ip restriction", () => {
21
+ const acl = createBuilder().withIpRestrictionRule(["1.2.3.4", "1.2.6.6"]).build();
22
+ expect(acl.rules).toHaveLength(1);
23
+ });
24
+ });
25
+ //# sourceMappingURL=acl-builder.test.mjs.map
@@ -1,6 +1,6 @@
1
- import { HandlerFactory } from "../../aws/infra/api/handler-factory.mjs";
2
- import { DtLogger } from "../../aws/runtime/dt-logger.mjs";
3
- import { LambdaResponse } from "../../aws/types/lambda-response.mjs";
1
+ import { HandlerFactory } from "../../../aws/infra/api/handler-factory.mjs";
2
+ import { DtLogger } from "../../../aws/runtime/dt-logger.mjs";
3
+ import { LambdaResponse } from "../../../aws/types/lambda-response.mjs";
4
4
  import { jest } from "@jest/globals";
5
5
  const logger = new DtLogger();
6
6
  describe("handler-factory tests", () => {
@@ -1,4 +1,4 @@
1
- import { RESPONSE_DEFAULT_LAMBDA } from "../../aws/infra/api/response.mjs";
1
+ import { RESPONSE_DEFAULT_LAMBDA } from "../../../aws/infra/api/response.mjs";
2
2
  import etag from "etag";
3
3
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
4
4
  //const velocity = require("velocityjs");
@@ -1,5 +1,5 @@
1
- import { DigitrafficStaticIntegration } from "../../aws/infra/api/static-integration.mjs";
2
- import { MediaType } from "../../aws/types/mediatypes.mjs";
1
+ import { DigitrafficStaticIntegration } from "../../../aws/infra/api/static-integration.mjs";
2
+ import { MediaType } from "../../../aws/types/mediatypes.mjs";
3
3
  describe("response tests", () => {
4
4
  it("createIntegrationResponse works", () => {
5
5
  const integrationResponse = DigitrafficStaticIntegration.createIntegrationResponse("FakeResource", MediaType.APPLICATION_JSON, { "test-header": "test-value" });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ import { DocumentationPart } from "../../aws/infra/documentation.mjs";
2
+ const METHOD_NAME = "test";
3
+ const SUMMARY = "summary";
4
+ const PARAMETER_NAME = "parameter";
5
+ const DESCRIPTION = "description";
6
+ const DEPRECATION_NOTE = "note";
7
+ describe("DocumentationPart tests", () => {
8
+ test("method", () => {
9
+ const part = DocumentationPart.method([], METHOD_NAME, SUMMARY);
10
+ expect(part.type).toEqual("METHOD");
11
+ expect(part.parameterName).toEqual(METHOD_NAME);
12
+ expect(part.documentationProperties.summary).toEqual(SUMMARY);
13
+ expect(part.documentationProperties.deprecated).toBeFalsy();
14
+ });
15
+ test("method - deprecated", () => {
16
+ const part = DocumentationPart.method([], METHOD_NAME, SUMMARY).deprecated(DEPRECATION_NOTE);
17
+ expect(part.type).toEqual("METHOD");
18
+ expect(part.parameterName).toEqual(METHOD_NAME);
19
+ expect(part.documentationProperties.summary).toEqual(`${SUMMARY}. ${DEPRECATION_NOTE}`);
20
+ expect(part.documentationProperties.deprecated).toBeTruthy();
21
+ });
22
+ test("queryparameter", () => {
23
+ const part = DocumentationPart.queryParameter(PARAMETER_NAME, DESCRIPTION);
24
+ expect(part.type).toEqual("QUERY_PARAMETER");
25
+ expect(part.parameterName).toEqual(PARAMETER_NAME);
26
+ expect(part.documentationProperties.description).toEqual(DESCRIPTION);
27
+ expect(part.documentationProperties.deprecated).toBeFalsy();
28
+ });
29
+ test("pathparameter", () => {
30
+ const part = DocumentationPart.pathParameter(PARAMETER_NAME, DESCRIPTION);
31
+ expect(part.type).toEqual("PATH_PARAMETER");
32
+ expect(part.parameterName).toEqual(PARAMETER_NAME);
33
+ expect(part.documentationProperties.description).toEqual(DESCRIPTION);
34
+ expect(part.documentationProperties.deprecated).toBeFalsy();
35
+ });
36
+ });
37
+ //# sourceMappingURL=documentation.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ import { App, Stack } from "aws-cdk-lib";
2
+ import { Scheduler } from "../../aws/infra/scheduler.mjs";
3
+ import { Template } from "aws-cdk-lib/assertions";
4
+ describe("scheduler tests", () => {
5
+ function expectRate(createScheduler, expectedRate) {
6
+ const app = new App();
7
+ const stack = new Stack(app);
8
+ createScheduler(stack);
9
+ const template = Template.fromStack(stack);
10
+ template.hasResource("AWS::Events::Rule", {
11
+ Properties: {
12
+ ScheduleExpression: expectedRate,
13
+ State: "ENABLED"
14
+ }
15
+ });
16
+ }
17
+ test("everyMinute", () => expectRate((stack) => Scheduler.everyMinute(stack, "test"), "rate(1 minute)"));
18
+ test("everyMinutes", () => expectRate((stack) => Scheduler.everyMinutes(stack, "test", 12), "rate(12 minutes)"));
19
+ test("everyHour", () => expectRate((stack) => Scheduler.everyHour(stack, "test"), "rate(1 hour)"));
20
+ test("everyDay", () => expectRate((stack) => Scheduler.everyDay(stack, "test"), "rate(1 day)"));
21
+ });
22
+ //# sourceMappingURL=scheduler.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { App, Stack } from "aws-cdk-lib";
2
+ import { Template } from "aws-cdk-lib/assertions";
3
+ import { DigitrafficSecurityRule } from "../../aws/infra/security-rule.mjs";
4
+ import { Topic } from "aws-cdk-lib/aws-sns";
5
+ describe("security-rule tests", () => {
6
+ test("create", () => {
7
+ const app = new App();
8
+ const stack = new Stack(app);
9
+ const topic = new Topic(stack, "test");
10
+ new DigitrafficSecurityRule(stack, topic);
11
+ const template = Template.fromStack(stack);
12
+ template.hasResource("AWS::Events::Rule", {
13
+ Properties: {
14
+ EventPattern: {},
15
+ State: "ENABLED"
16
+ }
17
+ });
18
+ });
19
+ });
20
+ //# sourceMappingURL=security-rule.test.mjs.map
@@ -0,0 +1,21 @@
1
+ import { CfnWebACL } from "aws-cdk-lib/aws-wafv2";
2
+ import type { Construct } from "constructs";
3
+ export type AWSManagedWafRule = "CommonRuleSet" | "AmazonIpReputationList" | "KnownBadInputsRuleSet" | "SQLiRuleSet";
4
+ /**
5
+ * Builder class for building CfnWebACL.
6
+ *
7
+ * Currently supports:
8
+ * * Some AWS managed WAF rules
9
+ * * IP blacklisting
10
+ */
11
+ export declare class AclBuilder {
12
+ readonly _construct: Construct;
13
+ readonly _rules: CfnWebACL.RuleProperty[];
14
+ _scope: string;
15
+ _name: string;
16
+ constructor(construct: Construct);
17
+ isRuleDefined(rules: AWSManagedWafRule[] | "all", rule: AWSManagedWafRule): boolean;
18
+ withAWSManagedRules(rules?: AWSManagedWafRule[] | "all"): AclBuilder;
19
+ withIpRestrictionRule(addresses: string[]): AclBuilder;
20
+ build(): CfnWebACL;
21
+ }
@@ -0,0 +1,136 @@
1
+ import { CfnIPSet, CfnWebACL } from "aws-cdk-lib/aws-wafv2";
2
+ /**
3
+ * Builder class for building CfnWebACL.
4
+ *
5
+ * Currently supports:
6
+ * * Some AWS managed WAF rules
7
+ * * IP blacklisting
8
+ */
9
+ export class AclBuilder {
10
+ _construct;
11
+ _rules = [];
12
+ _scope = "CLOUDFRONT";
13
+ _name = "WebACL";
14
+ constructor(construct) {
15
+ this._construct = construct;
16
+ }
17
+ isRuleDefined(rules, rule) {
18
+ return rules === "all" || rules.includes(rule);
19
+ }
20
+ withAWSManagedRules(rules = "all") {
21
+ if (this.isRuleDefined(rules, "CommonRuleSet")) {
22
+ this._rules.push(createAWSCommonRuleSet());
23
+ }
24
+ if (this.isRuleDefined(rules, "AmazonIpReputationList")) {
25
+ this._rules.push(createAWSReputationList());
26
+ }
27
+ if (this.isRuleDefined(rules, "KnownBadInputsRuleSet")) {
28
+ this._rules.push(createAWSKnownBadInput());
29
+ }
30
+ if (this.isRuleDefined(rules, "SQLiRuleSet")) {
31
+ this._rules.push(createAWSAntiSQLInjection());
32
+ }
33
+ return this;
34
+ }
35
+ withIpRestrictionRule(addresses) {
36
+ const blocklistIpSet = new CfnIPSet(this._construct, "BlocklistIpSet", {
37
+ ipAddressVersion: "IPV4",
38
+ scope: this._scope,
39
+ addresses,
40
+ });
41
+ this._rules.push({
42
+ name: "IpBlocklist",
43
+ priority: 10,
44
+ action: { block: {} },
45
+ statement: {
46
+ ipSetReferenceStatement: {
47
+ arn: blocklistIpSet.attrArn,
48
+ },
49
+ },
50
+ visibilityConfig: {
51
+ sampledRequestsEnabled: false,
52
+ cloudWatchMetricsEnabled: true,
53
+ metricName: "IpBlocklist",
54
+ },
55
+ });
56
+ return this;
57
+ }
58
+ build() {
59
+ if (this._rules.length === 0) {
60
+ throw new Error("No rules defined for WebACL");
61
+ }
62
+ const acl = new CfnWebACL(this._construct, this._name, {
63
+ defaultAction: { allow: {} },
64
+ scope: this._scope,
65
+ visibilityConfig: {
66
+ cloudWatchMetricsEnabled: true,
67
+ metricName: "WAF-Blocked",
68
+ sampledRequestsEnabled: false
69
+ },
70
+ rules: this._rules,
71
+ // customResponseBodies
72
+ });
73
+ return acl;
74
+ }
75
+ }
76
+ function createAWSCommonRuleSet() {
77
+ return createRuleProperty("AWS-AWSManagedRulesCommonRuleSet", 70, {
78
+ statement: {
79
+ managedRuleGroupStatement: {
80
+ vendorName: "AWS",
81
+ name: "AWSManagedRulesCommonRuleSet",
82
+ excludedRules: [
83
+ { name: "NoUserAgent_HEADER" },
84
+ { name: "SizeRestrictions_BODY" },
85
+ { name: "GenericRFI_BODY" }
86
+ ]
87
+ }
88
+ }
89
+ });
90
+ }
91
+ function createAWSReputationList() {
92
+ return createRuleProperty("AWS-AWSManagedRulesAmazonIpReputationList", 80, {
93
+ statement: {
94
+ managedRuleGroupStatement: {
95
+ vendorName: "AWS",
96
+ name: "AWSManagedRulesAmazonIpReputationList"
97
+ }
98
+ }
99
+ });
100
+ }
101
+ function createAWSKnownBadInput() {
102
+ return createRuleProperty("AWS-AWSManagedRulesKnownBadInputsRuleSet", 90, {
103
+ statement: {
104
+ managedRuleGroupStatement: {
105
+ vendorName: "AWS",
106
+ name: "AWSManagedRulesKnownBadInputsRuleSet"
107
+ }
108
+ }
109
+ });
110
+ }
111
+ function createAWSAntiSQLInjection() {
112
+ return createRuleProperty("AWS-AWSManagedRulesSQLiRuleSet", 100, {
113
+ statement: {
114
+ managedRuleGroupStatement: {
115
+ vendorName: "AWS",
116
+ name: "AWSManagedRulesSQLiRuleSet"
117
+ }
118
+ }
119
+ });
120
+ }
121
+ function createRuleProperty(name, priority, rule, overrideAction = true) {
122
+ return {
123
+ ...{
124
+ name,
125
+ priority,
126
+ visibilityConfig: {
127
+ sampledRequestsEnabled: true,
128
+ cloudWatchMetricsEnabled: true,
129
+ metricName: name
130
+ }
131
+ },
132
+ ...rule,
133
+ ...(overrideAction ? { overrideAction: { none: {} } } : {})
134
+ };
135
+ }
136
+ //# sourceMappingURL=acl-builder.mjs.map
@@ -9,11 +9,11 @@ import { SnsTopic } from "aws-cdk-lib/aws-events-targets";
9
9
  */
10
10
  export class DigitrafficSecurityRule extends Rule {
11
11
  constructor(scope, topic) {
12
- const ruleName = 'SecurityHubRule';
12
+ const ruleName = "SecurityHubRule";
13
13
  super(scope, ruleName, {
14
14
  ruleName,
15
15
  eventPattern: {
16
- source: ['aws.securityhub'],
16
+ source: ["aws.securityhub"],
17
17
  detailType: ["Security Hub Findings - Imported"],
18
18
  detail: {
19
19
  findings: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitraffic/common",
3
- "version": "2024.3.22-2",
3
+ "version": "2024.3.28-1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "repository": {
@@ -56,6 +56,7 @@
56
56
  "./dist/aws/infra/stacks/db-proxy-stack": "./dist/aws/infra/stacks/db-proxy-stack.mjs",
57
57
  "./dist/aws/infra/stacks/intra-stack-configuration": "./dist/aws/infra/stacks/intra-stack-configuration.mjs",
58
58
  "./dist/aws/infra/stacks/db-dns-stack": "./dist/aws/infra/stacks/db-dns-stack.mjs",
59
+ "./dist/aws/infra/acl-builder": "./dist/aws/infra/acl-builder.mjs",
59
60
  "./dist/aws/infra/documentation": "./dist/aws/infra/documentation.mjs",
60
61
  "./dist/aws/infra/usage-plans": "./dist/aws/infra/usage-plans.mjs",
61
62
  "./dist/aws/infra/scheduler": "./dist/aws/infra/scheduler.mjs",
@@ -103,32 +104,32 @@
103
104
  "./dist/aws/runtime/digitraffic-integration-response": "./dist/aws/runtime/digitraffic-integration-response.mjs"
104
105
  },
105
106
  "peerDependencies": {
106
- "@aws-sdk/client-s3": "^3.533.0",
107
- "@aws-sdk/lib-storage": "^3.533.0",
108
- "@aws-sdk/client-secrets-manager": "^3.533.0",
109
- "@aws-sdk/client-api-gateway": "^3.533.0",
110
- "@aws-sdk/client-sns": "^3.533.0",
107
+ "@aws-sdk/client-s3": "^3.540.0",
108
+ "@aws-sdk/lib-storage": "^3.540.0",
109
+ "@aws-sdk/client-secrets-manager": "^3.540.0",
110
+ "@aws-sdk/client-api-gateway": "^3.540.0",
111
+ "@aws-sdk/client-sns": "^3.540.0",
111
112
  "@types/geojson": "^7946.0.14",
112
- "aws-cdk-lib": "^2.133.0",
113
+ "aws-cdk-lib": "^2.134.0",
113
114
  "change-case": "5.0.0",
114
115
  "constructs": "^10.3.0",
115
116
  "date-fns": "~2.30.0",
116
117
  "date-fns-tz": "~2.0.0",
117
118
  "etag": "^1.8.1",
118
119
  "geojson-validation": "^1.0.2",
119
- "ky": "^1.2.2",
120
+ "ky": "^1.2.3",
120
121
  "lodash": "~4.17.21",
121
122
  "node-ttl": "^0.2.0",
122
123
  "pg-native": "^3.0.1",
123
124
  "pg-promise": "^11.5.4"
124
125
  },
125
126
  "devDependencies": {
126
- "aws-sdk": "2.1577.0",
127
- "@aws-sdk/client-s3": "3.533.0",
128
- "@aws-sdk/lib-storage": "3.533.0",
129
- "@aws-sdk/client-secrets-manager": "3.533.0",
130
- "@aws-sdk/client-api-gateway": "3.533.0",
131
- "@aws-sdk/client-sns": "3.533.0",
127
+ "aws-sdk": "2.1586.0",
128
+ "@aws-sdk/client-s3": "3.540.0",
129
+ "@aws-sdk/lib-storage": "3.540.0",
130
+ "@aws-sdk/client-secrets-manager": "3.540.0",
131
+ "@aws-sdk/client-api-gateway": "3.540.0",
132
+ "@aws-sdk/client-sns": "3.540.0",
132
133
  "@jest/globals": "^29.7.0",
133
134
  "@rushstack/eslint-config": "^3.6.4",
134
135
  "@rushstack/heft": "^0.66.0",
@@ -142,10 +143,9 @@
142
143
  "@types/jest": "29.5.12",
143
144
  "@types/lodash": "4.14.202",
144
145
  "@types/node": "20.11.27",
145
- "@types/sinon": "17.0.3",
146
146
  "@typescript-eslint/eslint-plugin": "~6.18.1",
147
147
  "@typescript-eslint/parser": "^6.20.0",
148
- "aws-cdk-lib": "^2.133.0",
148
+ "aws-cdk-lib": "^2.134.0",
149
149
  "change-case": "5.3.0",
150
150
  "constructs": "10.3.0",
151
151
  "date-fns": "~2.30.0",
@@ -157,13 +157,12 @@
157
157
  "geojson-validation": "^1.0.2",
158
158
  "jest": "^29.7.0",
159
159
  "jest-junit": "^16.0.0",
160
- "ky": "^1.2.2",
160
+ "ky": "^1.2.3",
161
161
  "lodash": "~4.17.21",
162
162
  "node-ttl": "^0.2.0",
163
163
  "pg-promise": "^11.5.4",
164
164
  "prettier": "^3.2.5",
165
165
  "rimraf": "^5.0.5",
166
- "sinon": "17.0.1",
167
166
  "ts-jest": "^29.1.2",
168
167
  "typescript": "~5.3.3",
169
168
  "velocityjs": "2.0.6"