@@ -10,22 +10,23 @@ import * as snsSubscriptions from '@aws-cdk/aws-sns-subscriptions';
1010import * as sqs from '@aws-cdk/aws-sqs' ;
1111import * as path from 'path' ;
1212import { DispatcherConfig } from './maildog-stack.dispatcher' ;
13- interface MailDogForwardingRule {
14- description ?: string ;
13+
14+ interface MailDogAliasRule {
15+ description : string ;
1516 to : string [ ] ;
1617}
1718
1819interface MailDogDomainRule {
19- enabled ? : boolean ;
20- fromEmail ? : string ;
21- scanEnabled ? : boolean ;
22- tlsEnforced ? : boolean ;
23- fallbackEmails ? : string [ ] ;
24- alias ? : Record < string , MailDogForwardingRule > ;
20+ enabled : boolean ;
21+ fromEmail : string ;
22+ scanEnabled : boolean ;
23+ tlsEnforced : boolean ;
24+ fallbackEmails : string [ ] ;
25+ alias : Record < string , Partial < MailDogAliasRule > > ;
2526}
2627
2728interface MailDogConfig {
28- domains : Record < string , MailDogDomainRule > ;
29+ domains : Record < string , Partial < MailDogDomainRule > > ;
2930}
3031
3132interface MailDogStackProps extends cdk . StackProps {
@@ -37,7 +38,19 @@ export class MailDogStack extends cdk.Stack {
3738 super ( scope , id , props ) ;
3839
3940 // The code that defines your stack goes here
40- const { domains } = props . config ;
41+ const domainRuleEntries = Object . entries ( props . config . domains ) . map <
42+ [ string , MailDogDomainRule ]
43+ > ( ( [ domain , rule ] ) => [
44+ domain ,
45+ {
46+ enabled : rule . enabled ?? true ,
47+ fromEmail : rule . fromEmail ?? 'noreply' ,
48+ scanEnabled : rule . scanEnabled ?? true ,
49+ tlsEnforced : rule . tlsEnforced ?? false ,
50+ fallbackEmails : rule . fallbackEmails ?? [ ] ,
51+ alias : rule . alias ?? { } ,
52+ } ,
53+ ] ) ;
4154 const bucket = new s3 . Bucket ( this , 'Bucket' , {
4255 lifecycleRules : [
4356 {
@@ -75,24 +88,28 @@ export class MailDogStack extends cdk.Stack {
7588 sourceMap : false ,
7689 define : {
7790 'process.env.CONFIG_PER_KEY_PREFIX' : JSON . stringify (
78- Object . entries ( domains ) . reduce ( ( result , [ domain , rule ] ) => {
79- result [ `${ domain } /` ] = {
80- fromEmail : `${ rule . fromEmail ?? 'noreply' } @${ domain } ` ,
81- forwardMapping : Object . entries ( rule . alias ?? { } )
82- . concat (
83- rule . fallbackEmails
84- ? [ [ '' , { to : rule . fallbackEmails } ] ]
85- : [ ] ,
86- )
87- . reduce ( ( mapping , [ prefix , entry ] ) => {
88- mapping [ `${ prefix } @${ domain } ` ] = entry . to ;
89-
90- return mapping ;
91- } , { } as Record < string , string [ ] > ) ,
92- } ;
93-
94- return result ;
95- } , { } as Record < string , DispatcherConfig > ) ,
91+ Object . fromEntries (
92+ domainRuleEntries . map < [ string , DispatcherConfig ] > (
93+ ( [ domain , rule ] ) => [
94+ `${ domain } /` ,
95+ {
96+ fromEmail : `${ rule . fromEmail } @${ domain } ` ,
97+ forwardMapping : Object . fromEntries (
98+ Object . entries ( rule . alias )
99+ . concat (
100+ rule . fallbackEmails . length > 0
101+ ? [ [ '' , { to : rule . fallbackEmails } ] ]
102+ : [ ] ,
103+ )
104+ . map ( ( [ alias , entry ] ) => [
105+ `${ alias } @${ domain } ` ,
106+ entry . to ?? [ ] ,
107+ ] ) ,
108+ ) ,
109+ } ,
110+ ] ,
111+ ) ,
112+ ) ,
96113 ) ,
97114 } ,
98115 } ,
@@ -146,13 +163,26 @@ export class MailDogStack extends cdk.Stack {
146163 const ruleset = new ses . ReceiptRuleSet ( this , 'ReceiptRuleSet' , {
147164 receiptRuleSetName : `${ props . stackName ?? 'MailDog' } -ReceiptRuleSet` ,
148165 dropSpam : false , // maybe a bug, it is not added as first rule
149- rules : Object . entries ( domains ) . flatMap ( ( [ domain , rule ] ) => {
166+ rules : domainRuleEntries . flatMap ( ( [ domain , rule ] ) => {
150167 const maxRecipientsPerRule = 100 ;
151- const recipients = rule . fallbackEmails
152- ? [ domain ]
153- : Object . keys ( rule . alias ?? { } ) . map (
154- ( prefix ) => `${ prefix } @${ domain } ` ,
155- ) ;
168+ const recipients =
169+ rule . fallbackEmails . length > 0
170+ ? [ domain ]
171+ : Object . entries ( rule . alias )
172+ . filter ( ( [ _ , entry ] ) => {
173+ if (
174+ typeof entry . to === 'undefined' ||
175+ entry . to . length === 0
176+ ) {
177+ console . warn (
178+ '[maildog] Alias with no forwarding email addresses found; It will be disabled if no fallback emails are set' ,
179+ ) ;
180+ return false ;
181+ }
182+
183+ return true ;
184+ } )
185+ . map ( ( [ alias ] ) => `${ alias } @${ domain } ` ) ;
156186 const rules = recipients
157187 . reduce ( ( chunks , _ , i , list ) => {
158188 if ( i % maxRecipientsPerRule === 0 ) {
0 commit comments