@digitraffic/common 2025.4.29-1 → 2025.5.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.
- package/README.md +4 -0
- package/dist/__test__/infra/acl-builder.test.js +7 -2
- package/dist/aws/infra/acl-builder.d.ts +19 -12
- package/dist/aws/infra/acl-builder.js +34 -2
- package/dist/aws/runtime/secrets/secret-holder.d.ts +3 -1
- package/dist/aws/runtime/secrets/secret-holder.js +12 -8
- package/dist/types/openapi-schema.d.ts +128 -128
- package/dist/utils/logging.d.ts +1 -2
- package/dist/utils/logging.js +1 -2
- package/package.json +29 -33
package/README.md
CHANGED
@@ -21,8 +21,13 @@ describe("acl-builder tests", () => {
|
|
21
21
|
]).build();
|
22
22
|
expect(acl.rules).toHaveLength(2);
|
23
23
|
});
|
24
|
-
test("ip
|
25
|
-
const acl = createBuilder().
|
24
|
+
test("ip blacklist", () => {
|
25
|
+
const acl = createBuilder().withIpBlacklistRule(["1.2.3.4", "1.2.6.6"])
|
26
|
+
.build();
|
27
|
+
expect(acl.rules).toHaveLength(1);
|
28
|
+
});
|
29
|
+
test("ip whitelist", () => {
|
30
|
+
const acl = createBuilder().withIpWhitelistRule(["1.2.3.4", "1.2.6.6"])
|
26
31
|
.build();
|
27
32
|
expect(acl.rules).toHaveLength(1);
|
28
33
|
});
|
@@ -12,7 +12,7 @@ export type CfnWebAclRuleProperty = {
|
|
12
12
|
*
|
13
13
|
* Currently supports:
|
14
14
|
* * Some AWS managed WAF rules
|
15
|
-
* * IP blacklisting
|
15
|
+
* * IP blacklisting/whitelisting
|
16
16
|
*/
|
17
17
|
export declare class AclBuilder {
|
18
18
|
readonly _construct: Construct;
|
@@ -23,18 +23,25 @@ export declare class AclBuilder {
|
|
23
23
|
_customResponseBodies: Record<string, CfnWebACL.CustomResponseBodyProperty>;
|
24
24
|
constructor(construct: Construct, name?: string);
|
25
25
|
isRuleDefined(rules: AWSManagedWafRule[] | "all", rule: AWSManagedWafRule): boolean;
|
26
|
-
withAWSManagedRules(rules?: AWSManagedWafRule[] | "all", excludedRules?: ExcludedAWSRules):
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
withAWSManagedRules(rules?: AWSManagedWafRule[] | "all", excludedRules?: ExcludedAWSRules): this;
|
27
|
+
/**
|
28
|
+
* Block access from given addresses
|
29
|
+
*/
|
30
|
+
withIpBlacklistRule(addresses: string[]): this;
|
31
|
+
/**
|
32
|
+
* Allow access only from the given addresses
|
33
|
+
*/
|
34
|
+
withIpWhitelistRule(addresses: string[]): this;
|
35
|
+
withThrottleRule(name: string, limit: number, isHeaderRequired: boolean, isBasedOnIpAndUriPath: boolean, customResponseBodyKey?: string): this;
|
36
|
+
withCustomResponseBody(key: string, customResponseBody: CfnWebACL.CustomResponseBodyProperty): this;
|
37
|
+
withThrottleDigitrafficUserIp(limit: number | undefined): this;
|
38
|
+
withThrottleDigitrafficUserIpAndUriPath(limit: number | undefined): this;
|
32
39
|
withThrottleAnonymousUserIp(limit: number | undefined): AclBuilder;
|
33
|
-
withThrottleAnonymousUserIpAndUriPath(limit: number | undefined):
|
34
|
-
withCountDigitrafficUserIp(limit: number | undefined):
|
35
|
-
withCountDigitrafficUserIpAndUriPath(limit: number | undefined):
|
36
|
-
withCountAnonymousUserIp(limit: number | undefined):
|
37
|
-
withCountAnonymousUserIpAndUriPath(limit: number | undefined):
|
40
|
+
withThrottleAnonymousUserIpAndUriPath(limit: number | undefined): this;
|
41
|
+
withCountDigitrafficUserIp(limit: number | undefined): this;
|
42
|
+
withCountDigitrafficUserIpAndUriPath(limit: number | undefined): this;
|
43
|
+
withCountAnonymousUserIp(limit: number | undefined): this;
|
44
|
+
withCountAnonymousUserIpAndUriPath(limit: number | undefined): this;
|
38
45
|
_isCustomResponseBodyKeySet(key: string): boolean;
|
39
46
|
_addThrottleResponseBody(customResponseBodyKey: string, limit: number): void;
|
40
47
|
build(): CfnWebACL;
|
@@ -6,7 +6,7 @@ import { concat, range, zipWith } from "lodash-es";
|
|
6
6
|
*
|
7
7
|
* Currently supports:
|
8
8
|
* * Some AWS managed WAF rules
|
9
|
-
* * IP blacklisting
|
9
|
+
* * IP blacklisting/whitelisting
|
10
10
|
*/
|
11
11
|
export class AclBuilder {
|
12
12
|
_construct;
|
@@ -37,7 +37,10 @@ export class AclBuilder {
|
|
37
37
|
}
|
38
38
|
return this;
|
39
39
|
}
|
40
|
-
|
40
|
+
/**
|
41
|
+
* Block access from given addresses
|
42
|
+
*/
|
43
|
+
withIpBlacklistRule(addresses) {
|
41
44
|
const blocklistIpSet = new CfnIPSet(this._construct, "BlocklistIpSet", {
|
42
45
|
ipAddressVersion: "IPV4",
|
43
46
|
scope: this._scope,
|
@@ -59,6 +62,35 @@ export class AclBuilder {
|
|
59
62
|
});
|
60
63
|
return this;
|
61
64
|
}
|
65
|
+
/**
|
66
|
+
* Allow access only from the given addresses
|
67
|
+
*/
|
68
|
+
withIpWhitelistRule(addresses) {
|
69
|
+
const blocklistIpSet = new CfnIPSet(this._construct, "AllowlistIpSet", {
|
70
|
+
ipAddressVersion: "IPV4",
|
71
|
+
scope: this._scope,
|
72
|
+
addresses,
|
73
|
+
});
|
74
|
+
this._blockRules.push({
|
75
|
+
name: "IpAllowlist",
|
76
|
+
action: { block: {} },
|
77
|
+
statement: {
|
78
|
+
notStatement: {
|
79
|
+
statement: {
|
80
|
+
ipSetReferenceStatement: {
|
81
|
+
arn: blocklistIpSet.attrArn,
|
82
|
+
},
|
83
|
+
},
|
84
|
+
},
|
85
|
+
},
|
86
|
+
visibilityConfig: {
|
87
|
+
sampledRequestsEnabled: false,
|
88
|
+
cloudWatchMetricsEnabled: true,
|
89
|
+
metricName: "IpAllowlist",
|
90
|
+
},
|
91
|
+
});
|
92
|
+
return this;
|
93
|
+
}
|
62
94
|
withThrottleRule(name, limit, isHeaderRequired, isBasedOnIpAndUriPath, customResponseBodyKey) {
|
63
95
|
const isBlockRule = !!customResponseBodyKey;
|
64
96
|
const rules = isBlockRule ? this._blockRules : this._countRules;
|
@@ -17,7 +17,9 @@ export declare class SecretHolder<Secret extends GenericSecret> {
|
|
17
17
|
private readonly secretId;
|
18
18
|
private readonly prefix;
|
19
19
|
private readonly expectedKeys;
|
20
|
-
private
|
20
|
+
private cachedSecret?;
|
21
|
+
private expirationTime;
|
22
|
+
private readonly ttl;
|
21
23
|
constructor(secretId: string, prefix?: string, expectedKeys?: string[], configuration?: typeof DEFAULT_CONFIGURATION);
|
22
24
|
private initSecret;
|
23
25
|
static create<S extends GenericSecret>(prefix?: string, expectedKeys?: string[]): SecretHolder<S>;
|
@@ -2,9 +2,7 @@ import { getSecret } from "./secret.js";
|
|
2
2
|
import { checkExpectedSecretKeys } from "./dbsecret.js";
|
3
3
|
import { getEnvVariable } from "../../../utils/utils.js";
|
4
4
|
import { logger } from "../dt-logger-default.js";
|
5
|
-
import NodeTtl from "node-ttl";
|
6
5
|
const DEFAULT_PREFIX = "";
|
7
|
-
const DEFAULT_SECRET_KEY = "SECRET";
|
8
6
|
const DEFAULT_CONFIGURATION = {
|
9
7
|
ttl: 5 * 60, // timeout secrets in 5 minutes
|
10
8
|
};
|
@@ -23,12 +21,15 @@ export class SecretHolder {
|
|
23
21
|
secretId;
|
24
22
|
prefix;
|
25
23
|
expectedKeys;
|
26
|
-
|
24
|
+
cachedSecret;
|
25
|
+
expirationTime;
|
26
|
+
ttl; // seconds
|
27
27
|
constructor(secretId, prefix = "", expectedKeys = [], configuration = DEFAULT_CONFIGURATION) {
|
28
28
|
this.secretId = secretId;
|
29
29
|
this.prefix = prefix;
|
30
30
|
this.expectedKeys = expectedKeys;
|
31
|
-
this.
|
31
|
+
this.expirationTime = new Date(0);
|
32
|
+
this.ttl = configuration.ttl;
|
32
33
|
}
|
33
34
|
async initSecret() {
|
34
35
|
const secretValue = await getSecret(this.secretId);
|
@@ -36,7 +37,8 @@ export class SecretHolder {
|
|
36
37
|
method: "SecretHolder.initSecret",
|
37
38
|
message: "Refreshing secret " + this.secretId,
|
38
39
|
});
|
39
|
-
this.
|
40
|
+
this.cachedSecret = secretValue;
|
41
|
+
this.expirationTime = new Date(Date.now() + this.ttl * 1000);
|
40
42
|
}
|
41
43
|
static create(prefix = DEFAULT_PREFIX, expectedKeys = []) {
|
42
44
|
return new SecretHolder(getEnvVariable("SECRET_ID"), prefix, expectedKeys);
|
@@ -67,11 +69,13 @@ export class SecretHolder {
|
|
67
69
|
return parsed;
|
68
70
|
}
|
69
71
|
async getSecret() {
|
70
|
-
|
71
|
-
if (!secret) {
|
72
|
+
if (this.expirationTime.getTime() < Date.now()) {
|
72
73
|
await this.initSecret();
|
73
74
|
}
|
74
|
-
|
75
|
+
if (this.cachedSecret === undefined) {
|
76
|
+
throw new Error("SecretHolder in illegal state");
|
77
|
+
}
|
78
|
+
return this.cachedSecret;
|
75
79
|
}
|
76
80
|
}
|
77
81
|
//# sourceMappingURL=secret-holder.js.map
|