@rio-cloud/cdk-v2-constructs 6.15.0 → 6.16.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.
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.trimIndent = trimIndent;
4
+ /**
5
+ * Trim the indent of a multiline string.
6
+ *
7
+ * This uses the [Tagged Templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) feature of JavaScript.
8
+ *
9
+ * Useful in particular when defining multiline messages for datadog monitors.
10
+ * Usage example:
11
+ *
12
+ * ```typescript
13
+ * const message = trimIndent`
14
+ * {{#is_warning}}
15
+ * The auth-server handles ${props.others.name} slower than usual.
16
+ * {{/is_warning}}
17
+ * `;
18
+ * console.log(message);
19
+ * ```
20
+ * returns the following:
21
+ * ```
22
+ * {{#is_warning}}
23
+ * The auth-server handles ${props.others.name} slower than usual.
24
+ * {{/is_warning}}
25
+ * ```
26
+ */
27
+ function trimIndent(strings, ...values) {
28
+ let rawString = strings.raw.reduce((acc, str, i) => acc + str + (values[i] || ''), '');
29
+ const lines = rawString.split('\n');
30
+ const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
31
+ const indentLengths = nonEmptyLines.map((line) => {
32
+ const match = line.match(/^\s*/);
33
+ if (match === null || match.length === 0) {
34
+ return 0;
35
+ }
36
+ return match[0].length;
37
+ });
38
+ const minIndent = Math.min(...indentLengths);
39
+ return lines
40
+ .map((line) => (line.startsWith(' '.repeat(minIndent)) ? line.slice(minIndent) : line))
41
+ .join('\n')
42
+ .trim();
43
+ }
44
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Nlcy9oZWxwZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUF1QkEsZ0NBaUJDO0FBeENEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBQ0gsU0FBZ0IsVUFBVSxDQUFDLE9BQTZCLEVBQUUsR0FBRyxNQUFhO0lBQ3hFLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdkYsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQyxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sYUFBYSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUMvQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2pDLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUN6QixDQUFDLENBQUMsQ0FBQztJQUNILE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxhQUFhLENBQUMsQ0FBQztJQUU3QyxPQUFPLEtBQUs7U0FDVCxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3RGLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDVixJQUFJLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyaW0gdGhlIGluZGVudCBvZiBhIG11bHRpbGluZSBzdHJpbmcuXG4gKlxuICogVGhpcyB1c2VzIHRoZSBbVGFnZ2VkIFRlbXBsYXRlc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvVGVtcGxhdGVfbGl0ZXJhbHMjdGFnZ2VkX3RlbXBsYXRlcykgZmVhdHVyZSBvZiBKYXZhU2NyaXB0LlxuICpcbiAqIFVzZWZ1bCBpbiBwYXJ0aWN1bGFyIHdoZW4gZGVmaW5pbmcgbXVsdGlsaW5lIG1lc3NhZ2VzIGZvciBkYXRhZG9nIG1vbml0b3JzLlxuICogVXNhZ2UgZXhhbXBsZTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBtZXNzYWdlID0gdHJpbUluZGVudGBcbiAqICAgICB7eyNpc193YXJuaW5nfX1cbiAqICAgICAgIFRoZSBhdXRoLXNlcnZlciBoYW5kbGVzICR7cHJvcHMub3RoZXJzLm5hbWV9IHNsb3dlciB0aGFuIHVzdWFsLlxuICogICAgIHt7L2lzX3dhcm5pbmd9fVxuICogICBgO1xuICogY29uc29sZS5sb2cobWVzc2FnZSk7XG4gKiBgYGBcbiAqIHJldHVybnMgdGhlIGZvbGxvd2luZzpcbiAqIGBgYFxuICoge3sjaXNfd2FybmluZ319XG4gKiAgIFRoZSBhdXRoLXNlcnZlciBoYW5kbGVzICR7cHJvcHMub3RoZXJzLm5hbWV9IHNsb3dlciB0aGFuIHVzdWFsLlxuICoge3svaXNfd2FybmluZ319XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyaW1JbmRlbnQoc3RyaW5nczogVGVtcGxhdGVTdHJpbmdzQXJyYXksIC4uLnZhbHVlczogYW55W10pOiBzdHJpbmcge1xuICBsZXQgcmF3U3RyaW5nID0gc3RyaW5ncy5yYXcucmVkdWNlKChhY2MsIHN0ciwgaSkgPT4gYWNjICsgc3RyICsgKHZhbHVlc1tpXSB8fCAnJyksICcnKTtcbiAgY29uc3QgbGluZXMgPSByYXdTdHJpbmcuc3BsaXQoJ1xcbicpO1xuICBjb25zdCBub25FbXB0eUxpbmVzID0gbGluZXMuZmlsdGVyKChsaW5lKSA9PiBsaW5lLnRyaW0oKS5sZW5ndGggPiAwKTtcbiAgY29uc3QgaW5kZW50TGVuZ3RocyA9IG5vbkVtcHR5TGluZXMubWFwKChsaW5lKSA9PiB7XG4gICAgY29uc3QgbWF0Y2ggPSBsaW5lLm1hdGNoKC9eXFxzKi8pO1xuICAgIGlmIChtYXRjaCA9PT0gbnVsbCB8fCBtYXRjaC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gbWF0Y2hbMF0ubGVuZ3RoO1xuICB9KTtcbiAgY29uc3QgbWluSW5kZW50ID0gTWF0aC5taW4oLi4uaW5kZW50TGVuZ3Rocyk7XG5cbiAgcmV0dXJuIGxpbmVzXG4gICAgLm1hcCgobGluZSkgPT4gKGxpbmUuc3RhcnRzV2l0aCgnICcucmVwZWF0KG1pbkluZGVudCkpID8gbGluZS5zbGljZShtaW5JbmRlbnQpIDogbGluZSkpXG4gICAgLmpvaW4oJ1xcbicpXG4gICAgLnRyaW0oKTtcbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export * from './ses-observability';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ses-observability"), exports);
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxzREFBb0MiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3Nlcy1vYnNlcnZhYmlsaXR5JzsiXX0=
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/ses/lambda/ses-logger.ts
21
+ var ses_logger_exports = {};
22
+ __export(ses_logger_exports, {
23
+ handler: () => handler
24
+ });
25
+ module.exports = __toCommonJS(ses_logger_exports);
26
+ var handler = async (event) => {
27
+ try {
28
+ const perEmailEvents = event.Records.map(({ Sns, ...rest }) => ({
29
+ ...event,
30
+ Records: void 0,
31
+ Record: {
32
+ ...rest,
33
+ Sns: {
34
+ ...Sns,
35
+ Message: JSON.parse(Sns.Message)
36
+ }
37
+ }
38
+ }));
39
+ perEmailEvents.forEach((perEmailEvent) => {
40
+ console.log(perEmailEvent);
41
+ });
42
+ } catch (err) {
43
+ console.error(err);
44
+ console.log(event);
45
+ }
46
+ };
47
+ // Annotate the CommonJS export names for ESM import in node:
48
+ 0 && (module.exports = {
49
+ handler
50
+ });
@@ -0,0 +1,2 @@
1
+ import { SNSEvent } from 'aws-lambda';
2
+ export declare const handler: (event: SNSEvent) => Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handler = void 0;
4
+ const handler = async (event) => {
5
+ try {
6
+ // Parse and write one log per event/email
7
+ const perEmailEvents = event.Records.map(({ Sns, ...rest }) => ({
8
+ ...event,
9
+ Records: undefined,
10
+ Record: {
11
+ ...rest,
12
+ Sns: {
13
+ ...Sns,
14
+ Message: JSON.parse(Sns.Message),
15
+ },
16
+ },
17
+ }));
18
+ perEmailEvents.forEach((perEmailEvent) => {
19
+ console.log(perEmailEvent);
20
+ });
21
+ }
22
+ catch (err) {
23
+ console.error(err);
24
+ console.log(event);
25
+ }
26
+ };
27
+ exports.handler = handler;
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VzLWxvZ2dlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXMvbGFtYmRhL3Nlcy1sb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRU8sTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLEtBQWUsRUFBRSxFQUFFO0lBQy9DLElBQUksQ0FBQztRQUNILDBDQUEwQztRQUMxQyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDOUQsR0FBRyxLQUFLO1lBQ1IsT0FBTyxFQUFFLFNBQVM7WUFDbEIsTUFBTSxFQUFFO2dCQUNOLEdBQUcsSUFBSTtnQkFDUCxHQUFHLEVBQUU7b0JBQ0gsR0FBRyxHQUFHO29CQUNOLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQVc7aUJBQzNDO2FBQ0Y7U0FDRixDQUFDLENBQUMsQ0FBQztRQUNKLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxhQUFhLEVBQUUsRUFBRTtZQUN2QyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ25CLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckIsQ0FBQztBQUNILENBQUMsQ0FBQztBQXJCVyxRQUFBLE9BQU8sV0FxQmxCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU05TRXZlbnQgfSBmcm9tICdhd3MtbGFtYmRhJztcblxuZXhwb3J0IGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoZXZlbnQ6IFNOU0V2ZW50KSA9PiB7XG4gIHRyeSB7XG4gICAgLy8gUGFyc2UgYW5kIHdyaXRlIG9uZSBsb2cgcGVyIGV2ZW50L2VtYWlsXG4gICAgY29uc3QgcGVyRW1haWxFdmVudHMgPSBldmVudC5SZWNvcmRzLm1hcCgoeyBTbnMsIC4uLnJlc3QgfSkgPT4gKHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgUmVjb3JkczogdW5kZWZpbmVkLFxuICAgICAgUmVjb3JkOiB7XG4gICAgICAgIC4uLnJlc3QsXG4gICAgICAgIFNuczoge1xuICAgICAgICAgIC4uLlNucyxcbiAgICAgICAgICBNZXNzYWdlOiBKU09OLnBhcnNlKFNucy5NZXNzYWdlKSBhcyBvYmplY3QsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pKTtcbiAgICBwZXJFbWFpbEV2ZW50cy5mb3JFYWNoKChwZXJFbWFpbEV2ZW50KSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhwZXJFbWFpbEV2ZW50KTtcbiAgICB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgIGNvbnNvbGUubG9nKGV2ZW50KTtcbiAgfVxufTtcbiJdfQ==
@@ -0,0 +1,63 @@
1
+ import * as ses from 'aws-cdk-lib/aws-ses';
2
+ import * as sns from 'aws-cdk-lib/aws-sns';
3
+ import { Construct } from 'constructs';
4
+ export interface SesObservabilityProps {
5
+ /**
6
+ * The SES events to log.
7
+ *
8
+ * @default [EmailSendingEvent.DELIVERY, EmailSendingEvent.BOUNCE, EmailSendingEvent.COMPLAINT, EmailSendingEvent.REJECT]
9
+ */
10
+ readonly loggedSesEvents?: ses.EmailSendingEvent[];
11
+ }
12
+ /**
13
+ * RioSesObservability
14
+ *
15
+ * This construct sets up observability for SES as defined by [ADR - SES domain reputation observability](https://confluence.collaboration-man.com/display/MAN/ADR+-+SES+domain+reputation+observability).
16
+ *
17
+ * # Warning
18
+ * This construct results in logging all sent emails including the recipient address into CloudWatch logs.
19
+ * As this is considered **PII**, this information MUST be handled accordingly.
20
+ * In particular, logs **MUST NOT** be sent to further third party services (e.g. Datadog) and the retention period for logs **MUST NOT** be extended.
21
+ *
22
+ * # Usage
23
+ * ## Default Configuration Set for Identity
24
+ *
25
+ * ```typescript
26
+ * const rioSesObservability = new RioSesObservability(this, 'ConfigurationSet', {})
27
+ * const identity = new EmailIdentity(this, 'EmailIdentity', {
28
+ * identity: Identity.domain('example.com'),
29
+ * configurationSet: rioSesObservability.configurationSet,
30
+ * });
31
+ * ```
32
+ *
33
+ * ## Specifically using the configuration set per request
34
+ *
35
+ * This is ideal if you want to try out the construct first one some specific emails (e.g. during initial migration).
36
+ * The configuration set name is exported as an SSM parameter `/rio/config/ses-observability/configuration-set-name`.
37
+ * Thus, you can easily make it available as environment variable in your code.
38
+ *
39
+ * ```kotlin
40
+ * import com.amazonaws.services.simpleemail.model.SendEmailRequest
41
+ *
42
+ * val request = SendEmailRequest()
43
+ * .withConfigurationSetName(SSM_CONFIGURATION_SSM_PARAMETER_VALUE)
44
+ * ...
45
+ * ```
46
+ *
47
+ * ## Automated event processing
48
+ *
49
+ * If you have specific needs for which you'd like to process the SNS events directly
50
+ * (e.g. automatically creating a suppression list from bounces), you can subscribe to the SNS topic.
51
+ * To enable this the SNS topic ARN is exported via Cloudformation as `RioSesObservabilityTopicArn`.
52
+ */
53
+ export declare class SesObservability extends Construct {
54
+ static readonly CONFIGURATION_SET_NAME_SSM_PARAMETER = "/rio/config/ses-observability/configuration-set-name";
55
+ static readonly SNS_TOPIC_ARN_EXPORT_NAME = "RioSesObservabilityTopicArn";
56
+ readonly snsTopic: sns.Topic;
57
+ readonly configurationSet: ses.ConfigurationSet;
58
+ constructor(scope: Construct, id: string, props: SesObservabilityProps);
59
+ /**
60
+ * This function ensures that no PII is leaked to Datadog by adding a subscription filter to the log group of the lambda.
61
+ */
62
+ private ensureNoSubscriptionFiltersOnLambdasLogGroup;
63
+ }
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.SesObservability = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const path = require("path");
7
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
8
+ const lambda = require("aws-cdk-lib/aws-lambda");
9
+ const aws_logs_1 = require("aws-cdk-lib/aws-logs");
10
+ const ses = require("aws-cdk-lib/aws-ses");
11
+ const sns = require("aws-cdk-lib/aws-sns");
12
+ const snsSubscriptions = require("aws-cdk-lib/aws-sns-subscriptions");
13
+ const ssm = require("aws-cdk-lib/aws-ssm");
14
+ const cdk = require("aws-cdk-lib/core");
15
+ const constructs_1 = require("constructs");
16
+ const helper_1 = require("./helper");
17
+ const datadogv2_1 = require("../datadogv2");
18
+ const rio_landing_zone_1 = require("../rio-landing-zone");
19
+ /**
20
+ * RioSesObservability
21
+ *
22
+ * This construct sets up observability for SES as defined by [ADR - SES domain reputation observability](https://confluence.collaboration-man.com/display/MAN/ADR+-+SES+domain+reputation+observability).
23
+ *
24
+ * # Warning
25
+ * This construct results in logging all sent emails including the recipient address into CloudWatch logs.
26
+ * As this is considered **PII**, this information MUST be handled accordingly.
27
+ * In particular, logs **MUST NOT** be sent to further third party services (e.g. Datadog) and the retention period for logs **MUST NOT** be extended.
28
+ *
29
+ * # Usage
30
+ * ## Default Configuration Set for Identity
31
+ *
32
+ * ```typescript
33
+ * const rioSesObservability = new RioSesObservability(this, 'ConfigurationSet', {})
34
+ * const identity = new EmailIdentity(this, 'EmailIdentity', {
35
+ * identity: Identity.domain('example.com'),
36
+ * configurationSet: rioSesObservability.configurationSet,
37
+ * });
38
+ * ```
39
+ *
40
+ * ## Specifically using the configuration set per request
41
+ *
42
+ * This is ideal if you want to try out the construct first one some specific emails (e.g. during initial migration).
43
+ * The configuration set name is exported as an SSM parameter `/rio/config/ses-observability/configuration-set-name`.
44
+ * Thus, you can easily make it available as environment variable in your code.
45
+ *
46
+ * ```kotlin
47
+ * import com.amazonaws.services.simpleemail.model.SendEmailRequest
48
+ *
49
+ * val request = SendEmailRequest()
50
+ * .withConfigurationSetName(SSM_CONFIGURATION_SSM_PARAMETER_VALUE)
51
+ * ...
52
+ * ```
53
+ *
54
+ * ## Automated event processing
55
+ *
56
+ * If you have specific needs for which you'd like to process the SNS events directly
57
+ * (e.g. automatically creating a suppression list from bounces), you can subscribe to the SNS topic.
58
+ * To enable this the SNS topic ARN is exported via Cloudformation as `RioSesObservabilityTopicArn`.
59
+ */
60
+ class SesObservability extends constructs_1.Construct {
61
+ constructor(scope, id, props) {
62
+ super(scope, id);
63
+ const accountId = aws_cdk_lib_1.Stack.of(this).account;
64
+ const accountName = rio_landing_zone_1.RioLandingZone.getAccountNameParameter(this);
65
+ const parameter = new ssm.StringParameter(this, 'ConfigurationSetName', {
66
+ parameterName: SesObservability.CONFIGURATION_SET_NAME_SSM_PARAMETER,
67
+ stringValue: 'rio-ses-observability-configuration-set',
68
+ });
69
+ this.snsTopic = new sns.Topic(this, 'SnsTopic', {
70
+ topicName: 'rio-ses-observability-topic',
71
+ });
72
+ this.configurationSet = new ses.ConfigurationSet(this, 'ConfigurationSet', {
73
+ configurationSetName: parameter.stringValue,
74
+ });
75
+ this.configurationSet.addEventDestination('EventDestination', {
76
+ configurationSetEventDestinationName: 'rio-ses-observability-event-destination',
77
+ destination: ses.EventDestination.snsTopic(this.snsTopic),
78
+ events: props.loggedSesEvents ?? [
79
+ ses.EmailSendingEvent.DELIVERY,
80
+ ses.EmailSendingEvent.BOUNCE,
81
+ ses.EmailSendingEvent.COMPLAINT,
82
+ ses.EmailSendingEvent.REJECT,
83
+ ],
84
+ });
85
+ const logFunction = new lambda.Function(this, 'LogFunction', {
86
+ functionName: 'rio-ses-observability-log-function',
87
+ runtime: lambda.Runtime.NODEJS_20_X,
88
+ handler: 'index.handler',
89
+ logRetention: aws_logs_1.RetentionDays.THREE_MONTHS,
90
+ systemLogLevelV2: lambda.SystemLogLevel.WARN,
91
+ loggingFormat: lambda.LoggingFormat.JSON,
92
+ code: lambda.Code.fromAsset(path.join(__dirname, 'lambda'), {
93
+ exclude: ['*.js', '*.d.ts'],
94
+ }),
95
+ });
96
+ this.ensureNoSubscriptionFiltersOnLambdasLogGroup(logFunction);
97
+ this.snsTopic.addSubscription(new snsSubscriptions.LambdaSubscription(logFunction));
98
+ new cdk.CfnOutput(this, 'SnsTopicArn', {
99
+ value: this.snsTopic.topicArn,
100
+ exportName: SesObservability.SNS_TOPIC_ARN_EXPORT_NAME,
101
+ });
102
+ const notificationHandle = rio_landing_zone_1.RioLandingZone.getTeamAlertSlackChannelParameter(this);
103
+ new datadogv2_1.DatadogMonitor(this, 'QuotaMonitor', {
104
+ name: `${accountName} SES quota almost reached`,
105
+ serviceName: 'aws-ses',
106
+ monitorType: datadogv2_1.DatadogMonitorQueryAlertType.QUERY_ALERT,
107
+ query: `max(last_1h):max:aws.ses.sent_last_24_hours{account_id:${accountId}} / max:aws.ses.max_24_hour_send{account_id:${accountId}} > 0.8`,
108
+ message: (0, helper_1.trimIndent) `
109
+ You are almost using up you're maximum email sending quota per 24h.
110
+ Either [request an increase](https://docs.aws.amazon.com/ses/latest/dg/manage-sending-quotas-request-increase.html) for your quota by AWS or reduce the amount of emails sent.
111
+ You can find logs about all mails sent at \`${logFunction.logGroup.logGroupName}\`.
112
+
113
+ {{#is_alert}}@slack-${notificationHandle}{{/is_alert}}
114
+ {{#is_alert_recovery}}@slack-${notificationHandle}{{/is_alert_recovery}}
115
+ `,
116
+ priority: 4,
117
+ optionOverrides: {
118
+ thresholds: {
119
+ critical: 0.8,
120
+ warning: 0.7,
121
+ },
122
+ evaluationDelay: 900,
123
+ },
124
+ });
125
+ new datadogv2_1.DatadogMonitor(this, 'EmailRejectedMonitor', {
126
+ name: `${accountName} SES Email Rejected`,
127
+ serviceName: 'aws-ses',
128
+ monitorType: datadogv2_1.DatadogMonitorQueryAlertType.QUERY_ALERT,
129
+ query: `sum(last_1h):max:aws.ses.rejects{account_id:${accountId}} > 0`,
130
+ message: (0, helper_1.trimIndent) `
131
+ SES [rejected](https://docs.aws.amazon.com/ses/latest/dg/monitor-sending-activity.html) sending at least one email.
132
+ Please investigate the root case, as this is not expected to happen in production ever.
133
+ You can find logs about all mails sent at \`${logFunction.logGroup.logGroupName}\`.
134
+
135
+ {{#is_alert}}@slack-${notificationHandle}{{/is_alert}}
136
+ `,
137
+ priority: 3,
138
+ optionOverrides: {
139
+ thresholds: {
140
+ critical: 0,
141
+ },
142
+ evaluationDelay: 900,
143
+ },
144
+ });
145
+ new datadogv2_1.DatadogMonitor(this, 'ComplaintRateMonitor', {
146
+ name: `${accountName} SES reputation endangered: Complaint rate High`,
147
+ serviceName: 'aws-ses',
148
+ monitorType: datadogv2_1.DatadogMonitorQueryAlertType.QUERY_ALERT,
149
+ query: `max(last_1h):max:aws.ses.reputation_complaint_rate{account_id:${accountId} and not ses:*} > 0.001`,
150
+ message: (0, helper_1.trimIndent) `
151
+ Warning Threshold for Complaint rate {{#is_warning}}almost {{/is_warning}}reached (as defined in AWS).
152
+
153
+ Please reduce the number of complaints received for E-mails sent by your Account.
154
+ If this metric reaches \`0.5%\` the email sending capability of your account will be disabled by AWS.
155
+ You can find logs about all mails sent at \`${logFunction.logGroup.logGroupName}\`.
156
+ See [ADR - SES domain reputation observability](https://confluence.collaboration-man.com/display/MAN/ADR+-+SES+domain+reputation+observability).
157
+
158
+
159
+ {{#is_alert}}@slack-${notificationHandle}{{/is_alert}}
160
+ {{#is_alert_recovery}}@slack-${notificationHandle}{{/is_alert_recovery}}
161
+ `,
162
+ priority: 2,
163
+ optionOverrides: {
164
+ thresholds: {
165
+ critical: 0.001,
166
+ warning: 0.0008,
167
+ },
168
+ evaluationDelay: 900,
169
+ },
170
+ });
171
+ new datadogv2_1.DatadogMonitor(this, 'BounceRateMonitor', {
172
+ name: `${accountName} SES reputation endangered: Bounce Rate High`,
173
+ serviceName: 'aws-ses',
174
+ monitorType: datadogv2_1.DatadogMonitorQueryAlertType.QUERY_ALERT,
175
+ query: `max(last_1h):max:aws.ses.reputation_bounce_rate{account_id:${accountId} and not ses:*} > 0.05`,
176
+ message: (0, helper_1.trimIndent) `
177
+ Warning Threshold for Bounce rate {{#is_warning}}almost {{/is_warning}}reached (as defined in AWS).
178
+
179
+ Please reduce the number of bounces for E-mails sent by your Account.
180
+ If this metric reaches \`10%\` the email sending capability of your account will be disabled by AWS.
181
+ You can find logs about all mails sent at \`${logFunction.logGroup.logGroupName}\`.
182
+ See [ADR - SES domain reputation observability](https://confluence.collaboration-man.com/display/MAN/ADR+-+SES+domain+reputation+observability).
183
+
184
+
185
+ {{#is_alert}}@slack-${notificationHandle}{{/is_alert}}
186
+ {{#is_alert_recovery}}@slack-${notificationHandle}{{/is_alert_recovery}}
187
+ `,
188
+ priority: 2,
189
+ optionOverrides: {
190
+ thresholds: {
191
+ critical: 0.05,
192
+ warning: 0.04,
193
+ },
194
+ evaluationDelay: 900,
195
+ },
196
+ });
197
+ }
198
+ /**
199
+ * This function ensures that no PII is leaked to Datadog by adding a subscription filter to the log group of the lambda.
200
+ */
201
+ ensureNoSubscriptionFiltersOnLambdasLogGroup(logFunction) {
202
+ const stack = cdk.Stack.of(this);
203
+ stack.node.addValidation({
204
+ validate: () => {
205
+ const errors = [];
206
+ stack.node.findAll().forEach(node => {
207
+ if (node instanceof aws_logs_1.CfnSubscriptionFilter) {
208
+ const logGroupName = node.logGroupName;
209
+ if (logGroupName === logFunction.logGroup.logGroupName) {
210
+ errors.push('Subscription filters are not allowed ses-observability lambdas log group');
211
+ }
212
+ }
213
+ });
214
+ return errors;
215
+ },
216
+ });
217
+ }
218
+ }
219
+ exports.SesObservability = SesObservability;
220
+ _a = JSII_RTTI_SYMBOL_1;
221
+ SesObservability[_a] = { fqn: "@rio-cloud/cdk-v2-constructs.SesObservability", version: "0.0.0" };
222
+ // ! changing these values is a breaking change for users
223
+ SesObservability.CONFIGURATION_SET_NAME_SSM_PARAMETER = '/rio/config/ses-observability/configuration-set-name';
224
+ SesObservability.SNS_TOPIC_ARN_EXPORT_NAME = 'RioSesObservabilityTopicArn';
225
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VzLW9ic2VydmFiaWxpdHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VzL3Nlcy1vYnNlcnZhYmlsaXR5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsNkJBQTZCO0FBQzdCLDZDQUFvQztBQUNwQyxpREFBaUQ7QUFFakQsbURBQTRFO0FBQzVFLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0Msc0VBQXNFO0FBQ3RFLDJDQUEyQztBQUMzQyx3Q0FBd0M7QUFDeEMsMkNBQXVDO0FBQ3ZDLHFDQUFzQztBQUN0Qyw0Q0FBNEU7QUFDNUUsMERBQXFEO0FBWXJEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0NHO0FBQ0gsTUFBYSxnQkFBaUIsU0FBUSxzQkFBUztJQU83QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQTRCO1FBQ3BFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsTUFBTSxTQUFTLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ3pDLE1BQU0sV0FBVyxHQUFHLGlDQUFjLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFakUsTUFBTSxTQUFTLEdBQUcsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxzQkFBc0IsRUFBRTtZQUN0RSxhQUFhLEVBQUUsZ0JBQWdCLENBQUMsb0NBQW9DO1lBQ3BFLFdBQVcsRUFBRSx5Q0FBeUM7U0FDdkQsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtZQUM5QyxTQUFTLEVBQUUsNkJBQTZCO1NBQ3pDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVB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QUFPLEVBQUUsSUFBSTtpQkFDZDtnQkFDRCxlQUFlLEVBQUUsR0FBRzthQUNyQjtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLDRDQUE0QyxDQUFDLFdBQTJCO1FBQzlFLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pDLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ3ZCLFFBQVEsRUFBRSxHQUFHLEVBQUU7Z0JBQ2IsTUFBTSxNQUFNLEdBQWEsRUFBRSxDQUFDO2dCQUM1QixLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtvQkFDbEMsSUFBSSxJQUFJLFlBQVksZ0NBQXFCLEVBQUUsQ0FBQzt3QkFDMUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQzt3QkFDdkMsSUFBSSxZQUFZLEtBQUssV0FBVyxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQzs0QkFDdkQsTUFBTSxDQUFDLElBQUksQ0FBQywwRUFBMEUsQ0FBQyxDQUFDO3dCQUMxRixDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsT0FBTyxNQUFNLENBQUM7WUFDaEIsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBaExILDRDQWlMQzs7O0FBaExDLHlEQUF5RDtBQUN6QyxxREFBb0MsR0FBRyxzREFBc0QsQ0FBQztBQUM5RiwwQ0FBeUIsR0FBRyw2QkFBNkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IE5vZGVqc0Z1bmN0aW9uIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxhbWJkYS1ub2RlanMnO1xuaW1wb3J0IHsgQ2ZuU3Vic2NyaXB0aW9uRmlsdGVyLCBSZXRlbnRpb25EYXlzIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWxvZ3MnO1xuaW1wb3J0ICogYXMgc2VzIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZXMnO1xuaW1wb3J0ICogYXMgc25zIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zbnMnO1xuaW1wb3J0ICogYXMgc25zU3Vic2NyaXB0aW9ucyBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtc25zLXN1YnNjcmlwdGlvbnMnO1xuaW1wb3J0ICogYXMgc3NtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zc20nO1xuaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliL2NvcmUnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyB0cmltSW5kZW50IH0gZnJvbSAnLi9oZWxwZXInO1xuaW1wb3J0IHsgRGF0YWRvZ01vbml0b3IsIERhdGFkb2dNb25pdG9yUXVlcnlBbGVydFR5cGUgfSBmcm9tICcuLi9kYXRhZG9ndjInO1xuaW1wb3J0IHsgUmlvTGFuZGluZ1pvbmUgfSBmcm9tICcuLi9yaW8tbGFuZGluZy16b25lJztcblxuXG5leHBvcnQgaW50ZXJmYWNlIFNlc09ic2VydmFiaWxpdHlQcm9wcyB7XG4gIC8qKlxuICAgICAqIFRoZSBTRVMgZXZlbnRzIHRvIGxvZy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IFtFbWFpbFNlbmRpbmdFdmVudC5ERUxJVkVSWSwgRW1haWxTZW5kaW5nRXZlbnQuQk9VTkNFLCBFbWFpbFNlbmRpbmdFdmVudC5DT01QTEFJTlQsIEVtYWlsU2VuZGluZ0V2ZW50LlJFSkVDVF1cbiAgICAgKi9cbiAgcmVhZG9ubHkgbG9nZ2VkU2VzRXZlbnRzPzogc2VzLkVtYWlsU2VuZGluZ0V2ZW50W107XG59XG5cbi8qKlxuICogUmlvU2VzT2JzZXJ2YWJpbGl0eVxuICpcbiAqIFRoaXMgY29uc3RydWN0IHNldHMgdXAgb2JzZXJ2YWJpbGl0eSBmb3IgU0VTIGFzIGRlZmluZWQgYnkgW0FEUiAtIFNFUyBkb21haW4gcmVwdXRhdGlvbiBvYnNlcnZhYmlsaXR5XShodHRwczovL2NvbmZsdWVuY2UuY29sbGFib3JhdGlvbi1tYW4uY29tL2Rpc3BsYXkvTUFOL0FEUistK1NFUytkb21haW4rcmVwdXRhdGlvbitvYnNlcnZhYmlsaXR5KS5cbiAqXG4gKiAjIFdhcm5pbmdcbiAqIFRoaXMgY29uc3RydWN0IHJlc3VsdHMgaW4gbG9nZ2luZyBhbGwgc2VudCBlbWFpbHMgaW5jbHVkaW5nIHRoZSByZWNpcGllbnQgYWRkcmVzcyBpbnRvIENsb3VkV2F0Y2ggbG9ncy5cbiAqIEFzIHRoaXMgaXMgY29uc2lkZXJlZCAqKlBJSSoqLCB0aGlzIGluZm9ybWF0aW9uIE1VU1QgYmUgaGFuZGxlZCBhY2NvcmRpbmdseS5cbiAqIEluIHBhcnRpY3VsYXIsIGxvZ3MgKipNVVNUIE5PVCoqIGJlIHNlbnQgdG8gZnVydGhlciB0aGlyZCBwYXJ0eSBzZXJ2aWNlcyAoZS5nLiBEYXRhZG9nKSBhbmQgdGhlIHJldGVudGlvbiBwZXJpb2QgZm9yIGxvZ3MgKipNVVNUIE5PVCoqIGJlIGV4dGVuZGVkLlxuICpcbiAqICMgVXNhZ2VcbiAqICMjIERlZmF1bHQgQ29uZmlndXJhdGlvbiBTZXQgZm9yIElkZW50aXR5XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgcmlvU2VzT2JzZXJ2YWJpbGl0eSA9IG5ldyBSaW9TZXNPYnNlcnZhYmlsaXR5KHRoaXMsICdDb25maWd1cmF0aW9uU2V0Jywge30pXG4gKiBjb25zdCBpZGVudGl0eSA9IG5ldyBFbWFpbElkZW50aXR5KHRoaXMsICdFbWFpbElkZW50aXR5Jywge1xuICogICAgIGlkZW50aXR5OiBJZGVudGl0eS5kb21haW4oJ2V4YW1wbGUuY29tJyksXG4gKiAgICAgY29uZmlndXJhdGlvblNldDogcmlvU2VzT2JzZXJ2YWJpbGl0eS5jb25maWd1cmF0aW9uU2V0LFxuICogfSk7XG4gKiBgYGBcbiAqXG4gKiAjIyBTcGVjaWZpY2FsbHkgdXNpbmcgdGhlIGNvbmZpZ3VyYXRpb24gc2V0IHBlciByZXF1ZXN0XG4gKlxuICogVGhpcyBpcyBpZGVhbCBpZiB5b3Ugd2FudCB0byB0cnkgb3V0IHRoZSBjb25zdHJ1Y3QgZmlyc3Qgb25lIHNvbWUgc3BlY2lmaWMgZW1haWxzIChlLmcuIGR1cmluZyBpbml0aWFsIG1pZ3JhdGlvbikuXG4gKiBUaGUgY29uZmlndXJhdGlvbiBzZXQgbmFtZSBpcyBleHBvcnRlZCBhcyBhbiBTU00gcGFyYW1ldGVyIGAvcmlvL2NvbmZpZy9zZXMtb2JzZXJ2YWJpbGl0eS9jb25maWd1cmF0aW9uLXNldC1uYW1lYC5cbiAqIFRodXMsIHlvdSBjYW4gZWFzaWx5IG1ha2UgaXQgYXZhaWxhYmxlIGFzIGVudmlyb25tZW50IHZhcmlhYmxlIGluIHlvdXIgY29kZS5cbiAqXG4gKiBgYGBrb3RsaW5cbiAqIGltcG9ydCBjb20uYW1hem9uYXdzLnNlcnZpY2VzLnNpbXBsZWVtYWlsLm1vZGVsLlNlbmRFbWFpbFJlcXVlc3RcbiAqXG4gKiB2YWwgcmVxdWVzdCA9IFNlbmRFbWFpbFJlcXVlc3QoKVxuICogICAgICAgICAgICAgICAgIC53aXRoQ29uZmlndXJhdGlvblNldE5hbWUoU1NNX0NPTkZJR1VSQVRJT05fU1NNX1BBUkFNRVRFUl9WQUxVRSlcbiAqICAgICAgICAgICAgICAgICAuLi5cbiAqIGBgYFxuICpcbiAqICMjIEF1dG9tYXRlZCBldmVudCBwcm9jZXNzaW5nXG4gKlxuICogSWYgeW91IGhhdmUgc3BlY2lmaWMgbmVlZHMgZm9yIHdoaWNoIHlvdSdkIGxpa2UgdG8gcHJvY2VzcyB0aGUgU05TIGV2ZW50cyBkaXJlY3RseVxuICogKGUuZy4gYXV0b21hdGljYWxseSBjcmVhdGluZyBhIHN1cHByZXNzaW9uIGxpc3QgZnJvbSBib3VuY2VzKSwgeW91IGNhbiBzdWJzY3JpYmUgdG8gdGhlIFNOUyB0b3BpYy5cbiAqIFRvIGVuYWJsZSB0aGlzIHRoZSBTTlMgdG9waWMgQVJOIGlzIGV4cG9ydGVkIHZpYSBDbG91ZGZvcm1hdGlvbiBhcyBgUmlvU2VzT2JzZXJ2YWJpbGl0eVRvcGljQXJuYC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNlc09ic2VydmFiaWxpdHkgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvLyAhIGNoYW5naW5nIHRoZXNlIHZhbHVlcyBpcyBhIGJyZWFraW5nIGNoYW5nZSBmb3IgdXNlcnNcbiAgc3RhdGljIHJlYWRvbmx5IENPTkZJR1VSQVRJT05fU0VUX05BTUVfU1NNX1BBUkFNRVRFUiA9ICcvcmlvL2NvbmZpZy9zZXMtb2JzZXJ2YWJpbGl0eS9jb25maWd1cmF0aW9uLXNldC1uYW1lJztcbiAgc3RhdGljIHJlYWRvbmx5IFNOU19UT1BJQ19BUk5fRVhQT1JUX05BTUUgPSAnUmlvU2VzT2JzZXJ2YWJpbGl0eVRvcGljQXJuJztcbiAgcmVhZG9ubHkgc25zVG9waWM6IHNucy5Ub3BpYztcbiAgcmVhZG9ubHkgY29uZmlndXJhdGlvblNldDogc2VzLkNvbmZpZ3VyYXRpb25TZXQ7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFNlc09ic2VydmFiaWxpdHlQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgY29uc3QgYWNjb3VudElkID0gU3RhY2sub2YodGhpcykuYWNjb3VudDtcbiAgICBjb25zdCBhY2NvdW50TmFtZSA9IFJpb0xhbmRpbmdab25lLmdldEFjY291bnROYW1lUGFyYW1ldGVyKHRoaXMpO1xuXG4gICAgY29uc3QgcGFyYW1ldGVyID0gbmV3IHNzbS5TdHJpbmdQYXJhbWV0ZXIodGhpcywgJ0NvbmZpZ3VyYXRpb25TZXROYW1lJywge1xuICAgICAgcGFyYW1ldGVyTmFtZTogU2VzT2JzZXJ2YWJpbGl0eS5DT05GSUdVUkFUSU9OX1NFVF9OQU1FX1NTTV9QQVJBTUVURVIsXG4gICAgICBzdHJpbmdWYWx1ZTogJ3Jpby1zZXMtb2JzZXJ2YWJpbGl0eS1jb25maWd1cmF0aW9uLXNldCcsXG4gICAgfSk7XG5cbiAgICB0aGlzLnNuc1RvcGljID0gbmV3IHNucy5Ub3BpYyh0aGlzLCAnU25zVG9waWMnLCB7XG4gICAgICB0b3BpY05hbWU6ICdyaW8tc2VzLW9ic2VydmFiaWxpdHktdG9waWMnLFxuICAgIH0pO1xuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uU2V0ID0gbmV3IHNlcy5Db25maWd1cmF0aW9uU2V0KHRoaXMsICdDb25maWd1cmF0aW9uU2V0Jywge1xuICAgICAgY29uZmlndXJhdGlvblNldE5hbWU6IHBhcmFtZXRlci5zdHJpbmdWYWx1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMuY29uZmlndXJhdGlvblNldC5hZGRFdmVudERlc3RpbmF0aW9uKCdFdmVudERlc3RpbmF0aW9uJywge1xuICAgICAgY29uZmlndXJhdGlvblNldEV2ZW50RGVzdGluYXRpb25OYW1lOiAncmlvLXNlcy1vYnNlcnZhYmlsaXR5LWV2ZW50LWRlc3RpbmF0aW9uJyxcbiAgICAgIGRlc3RpbmF0aW9uOiBzZXMuRXZlbnREZXN0aW5hdGlvbi5zbnNUb3BpYyh0aGlzLnNuc1RvcGljKSxcbiAgICAgIGV2ZW50czogcHJvcHMubG9nZ2VkU2VzRXZlbnRzID8/IFtcbiAgICAgICAgc2VzLkVtYWlsU2VuZGluZ0V2ZW50LkRFTElWRVJZLFxuICAgICAgICBzZXMuRW1haWxTZW5kaW5nRXZlbnQuQk9VTkNFLFxuICAgICAgICBzZXMuRW1haWxTZW5kaW5nRXZlbnQuQ09NUExBSU5ULFxuICAgICAgICBzZXMuRW1haWxTZW5kaW5nRXZlbnQuUkVKRUNULFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGxvZ0Z1bmN0aW9uID0gbmV3IGxhbWJkYS5GdW5jdGlvbih0aGlzLCAnTG9nRnVuY3Rpb24nLCB7XG4gICAgICBmdW5jdGlvbk5hbWU6ICdyaW8tc2VzLW9ic2VydmFiaWxpdHktbG9nLWZ1bmN0aW9uJyxcbiAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLk5PREVKU18yMF9YLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgbG9nUmV0ZW50aW9uOiBSZXRlbnRpb25EYXlzLlRIUkVFX01PTlRIUyxcbiAgICAgIHN5c3RlbUxvZ0xldmVsVjI6IGxhbWJkYS5TeXN0ZW1Mb2dMZXZlbC5XQVJOLFxuICAgICAgbG9nZ2luZ0Zvcm1hdDogbGFtYmRhLkxvZ2dpbmdGb3JtYXQuSlNPTixcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnbGFtYmRhJyksIHtcbiAgICAgICAgZXhjbHVkZTogWycqLmpzJywgJyouZC50cyddLFxuICAgICAgfSksXG4gICAgfSk7XG4gICAgdGhpcy5lbnN1cmVOb1N1YnNjcmlwdGlvbkZpbHRlcnNPbkxhbWJkYXNMb2dHcm91cChsb2dGdW5jdGlvbik7XG5cbiAgICB0aGlzLnNuc1RvcGljLmFkZFN1YnNjcmlwdGlvbihuZXcgc25zU3Vic2NyaXB0aW9ucy5MYW1iZGFTdWJzY3JpcHRpb24obG9nRnVuY3Rpb24pKTtcblxuICAgIG5ldyBjZGsuQ2ZuT3V0cHV0KHRoaXMsICdTbnNUb3BpY0FybicsIHtcbiAgICAgIHZhbHVlOiB0aGlzLnNuc1RvcGljLnRvcGljQXJuLFxuICAgICAgZXhwb3J0TmFtZTogU2VzT2JzZXJ2YWJpbGl0eS5TTlNfVE9QSUNfQVJOX0VYUE9SVF9OQU1FLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgbm90aWZpY2F0aW9uSGFuZGxlID0gUmlvTGFuZGluZ1pvbmUuZ2V0VGVhbUFsZXJ0U2xhY2tDaGFubmVsUGFyYW1ldGVyKHRoaXMpO1xuXG4gICAgbmV3IERhdGFkb2dNb25pdG9yKHRoaXMsICdRdW90YU1vbml0b3InLCB7XG4gICAgICBuYW1lOiBgJHthY2NvdW50TmFtZX0gU0VTIHF1b3RhIGFsbW9zdCByZWFjaGVkYCxcbiAgICAgIHNlcnZpY2VOYW1lOiAnYXdzLXNlcycsXG4gICAgICBtb25pdG9yVHlwZTogRGF0YWRvZ01vbml0b3JRdWVyeUFsZXJ0VHlwZS5RVUVSWV9BTEVSVCxcbiAgICAgIHF1ZXJ5OiBgbWF4KGxhc3RfMWgpOm1heDphd3Muc2VzLnNlbnRfbGFzdF8yNF9ob3Vyc3thY2NvdW50X2lkOiR7YWNjb3VudElkfX0gLyBtYXg6YXdzLnNlcy5tYXhfMjRfaG91cl9zZW5ke2FjY291bnRfaWQ6JHthY2NvdW50SWR9fSA+IDAuOGAsXG4gICAgICBtZXNzYWdlOiB0cmltSW5kZW50YFxuICAgICAgICBZb3UgYXJlIGFsbW9zdCB1c2luZyB1cCB5b3UncmUgbWF4aW11bSBlbWFpbCBzZW5kaW5nIHF1b3RhIHBlciAyNGguIFxuICAgICAgICBFaXRoZXIgW3JlcXVlc3QgYW4gaW5jcmVhc2VdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zZXMvbGF0ZXN0L2RnL21hbmFnZS1zZW5kaW5nLXF1b3Rhcy1yZXF1ZXN0LWluY3JlYXNlLmh0bWwpIGZvciB5b3VyIHF1b3RhIGJ5IEFXUyBvciByZWR1Y2UgdGhlIGFtb3VudCBvZiBlbWFpbHMgc2VudC5cbiAgICAgICAgWW91IGNhbiBmaW5kIGxvZ3MgYWJvdXQgYWxsIG1haWxzIHNlbnQgYXQgXFxgJHtsb2dGdW5jdGlvbi5sb2dHcm91cC5sb2dHcm91cE5hbWV9XFxgLlxuICAgICAgICBcbiAgICAgICAge3sjaXNfYWxlcnR9fUBzbGFjay0ke25vdGlmaWNhdGlvbkhhbmRsZX17ey9pc19hbGVydH19XG4gICAgICAgIHt7I2lzX2FsZXJ0X3JlY292ZXJ5fX1Ac2xhY2stJHtub3RpZmljYXRpb25IYW5kbGV9e3svaXNfYWxlcnRfcmVjb3Zlcnl9fVxuICAgICAgICBgLFxuICAgICAgcHJpb3JpdHk6IDQsXG4gICAgICBvcHRpb25PdmVycmlkZXM6IHtcbiAgICAgICAgdGhyZXNob2xkczoge1xuICAgICAgICAgIGNyaXRpY2FsOiAwLjgsXG4gICAgICAgICAgd2FybmluZzogMC43LFxuICAgICAgICB9LFxuICAgICAgICBldmFsdWF0aW9uRGVsYXk6IDkwMCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBuZXcgRGF0YWRvZ01vbml0b3IodGhpcywgJ0VtYWlsUmVqZWN0ZWRNb25pdG9yJywge1xuICAgICAgbmFtZTogYCR7YWNjb3VudE5hbWV9IFNFUyBFbWFpbCBSZWplY3RlZGAsXG4gICAgICBzZXJ2aWNlTmFtZTogJ2F3cy1zZXMnLFxuICAgICAgbW9uaXRvclR5cGU6IERhdGFkb2dNb25pdG9yUXVlcnlBbGVydFR5cGUuUVVFUllfQUxFUlQsXG4gICAgICBxdWVyeTogYHN1bShsYXN0XzFoKTptYXg6YXdzLnNlcy5yZWplY3Rze2FjY291bnRfaWQ6JHthY2NvdW50SWR9fSA+IDBgLFxuICAgICAgbWVzc2FnZTogdHJpbUluZGVudGBcbiAgICAgICAgU0VTIFtyZWplY3RlZF0oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3Nlcy9sYXRlc3QvZGcvbW9uaXRvci1zZW5kaW5nLWFjdGl2aXR5Lmh0bWwpIHNlbmRpbmcgYXQgbGVhc3Qgb25lIGVtYWlsLlxuICAgICAgICBQbGVhc2UgaW52ZXN0aWdhdGUgdGhlIHJvb3QgY2FzZSwgYXMgdGhpcyBpcyBub3QgZXhwZWN0ZWQgdG8gaGFwcGVuIGluIHByb2R1Y3Rpb24gZXZlci5cbiAgICAgICAgWW91IGNhbiBmaW5kIGxvZ3MgYWJvdXQgYWxsIG1haWxzIHNlbnQgYXQgXFxgJHtsb2dGdW5jdGlvbi5sb2dHcm91cC5sb2dHcm91cE5hbWV9XFxgLlxuICAgICAgICBcbiAgICAgICAge3sjaXNfYWxlcnR9fUBzbGFjay0ke25vdGlmaWNhdGlvbkhhbmRsZX17ey9pc19hbGVydH19XG4gICAgICAgIGAsXG4gICAgICBwcmlvcml0eTogMyxcbiAgICAgIG9wdGlvbk92ZXJyaWRlczoge1xuICAgICAgICB0aHJlc2hvbGRzOiB7XG4gICAgICAgICAgY3JpdGljYWw6IDAsXG4gICAgICAgIH0sXG4gICAgICAgIGV2YWx1YXRpb25EZWxheTogOTAwLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIG5ldyBEYXRhZG9nTW9uaXRvcih0aGlzLCAnQ29tcGxhaW50UmF0ZU1vbml0b3InLCB7XG4gICAgICBuYW1lOiBgJHthY2NvdW50TmFtZX0gU0VTIHJlcHV0YXRpb24gZW5kYW5nZXJlZDogQ29tcGxhaW50IHJhdGUgSGlnaGAsXG4gICAgICBzZXJ2aWNlTmFtZTogJ2F3cy1zZXMnLFxuICAgICAgbW9uaXRvclR5cGU6IERhdGFkb2dNb25pdG9yUXVlcnlBbGVydFR5cGUuUVVFUllfQUxFUlQsXG4gICAgICBxdWVyeTogYG1heChsYXN0XzFoKTptYXg6YXdzLnNlcy5yZXB1dGF0aW9uX2NvbXBsYWludF9yYXRle2FjY291bnRfaWQ6JHthY2NvdW50SWR9IGFuZCBub3Qgc2VzOip9ID4gMC4wMDFgLFxuICAgICAgbWVzc2FnZTogdHJpbUluZGVudGBcbiAgICAgICAgV2FybmluZyBUaHJlc2hvbGQgZm9yIENvbXBsYWludCByYXRlIHt7I2lzX3dhcm5pbmd9fWFsbW9zdCB7ey9pc193YXJuaW5nfX1yZWFjaGVkIChhcyBkZWZpbmVkIGluIEFXUykuXG4gICAgICAgIFxuICAgICAgICBQbGVhc2UgcmVkdWNlIHRoZSBudW1iZXIgb2YgY29tcGxhaW50cyByZWNlaXZlZCBmb3IgRS1tYWlscyBzZW50IGJ5IHlvdXIgQWNjb3VudC5cbiAgICAgICAgSWYgdGhpcyBtZXRyaWMgcmVhY2hlcyBcXGAwLjUlXFxgIHRoZSBlbWFpbCBzZW5kaW5nIGNhcGFiaWxpdHkgb2YgeW91ciBhY2NvdW50IHdpbGwgYmUgZGlzYWJsZWQgYnkgQVdTLlxuICAgICAgICBZb3UgY2FuIGZpbmQgbG9ncyBhYm91dCBhbGwgbWFpbHMgc2VudCBhdCBcXGAke2xvZ0Z1bmN0aW9uLmxvZ0dyb3VwLmxvZ0dyb3VwTmFtZX1cXGAuXG4gICAgICAgIFNlZSBbQURSIC0gU0VTIGRvbWFpbiByZXB1dGF0aW9uIG9ic2VydmFiaWxpdHldKGh0dHBzOi8vY29uZmx1ZW5jZS5jb2xsYWJvcmF0aW9uLW1hbi5jb20vZGlzcGxheS9NQU4vQURSKy0rU0VTK2RvbWFpbityZXB1dGF0aW9uK29ic2VydmFiaWxpdHkpLlxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIHt7I2lzX2FsZXJ0fX1Ac2xhY2stJHtub3RpZmljYXRpb25IYW5kbGV9e3svaXNfYWxlcnR9fVxuICAgICAgICB7eyNpc19hbGVydF9yZWNvdmVyeX19QHNsYWNrLSR7bm90aWZpY2F0aW9uSGFuZGxlfXt7L2lzX2FsZXJ0X3JlY292ZXJ5fX1cbiAgICAgICAgYCxcbiAgICAgIHByaW9yaXR5OiAyLFxuICAgICAgb3B0aW9uT3ZlcnJpZGVzOiB7XG4gICAgICAgIHRocmVzaG9sZHM6IHtcbiAgICAgICAgICBjcml0aWNhbDogMC4wMDEsXG4gICAgICAgICAgd2FybmluZzogMC4wMDA4LFxuICAgICAgICB9LFxuICAgICAgICBldmFsdWF0aW9uRGVsYXk6IDkwMCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBuZXcgRGF0YWRvZ01vbml0b3IodGhpcywgJ0JvdW5jZVJhdGVNb25pdG9yJywge1xuICAgICAgbmFtZTogYCR7YWNjb3VudE5hbWV9IFNFUyByZXB1dGF0aW9uIGVuZGFuZ2VyZWQ6IEJvdW5jZSBSYXRlIEhpZ2hgLFxuICAgICAgc2VydmljZU5hbWU6ICdhd3Mtc2VzJyxcbiAgICAgIG1vbml0b3JUeXBlOiBEYXRhZG9nTW9uaXRvclF1ZXJ5QWxlcnRUeXBlLlFVRVJZX0FMRVJULFxuICAgICAgcXVlcnk6IGBtYXgobGFzdF8xaCk6bWF4OmF3cy5zZXMucmVwdXRhdGlvbl9ib3VuY2VfcmF0ZXthY2NvdW50X2lkOiR7YWNjb3VudElkfSBhbmQgbm90IHNlczoqfSA+IDAuMDVgLFxuICAgICAgbWVzc2FnZTogdHJpbUluZGVudGBcbiAgICAgICAgV2FybmluZyBUaHJlc2hvbGQgZm9yIEJvdW5jZSByYXRlIHt7I2lzX3dhcm5pbmd9fWFsbW9zdCB7ey9pc193YXJuaW5nfX1yZWFjaGVkIChhcyBkZWZpbmVkIGluIEFXUykuXG4gICAgICAgIFxuICAgICAgICBQbGVhc2UgcmVkdWNlIHRoZSBudW1iZXIgb2YgYm91bmNlcyBmb3IgRS1tYWlscyBzZW50IGJ5IHlvdXIgQWNjb3VudC5cbiAgICAgICAgSWYgdGhpcyBtZXRyaWMgcmVhY2hlcyBcXGAxMCVcXGAgdGhlIGVtYWlsIHNlbmRpbmcgY2FwYWJpbGl0eSBvZiB5b3VyIGFjY291bnQgd2lsbCBiZSBkaXNhYmxlZCBieSBBV1MuXG4gICAgICAgIFlvdSBjYW4gZmluZCBsb2dzIGFib3V0IGFsbCBtYWlscyBzZW50IGF0IFxcYCR7bG9nRnVuY3Rpb24ubG9nR3JvdXAubG9nR3JvdXBOYW1lfVxcYC5cbiAgICAgICAgU2VlIFtBRFIgLSBTRVMgZG9tYWluIHJlcHV0YXRpb24gb2JzZXJ2YWJpbGl0eV0oaHR0cHM6Ly9jb25mbHVlbmNlLmNvbGxhYm9yYXRpb24tbWFuLmNvbS9kaXNwbGF5L01BTi9BRFIrLStTRVMrZG9tYWluK3JlcHV0YXRpb24rb2JzZXJ2YWJpbGl0eSkuXG4gICAgICAgIFxuICAgICAgICBcbiAgICAgICAge3sjaXNfYWxlcnR9fUBzbGFjay0ke25vdGlmaWNhdGlvbkhhbmRsZX17ey9pc19hbGVydH19XG4gICAgICAgIHt7I2lzX2FsZXJ0X3JlY292ZXJ5fX1Ac2xhY2stJHtub3RpZmljYXRpb25IYW5kbGV9e3svaXNfYWxlcnRfcmVjb3Zlcnl9fVxuICAgICAgICBgLFxuICAgICAgcHJpb3JpdHk6IDIsXG4gICAgICBvcHRpb25PdmVycmlkZXM6IHtcbiAgICAgICAgdGhyZXNob2xkczoge1xuICAgICAgICAgIGNyaXRpY2FsOiAwLjA1LFxuICAgICAgICAgIHdhcm5pbmc6IDAuMDQsXG4gICAgICAgIH0sXG4gICAgICAgIGV2YWx1YXRpb25EZWxheTogOTAwLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGVuc3VyZXMgdGhhdCBubyBQSUkgaXMgbGVha2VkIHRvIERhdGFkb2cgYnkgYWRkaW5nIGEgc3Vic2NyaXB0aW9uIGZpbHRlciB0byB0aGUgbG9nIGdyb3VwIG9mIHRoZSBsYW1iZGEuXG4gICAqL1xuICBwcml2YXRlIGVuc3VyZU5vU3Vic2NyaXB0aW9uRmlsdGVyc09uTGFtYmRhc0xvZ0dyb3VwKGxvZ0Z1bmN0aW9uOiBOb2RlanNGdW5jdGlvbikge1xuICAgIGNvbnN0IHN0YWNrID0gY2RrLlN0YWNrLm9mKHRoaXMpO1xuICAgIHN0YWNrLm5vZGUuYWRkVmFsaWRhdGlvbih7XG4gICAgICB2YWxpZGF0ZTogKCkgPT4ge1xuICAgICAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIHN0YWNrLm5vZGUuZmluZEFsbCgpLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBDZm5TdWJzY3JpcHRpb25GaWx0ZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGxvZ0dyb3VwTmFtZSA9IG5vZGUubG9nR3JvdXBOYW1lO1xuICAgICAgICAgICAgaWYgKGxvZ0dyb3VwTmFtZSA9PT0gbG9nRnVuY3Rpb24ubG9nR3JvdXAubG9nR3JvdXBOYW1lKSB7XG4gICAgICAgICAgICAgIGVycm9ycy5wdXNoKCdTdWJzY3JpcHRpb24gZmlsdGVycyBhcmUgbm90IGFsbG93ZWQgc2VzLW9ic2VydmFiaWxpdHkgbGFtYmRhcyBsb2cgZ3JvdXAnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZXJyb3JzO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufSJdfQ==
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "main": "lib/index.js",
17
17
  "license": "Apache-2.0",
18
- "version": "6.15.0",
18
+ "version": "6.16.0",
19
19
  "types": "lib/index.d.ts",
20
20
  "stability": "stable",
21
21
  "exports": {
package/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "6.15.0"
2
+ "version": "6.16.0"
3
3
  }