diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/asset.19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/asset.19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec/index.js new file mode 100644 index 0000000000000..82ba3b4bc761e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/asset.19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec/index.js @@ -0,0 +1 @@ +"use strict";var o=Object.defineProperty;var n=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var p=(i,t)=>{for(var e in t)o(i,e,{get:t[e],enumerable:!0})},l=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of c(t))!a.call(i,s)&&s!==e&&o(i,s,{get:()=>t[s],enumerable:!(r=n(t,s))||r.enumerable});return i};var d=i=>l(o({},"__esModule",{value:!0}),i);var S={};p(S,{handler:()=>u});module.exports=d(S);async function u(i){console.log("Spam filter");let t=i.Records[0].ses;return console.log("SES Notification: %j",t),t.receipt.spfVerdict.status==="FAIL"||t.receipt.dkimVerdict.status==="FAIL"||t.receipt.spamVerdict.status==="FAIL"||t.receipt.virusVerdict.status==="FAIL"?(console.log("Dropping spam"),{disposition:"STOP_RULE_SET"}):null}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.assets.json index 35cbc31e26575..78acf6dcc87d2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.assets.json @@ -1,7 +1,20 @@ { "version": "36.0.0", "files": { - "558c1448bff6417f14bd77ab3ed5fda1c051566e3e95f20865a1b5d5ac53d66c": { + "19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec": { + "source": { + "path": "asset.19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "e6588125503215c64027666d36868f7ca8e305ebf39630158558d6379dcc5fcb": { "source": { "path": "aws-cdk-ses-receipt.template.json", "packaging": "file" @@ -9,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "558c1448bff6417f14bd77ab3ed5fda1c051566e3e95f20865a1b5d5ac53d66c.json", + "objectKey": "e6588125503215c64027666d36868f7ca8e305ebf39630158558d6379dcc5fcb.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.template.json index 5363ad5b9d605..9c28697b45e93 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/aws-cdk-ses-receipt.template.json @@ -105,7 +105,11 @@ { "Ref": "AWS::AccountId" }, - ":receipt-rule-set/INBOUND_MAIL:receipt-rule/", + ":receipt-rule-set/", + { + "Ref": "RuleSetE30C6C48" + }, + ":receipt-rule/", { "Ref": "RuleSetFirstRule0A27C8CC" } @@ -195,11 +199,50 @@ "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, + "RuleSetE30C6C48": { + "Type": "AWS::SES::ReceiptRuleSet" + }, + "RuleSetDropSpamRule5809F51B": { + "Type": "AWS::SES::ReceiptRule", + "Properties": { + "Rule": { + "Actions": [ + { + "LambdaAction": { + "FunctionArn": { + "Fn::GetAtt": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15", + "Arn" + ] + }, + "InvocationType": "RequestResponse" + } + } + ], + "Enabled": true, + "ScanEnabled": true + }, + "RuleSetName": { + "Ref": "RuleSetE30C6C48" + } + } + }, "RuleSetFirstRule0A27C8CC": { "Type": "AWS::SES::ReceiptRule", "Properties": { + "After": { + "Ref": "RuleSetDropSpamRule5809F51B" + }, "Rule": { "Actions": [ + { + "WorkmailAction": { + "OrganizationArn": "arn:aws:workmail:us-east-1:339712719728:organization/m-5ea60ed9e37442c388898996f05c17ac", + "TopicArn": { + "Ref": "TopicBFC7AF6E" + } + } + }, { "AddHeaderAction": { "HeaderName": "X-My-Header", @@ -265,7 +308,9 @@ "ScanEnabled": true, "TlsPolicy": "Require" }, - "RuleSetName": "INBOUND_MAIL" + "RuleSetName": { + "Ref": "RuleSetE30C6C48" + } }, "DependsOn": [ "FunctionAllowSes1829904A" @@ -290,7 +335,78 @@ ], "Enabled": true }, - "RuleSetName": "INBOUND_MAIL" + "RuleSetName": { + "Ref": "RuleSetE30C6C48" + } + } + }, + "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec.zip" + }, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4", + "Arn" + ] + }, + "Runtime": "nodejs18.x" + }, + "DependsOn": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4" + ] + }, + "SingletonLambda224e77f9a32e4b4dac32983477abba16AllowSesB42DF904": { + "Type": "AWS::Lambda::Permission", + "Properties": { + "Action": "lambda:InvokeFunction", + "FunctionName": { + "Fn::GetAtt": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15", + "Arn" + ] + }, + "Principal": "ses.amazonaws.com", + "SourceAccount": { + "Ref": "AWS::AccountId" + } } }, "NotificationQueue36610CC1": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/manifest.json index 6f9536b92e4c3..5d007e6251fac 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/558c1448bff6417f14bd77ab3ed5fda1c051566e3e95f20865a1b5d5ac53d66c.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e6588125503215c64027666d36868f7ca8e305ebf39630158558d6379dcc5fcb.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -76,6 +76,18 @@ "data": "Key961B73FD" } ], + "/aws-cdk-ses-receipt/RuleSet/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RuleSetE30C6C48" + } + ], + "/aws-cdk-ses-receipt/RuleSet/DropSpam/Rule/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "RuleSetDropSpamRule5809F51B" + } + ], "/aws-cdk-ses-receipt/RuleSet/FirstRule/Resource": [ { "type": "aws:cdk:logicalId", @@ -94,79 +106,52 @@ ] } ], - "/aws-cdk-ses-receipt/NotificationQueue/Resource": [ + "/aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/ServiceRole/Resource": [ { "type": "aws:cdk:logicalId", - "data": "NotificationQueue36610CC1" + "data": "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4" } ], - "/aws-cdk-ses-receipt/NotificationQueue/Policy/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "NotificationQueuePolicyCC060EA6" - } - ], - "/aws-cdk-ses-receipt/NotificationQueue/awscdksesreceiptTopicE9CA2388/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "NotificationQueueawscdksesreceiptTopicE9CA2388E8E96C33" - } - ], - "/aws-cdk-ses-receipt/BootstrapVersion": [ + "/aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/Resource": [ { "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" + "data": "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15" } ], - "/aws-cdk-ses-receipt/CheckBootstrapVersion": [ + "/aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/AllowSes": [ { "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" + "data": "SingletonLambda224e77f9a32e4b4dac32983477abba16AllowSesB42DF904" } ], - "RuleSetE30C6C48": [ + "/aws-cdk-ses-receipt/NotificationQueue/Resource": [ { "type": "aws:cdk:logicalId", - "data": "RuleSetE30C6C48", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "NotificationQueue36610CC1" } ], - "RuleSetDropSpamRule5809F51B": [ + "/aws-cdk-ses-receipt/NotificationQueue/Policy/Resource": [ { "type": "aws:cdk:logicalId", - "data": "RuleSetDropSpamRule5809F51B", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "NotificationQueuePolicyCC060EA6" } ], - "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4": [ + "/aws-cdk-ses-receipt/NotificationQueue/awscdksesreceiptTopicE9CA2388/Resource": [ { "type": "aws:cdk:logicalId", - "data": "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "NotificationQueueawscdksesreceiptTopicE9CA2388E8E96C33" } ], - "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15": [ + "/aws-cdk-ses-receipt/BootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "BootstrapVersion" } ], - "SingletonLambda224e77f9a32e4b4dac32983477abba16AllowSesB42DF904": [ + "/aws-cdk-ses-receipt/CheckBootstrapVersion": [ { "type": "aws:cdk:logicalId", - "data": "SingletonLambda224e77f9a32e4b4dac32983477abba16AllowSesB42DF904", - "trace": [ - "!!DESTRUCTIVE_CHANGES: WILL_DESTROY" - ] + "data": "CheckBootstrapVersion" } ] }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/tree.json index 7eadd11a1c964..4976261e07769 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.js.snapshot/tree.json @@ -199,7 +199,11 @@ { "Ref": "AWS::AccountId" }, - ":receipt-rule-set/INBOUND_MAIL:receipt-rule/", + ":receipt-rule-set/", + { + "Ref": "RuleSetE30C6C48" + }, + ":receipt-rule/", { "Ref": "RuleSetFirstRule0A27C8CC" } @@ -326,6 +330,79 @@ "id": "RuleSet", "path": "aws-cdk-ses-receipt/RuleSet", "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-ses-receipt/RuleSet/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SES::ReceiptRuleSet", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ses.CfnReceiptRuleSet", + "version": "0.0.0" + } + }, + "DropSpam": { + "id": "DropSpam", + "path": "aws-cdk-ses-receipt/RuleSet/DropSpam", + "children": { + "Function": { + "id": "Function", + "path": "aws-cdk-ses-receipt/RuleSet/DropSpam/Function", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.SingletonFunction", + "version": "0.0.0" + } + }, + "Rule": { + "id": "Rule", + "path": "aws-cdk-ses-receipt/RuleSet/DropSpam/Rule", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-ses-receipt/RuleSet/DropSpam/Rule/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SES::ReceiptRule", + "aws:cdk:cloudformation:props": { + "rule": { + "actions": [ + { + "lambdaAction": { + "functionArn": { + "Fn::GetAtt": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15", + "Arn" + ] + }, + "invocationType": "RequestResponse" + } + } + ], + "enabled": true, + "scanEnabled": true + }, + "ruleSetName": { + "Ref": "RuleSetE30C6C48" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ses.CfnReceiptRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ses.ReceiptRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ses.DropSpamReceiptRule", + "version": "0.0.0" + } + }, "FirstRule": { "id": "FirstRule", "path": "aws-cdk-ses-receipt/RuleSet/FirstRule", @@ -336,8 +413,19 @@ "attributes": { "aws:cdk:cloudformation:type": "AWS::SES::ReceiptRule", "aws:cdk:cloudformation:props": { + "after": { + "Ref": "RuleSetDropSpamRule5809F51B" + }, "rule": { "actions": [ + { + "workmailAction": { + "organizationArn": "arn:aws:workmail:us-east-1:339712719728:organization/m-5ea60ed9e37442c388898996f05c17ac", + "topicArn": { + "Ref": "TopicBFC7AF6E" + } + } + }, { "addHeaderAction": { "headerName": "X-My-Header", @@ -403,7 +491,9 @@ "scanEnabled": true, "tlsPolicy": "Require" }, - "ruleSetName": "INBOUND_MAIL" + "ruleSetName": { + "Ref": "RuleSetE30C6C48" + } } }, "constructInfo": { @@ -443,7 +533,9 @@ ], "enabled": true }, - "ruleSetName": "INBOUND_MAIL" + "ruleSetName": { + "Ref": "RuleSetE30C6C48" + } } }, "constructInfo": { @@ -459,7 +551,151 @@ } }, "constructInfo": { - "fqn": "aws-cdk-lib.Resource", + "fqn": "aws-cdk-lib.aws_ses.ReceiptRuleSet", + "version": "0.0.0" + } + }, + "SingletonLambda224e77f9a32e4b4dac32983477abba16": { + "id": "SingletonLambda224e77f9a32e4b4dac32983477abba16", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/Code/Stage", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/Code/AssetBucket", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "19044c50ec489a0413f51a8e60d6272e5746e9b5a0356ed15c12de97c3ca93ec.zip" + }, + "handler": "index.handler", + "role": { + "Fn::GetAtt": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba16ServiceRole3037F5B4", + "Arn" + ] + }, + "runtime": "nodejs18.x" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnFunction", + "version": "0.0.0" + } + }, + "AllowSes": { + "id": "AllowSes", + "path": "aws-cdk-ses-receipt/SingletonLambda224e77f9a32e4b4dac32983477abba16/AllowSes", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Permission", + "aws:cdk:cloudformation:props": { + "action": "lambda:InvokeFunction", + "functionName": { + "Fn::GetAtt": [ + "SingletonLambda224e77f9a32e4b4dac32983477abba164533EA15", + "Arn" + ] + }, + "principal": "ses.amazonaws.com", + "sourceAccount": { + "Ref": "AWS::AccountId" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.CfnPermission", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_lambda.Function", "version": "0.0.0" } }, diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.ts index 93f0f4487b65f..81f86b64ca74d 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-ses-actions/test/integ.actions.ts @@ -13,14 +13,21 @@ import { STANDARD_NODEJS_RUNTIME } from '../../config'; * 1. Create a free Workmail test domain (https://us-east-1.console.aws.amazon.com/workmail/v2/home?region=us-east-1#/organizations/create) * - It should automatically be added to your list of verified SES domains, no need to exit the SES sandbox * 2. Add a new user email address in the Workmail console - * 3. Update the TEST_EMAIL constant with the email address of the user you created - * 4. Deploy the stack with --no-clean, and send an email to the email address you created - * 5. Check the following: + * 3. Remove the automatically created INBOUND_MAIL rule set (https://us-east-1.console.aws.amazon.com/ses/home?region=us-east-1#/email-receiving/INBOUND_MAIL) + * 4. Update the TEST_* constants declared below with the organization details and email address you created + * 5. Deploy the stack with --no-clean + * 6. Set the rule set as active in the SES web console (https://us-east-1.console.aws.amazon.com/ses/home?region=us-east-1#/email-receiving) + * 7. Send an email to the email address you created + * 8. Check the following: + * - The email should be in the WorkMail user inbox * - The email should be saved to the S3 bucket - * - The SQS queue should receive receipt notifications + * - The SQS queue should receive 6 receipt notifications + * - A bounce notification should be sent back to the sender mailbox */ -const TEST_EMAIL = 'test@cdk-test-123.awsapps.com'; +const TEST_WORKMAIL_DOMAIN = 'cdk-test-123.awsapps.com'; +const TEST_ORGANIZATION_ARN = 'arn:aws:workmail:us-east-1:339712719728:organization/m-5ea60ed9e37442c388898996f05c17ac'; +const TEST_EMAIL = `test@${TEST_WORKMAIL_DOMAIN}`; const app = new cdk.App(); @@ -38,15 +45,14 @@ const bucket = new s3.Bucket(stack, 'Bucket'); const kmsKey = new kms.Key(stack, 'Key'); -const ruleSet = ses.ReceiptRuleSet.fromReceiptRuleSetName( - stack, - 'RuleSet', - // Default WorkMail rule set - 'INBOUND_MAIL', -); +const ruleSet = new ses.ReceiptRuleSet(stack, 'RuleSet', { dropSpam: true }); const firstRule = ruleSet.addRule('FirstRule', { actions: [ + new actions.WorkMail({ + organizationArn: TEST_ORGANIZATION_ARN, + topic, + }), new actions.AddHeader({ name: 'X-My-Header', value: 'value', diff --git a/packages/aws-cdk-lib/aws-ses-actions/README.md b/packages/aws-cdk-lib/aws-ses-actions/README.md index c1c8de4a2f529..5d32cd048e8e0 100644 --- a/packages/aws-cdk-lib/aws-ses-actions/README.md +++ b/packages/aws-cdk-lib/aws-ses-actions/README.md @@ -11,6 +11,7 @@ Currently supported are: * [Lambda](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-lambda.html) * [S3](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-s3.html) * [SNS](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-sns.html) +* [WorkMail](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-workmail.html) * [Stop](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-stop.html) See the README of `aws-cdk-lib/aws-ses` for more information. diff --git a/packages/aws-cdk-lib/aws-ses-actions/lib/index.ts b/packages/aws-cdk-lib/aws-ses-actions/lib/index.ts index 17875248691c9..1b0ce18683730 100644 --- a/packages/aws-cdk-lib/aws-ses-actions/lib/index.ts +++ b/packages/aws-cdk-lib/aws-ses-actions/lib/index.ts @@ -4,3 +4,4 @@ export * from './lambda'; export * from './s3'; export * from './sns'; export * from './stop'; +export * from './workmail'; diff --git a/packages/aws-cdk-lib/aws-ses-actions/lib/workmail.ts b/packages/aws-cdk-lib/aws-ses-actions/lib/workmail.ts new file mode 100644 index 0000000000000..31aa392e24450 --- /dev/null +++ b/packages/aws-cdk-lib/aws-ses-actions/lib/workmail.ts @@ -0,0 +1,48 @@ +import * as ses from '../../aws-ses'; +import * as sns from '../../aws-sns'; + +/** + * Construction properties for a WorkMail action. + */ +export interface WorkMailProps { + /** + * The WorkMail organization ARN. + * + * Amazon WorkMail organization ARNs are in the form + * `arn:aws:workmail:region:account_ID:organization/organization_ID` + * + * @example 'arn:aws:workmail:us-east-1:123456789012:organization/m-68755160c4cb4e29a2b2f8fb58f359d7' + */ + readonly organizationArn: string; + + /** + * The SNS topic to notify when the WorkMail action is taken. + * + * @default - no topic will be attached to the action + */ + readonly topic?: sns.ITopic; +} + +/** + * Integrates an Amazon WorkMail action into a receipt rule set, + * and optionally publishes a notification to Amazon SNS. + * + * Beware that WorkMail should already set up an active `INBOUND_MAIL` rule set + * that includes a WorkMail rule action for this exact purpose. + * This action should be used to customize the behavior of replacement rule set. + * + * @see https://docs.aws.amazon.com/ses/latest/dg/receiving-email-action-workmail.html + */ +export class WorkMail implements ses.IReceiptRuleAction { + constructor(private readonly props: WorkMailProps) { + } + + public bind(_rule: ses.IReceiptRule): ses.ReceiptRuleActionConfig { + return { + workmailAction: { + organizationArn: this.props.organizationArn, + topicArn: this.props.topic?.topicArn, + }, + }; + } +} diff --git a/packages/aws-cdk-lib/aws-ses-actions/test/actions.test.ts b/packages/aws-cdk-lib/aws-ses-actions/test/actions.test.ts index d9b7c143f70ac..dc2fa57d124f3 100644 --- a/packages/aws-cdk-lib/aws-ses-actions/test/actions.test.ts +++ b/packages/aws-cdk-lib/aws-ses-actions/test/actions.test.ts @@ -308,3 +308,26 @@ test('add stop action', () => { }, }); }); + +test('add workmail action', () => { + rule.addAction(new actions.WorkMail({ + organizationArn: 'arn:aws:workmail:us-east-1:123456789012:organization/m-organizationid', + topic, + })); + + Template.fromStack(stack).hasResourceProperties('AWS::SES::ReceiptRule', { + Rule: { + Actions: [ + { + WorkmailAction: { + OrganizationArn: 'arn:aws:workmail:us-east-1:123456789012:organization/m-organizationid', + TopicArn: { + Ref: 'TopicBFC7AF6E', + }, + }, + }, + ], + Enabled: true, + }, + }); +});