Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for custom Lambda function email senders in Auth construct #2087

Merged
merged 124 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
124 commits
Select commit Hold shift + click to select a range
743354e
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
ab7f76f
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
7c55adc
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
36727ba
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
aa2f7d9
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
0302517
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
0adf873
chore: add changeset
vigy02 Sep 19, 2024
a5b5d3c
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
753701a
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
955cecc
fix: clearing the .amplify/generated/env/ before synthesis
vigy02 Sep 19, 2024
2a2b188
Merge branch 'main' of https://github.com/vigy02/amplify-backend
vigy02 Sep 19, 2024
fc0be7e
fix: Clear generated env directory before shim generation
vigy02 Sep 20, 2024
6c916e0
fix: Clear generated env directory before shim generation
vigy02 Sep 20, 2024
cab3f1a
fix: Clear generated env directory before shim generation
vigy02 Sep 20, 2024
954e1c0
fix: Clear generated env directory before shim generation
vigy02 Sep 20, 2024
d9212d8
chore: add changeset
vigy02 Sep 20, 2024
c09e1ee
fix: Clear generated env directory before shim generation
vigy02 Sep 20, 2024
05e1fd5
fix: Clear generated env directory before shim generation
vigy02 Sep 20, 2024
7714224
Merge branch 'issue-dir-clean'
vigy02 Sep 20, 2024
91faece
Merge branch 'aws-amplify:main' into main
vigy02 Sep 20, 2024
5977d8f
Merge branch 'aws-amplify:main' into main
vigy02 Sep 23, 2024
4c6616b
Merge branch 'main' of github.com:vigy02/amplify-backend
vigy02 Sep 25, 2024
cb908ed
feat: adding custom lambda function trigger for email
vigy02 Oct 2, 2024
dbbb9b8
feat: adding custom lambda function trigger for email
vigy02 Oct 2, 2024
2f7e6e8
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
f981039
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
e5ada8b
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
2cc04a9
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
1794ad0
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
e6c6730
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
4471aec
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
2b17234
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
61e10d8
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
fdbc617
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
5806d7f
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
e1ca822
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
f012a51
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
cb8f50d
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
6e7ab39
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
8fdd181
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
2187829
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
c86be92
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
c5f6ad4
feat: adding custom lambda function trigger for email
vigy02 Oct 4, 2024
f8f1c6a
Merge branch 'main' of github.com:vigy02/amplify-backend
vigy02 Oct 7, 2024
b8bb5a2
Merge branch 'aws-amplify:main' into main
vigy02 Oct 7, 2024
8e3f47d
cleanup
vigy02 Oct 7, 2024
b291851
chore: removed unwanted changesets
vigy02 Oct 7, 2024
206ec4e
chore: preparing for merge
vigy02 Oct 7, 2024
ad776e7
chore: preparing for merge
vigy02 Oct 7, 2024
eb24c3e
chore: preparing for merge
vigy02 Oct 7, 2024
3283dfd
feat: added a functionality to translate auth-props for custom fucnti…
vigy02 Oct 9, 2024
eac8809
chore: added changeset
vigy02 Oct 9, 2024
d9d7cae
chore: added new API
vigy02 Oct 9, 2024
872f88b
feat: added a functionality to translate auth-props for custom fucnti…
vigy02 Oct 9, 2024
afe3d89
feat: added a test case to cover custom function in backend-auth
vigy02 Oct 9, 2024
c829edf
Merge branch 'aws-amplify:main' into main
vigy02 Oct 9, 2024
fbfc8fe
feat: added a test case to cover custom function in backend-auth
vigy02 Oct 9, 2024
a4d17e8
feat: added a test case to cover custom function in backend-auth
vigy02 Oct 9, 2024
699986b
feat: added a test case to cover custom function in backend-auth
vigy02 Oct 9, 2024
b22de18
feat: added a test case to cover custom function in backend-auth
vigy02 Oct 9, 2024
f43703d
feat: narrowed down the permission by updating the conditions
vigy02 Oct 9, 2024
d1ff4aa
Refactored the code
vigy02 Oct 10, 2024
3262d3f
Merge branch 'aws-amplify:main' into main
vigy02 Oct 10, 2024
15b2fbf
Refactored the code
vigy02 Oct 10, 2024
5e02689
added a test case for checking lambdaTrigger={} empty condition
vigy02 Oct 10, 2024
606570a
added a test case for checking lambdaTrigger={} empty condition
vigy02 Oct 10, 2024
1cce05c
Merge branch 'main' into e2e/vigy/feature/custom-email-function
vigy02 Oct 10, 2024
7a5629b
Merge Branch
vigy02 Oct 10, 2024
16e07ed
Merge branch 'main' into e2e/vigy/feature/custom-email-function
vigy02 Oct 10, 2024
029b4d0
Merge Branch
vigy02 Oct 11, 2024
57daf18
Merge Branch
vigy02 Oct 11, 2024
04bca21
Merge Branch
vigy02 Oct 11, 2024
7d48cbe
Merge Branch
vigy02 Oct 11, 2024
7847881
Merge Branch
vigy02 Oct 11, 2024
43b7da0
Merge Branch
vigy02 Oct 11, 2024
e0532f3
Merge Branch
vigy02 Oct 11, 2024
7c007da
Merge Branch
vigy02 Oct 11, 2024
9178e8b
Merge Branch
vigy02 Oct 11, 2024
570de9e
fixed the code to use addTrigger instead of manually setting up permi…
vigy02 Oct 14, 2024
8a272d1
added KMS Key for customEmailSender
vigy02 Oct 14, 2024
c558111
changed KMS key to not read-only
vigy02 Oct 14, 2024
37b6d5d
changed the test case to include lambdaArn
vigy02 Oct 14, 2024
324afb6
add a test case validation for KMS key
vigy02 Oct 14, 2024
10444c7
Merge branch 'main' of github.com:vigy02/amplify-backend
vigy02 Oct 14, 2024
0c04155
Merge branch 'main' into feature/custom-email-function
vigy02 Oct 14, 2024
36160e5
fixed the code to use addTrigger instead of manually setting up permi…
vigy02 Oct 14, 2024
fff5cde
added KMS Key for customEmailSender
vigy02 Oct 14, 2024
22b8840
changed KMS key to not read-only
vigy02 Oct 14, 2024
a1b4056
changed the test case to include lambdaArn
vigy02 Oct 14, 2024
1b1a263
add a test case validation for KMS key
vigy02 Oct 14, 2024
7e688f6
detect transform errors with multiple errors (#2102)
rtpascual Oct 11, 2024
4772b2e
Add minify option to defineFunction (#2093)
fossamagna Oct 11, 2024
1d64301
upgrade constructs (#2103)
sobolk Oct 11, 2024
49b46d6
Remove deprecated messages field from event (#2106)
sobolk Oct 11, 2024
7119b35
detect generic CFN stack creation errors (#2108)
rtpascual Oct 11, 2024
0480694
Fix cdk tests when new dependencies are shipped to npm. (#2107)
sobolk Oct 14, 2024
793927a
Merge branch 'main' into feature/custom-email-function
vigy02 Oct 15, 2024
7665597
Merge branch 'feature/custom-email-function' of github.com:vigy02/amp…
vigy02 Oct 15, 2024
487f586
API changes
vigy02 Oct 15, 2024
2267f2a
Merge branch 'main' into feature/custom-email-function
vigy02 Oct 23, 2024
38c05f5
Update API changes
vigy02 Oct 23, 2024
be0d21e
Merge branch 'aws-amplify:main' into feature/custom-email-function
vigy02 Oct 23, 2024
50f7e94
Added kmsKeyArn for custom user KMS keys
vigy02 Oct 24, 2024
984bd69
chore: added changesets and updated API's
vigy02 Oct 24, 2024
70ae8a1
chore: added changesets
vigy02 Oct 24, 2024
fe1aaf1
Added integration tests for customEmailSender
vigy02 Oct 25, 2024
e06162b
updated the API files to reflect master
vigy02 Oct 25, 2024
b8d54a6
feat: added customSenderEmail with types and added exceptions to esli…
vigy02 Oct 29, 2024
3b03d3c
Merge branch 'main' into feature/custom-email-function
vigy02 Oct 29, 2024
3df2842
chore: Updated API
vigy02 Oct 29, 2024
4f21f21
chore: Updated API
vigy02 Oct 29, 2024
c7e53cc
chore: updated API
vigy02 Oct 29, 2024
e7d335c
Delete packages/ai-constructs/API.md
vigy02 Oct 29, 2024
30ffca8
chore: Updated API
vigy02 Oct 29, 2024
7411f34
chore: delete unused file
vigy02 Oct 29, 2024
1c6bef9
chore: update changeset
vigy02 Oct 29, 2024
65cbf67
chore: update changeset
vigy02 Oct 29, 2024
3e898fc
chore: Updated API and changeSets
vigy02 Oct 30, 2024
445e0a3
chore: Updated the API from main
vigy02 Oct 30, 2024
e4f879b
API updates to resolve conflicting naming
vigy02 Oct 30, 2024
a26da97
Updated the types in backend-auth
vigy02 Oct 31, 2024
3e49d70
chore: Updated changesets
vigy02 Oct 31, 2024
f5da56c
Added custom Email handler function and refactored the types of auth-…
vigy02 Oct 31, 2024
223181c
chore: updated API
vigy02 Oct 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/curvy-pans-brake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@aws-amplify/auth-construct': minor
'@aws-amplify/backend-auth': minor
'@aws-amplify/backend': minor
'@aws-amplify/integration-tests': minor
---

Add support for custom Lambda function email senders in Auth construct
3 changes: 3 additions & 0 deletions .eslint_dictionary.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"datasync",
"debounce",
"declarator",
"decrypt",
"deployer",
"deprecations",
"deprecator",
Expand Down Expand Up @@ -146,6 +147,7 @@
"sigint",
"signout",
"signup",
"SKey",
"sms",
"stderr",
"stdin",
Expand All @@ -159,6 +161,7 @@
"synthing",
"testname",
"testnamebucket",
"testuser",
"timestamps",
"tmpdir",
"todos",
Expand Down
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion packages/auth-construct/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { AuthResources } from '@aws-amplify/plugin-types';
import { aws_cognito } from 'aws-cdk-lib';
import { BackendOutputStorageStrategy } from '@aws-amplify/plugin-types';
import { Construct } from 'constructs';
import { IFunction } from 'aws-cdk-lib/aws-lambda';
import { NumberAttributeConstraints } from 'aws-cdk-lib/aws-cognito';
import { ResourceProvider } from '@aws-amplify/plugin-types';
import { SecretValue } from 'aws-cdk-lib';
Expand Down Expand Up @@ -47,7 +48,7 @@ export type AuthProps = {
externalProviders?: ExternalProviderOptions;
};
senders?: {
email: Pick<UserPoolSESOptions, 'fromEmail' | 'fromName' | 'replyTo'>;
email: Pick<UserPoolSESOptions, 'fromEmail' | 'fromName' | 'replyTo'> | CustomEmailSender;
};
userAttributes?: UserAttributes;
multifactor?: MFA;
Expand Down Expand Up @@ -84,6 +85,12 @@ export type CustomAttributeString = CustomAttributeBase & StringAttributeConstra
dataType: 'String';
};

// @public
export type CustomEmailSender = {
handler: IFunction;
kmsKeyArn?: string;
};

// @public
export type EmailLogin = true | EmailLoginSettings;

Expand Down
72 changes: 59 additions & 13 deletions packages/auth-construct/src/construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
UserPoolIdentityProviderOidc,
UserPoolIdentityProviderSaml,
UserPoolIdentityProviderSamlMetadataType,
UserPoolOperation,
UserPoolProps,
} from 'aws-cdk-lib/aws-cognito';
import { FederatedPrincipal, Role } from 'aws-cdk-lib/aws-iam';
Expand All @@ -51,6 +52,7 @@ import {
StackMetadataBackendOutputStorageStrategy,
} from '@aws-amplify/backend-output-storage';
import * as path from 'path';
import { IKey, Key } from 'aws-cdk-lib/aws-kms';

type DefaultRoles = { auth: Role; unAuth: Role };
type IdentityProviderSetupResult = {
Expand Down Expand Up @@ -130,6 +132,11 @@ export class AmplifyAuth
role: Role;
};
} = {};
/**
* The KMS key used for encrypting custom email sender data.
* This is only set when using a custom email sender.
*/
private customEmailSenderKMSkey: IKey | undefined;

/**
* Create a new Auth construct with AuthProps.
Expand All @@ -141,24 +148,39 @@ export class AmplifyAuth
props: AuthProps = DEFAULTS.IF_NO_PROPS_PROVIDED
) {
super(scope, id);

this.name = props.name ?? '';
this.domainPrefix = props.loginWith.externalProviders?.domainPrefix;

// UserPool
this.computedUserPoolProps = this.getUserPoolProps(props);

this.userPool = new cognito.UserPool(
this,
`${this.name}UserPool`,
this.computedUserPoolProps
);
/**
* Configure custom email sender for Cognito User Pool
* Grant necessary permissions for Lambda function to decrypt emails
* and allow Cognito to invoke the Lambda function
*/
if (
props.senders?.email &&
'handler' in props.senders.email &&
this.customEmailSenderKMSkey
) {
this.customEmailSenderKMSkey.grantDecrypt(props.senders.email.handler);
this.customEmailSenderKMSkey.grantEncrypt(props.senders.email.handler);
this.userPool.addTrigger(
UserPoolOperation.of('customEmailSender'),
props.senders.email.handler
);
}

// UserPool - External Providers (Oauth, SAML, OIDC) and User Pool Domain
this.providerSetupResult = this.setupExternalProviders(
this.userPool,
props.loginWith
);

// UserPool Client
const userPoolClient = new cognito.UserPoolClient(
this,
Expand Down Expand Up @@ -478,7 +500,30 @@ export class AmplifyAuth
},
{ standardAttributes: {}, customAttributes: {} }
);

/**
* Handle KMS key for custom email sender
* If a custom email sender is provided, we either use the provided KMS key ARN
* or create a new KMS key if one is not provided.
*/
if (props.senders?.email && 'handler' in props.senders.email) {
if (props.senders.email.kmsKeyArn) {
// Use the provided KMS key ARN
this.customEmailSenderKMSkey = Key.fromKeyArn(
this,
`${this.name}CustomSenderKey`,
props.senders.email.kmsKeyArn
);
} else {
// Create a new KMS key if not provided
this.customEmailSenderKMSkey = new Key(
props.senders.email.handler.stack,
`${this.name}CustomSenderKey`,
{
enableKeyRotation: true,
}
);
}
}
const userPoolProps: UserPoolProps = {
signInCaseSensitive: DEFAULTS.SIGN_IN_CASE_SENSITIVE,
signInAliases: {
Expand All @@ -503,15 +548,15 @@ export class AmplifyAuth
customAttributes: {
...customAttributes,
},
email: props.senders
? cognito.UserPoolEmail.withSES({
fromEmail: props.senders.email.fromEmail,
fromName: props.senders.email.fromName,
replyTo: props.senders.email.replyTo,
sesRegion: Stack.of(this).region,
})
: undefined,

email:
props.senders && 'fromEmail' in props.senders.email
? cognito.UserPoolEmail.withSES({
fromEmail: props.senders.email.fromEmail,
fromName: props.senders.email.fromName,
replyTo: props.senders.email.replyTo,
sesRegion: Stack.of(this).region,
})
: undefined,
selfSignUpEnabled: DEFAULTS.ALLOW_SELF_SIGN_UP,
mfa: mfaMode,
mfaMessage: this.getMFAMessage(props.multifactor),
Expand All @@ -528,6 +573,7 @@ export class AmplifyAuth
props.loginWith.email?.userInvitation
)
: undefined,
customSenderKmsKey: this.customEmailSenderKMSkey,
};
return userPoolProps;
};
Expand Down
1 change: 1 addition & 0 deletions packages/auth-construct/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export {
CustomAttributeBoolean,
CustomAttributeDateTime,
CustomAttributeBase,
CustomEmailSender,
} from './types.js';
export { AmplifyAuth } from './construct.js';
export { triggerEvents } from './trigger_events.js';
17 changes: 15 additions & 2 deletions packages/auth-construct/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
UserPoolIdentityProviderSamlMetadata,
UserPoolSESOptions,
} from 'aws-cdk-lib/aws-cognito';
import { IFunction } from 'aws-cdk-lib/aws-lambda';
export type VerificationEmailWithLink = {
/**
* The type of verification. Must be one of "CODE" or "LINK".
Expand Down Expand Up @@ -380,6 +381,14 @@ export type CustomAttribute =
export type UserAttributes = StandardAttributes &
Record<`custom:${string}`, CustomAttribute>;

/**
* CustomEmailSender type for configuring a custom Lambda function for email sending
*/
export type CustomEmailSender = {
handler: IFunction;
kmsKeyArn?: string;
};

/**
* Input props for the AmplifyAuth construct
*/
Expand Down Expand Up @@ -417,11 +426,15 @@ export type AuthProps = {
*/
senders?: {
/**
* Configure Cognito to send emails from SES
* Configure Cognito to send emails from SES or a custom message trigger
* SES configurations enable the use of customized email sender addresses and names
* Custom message triggers enable the use of third-party email providers when sending email notifications to users
* @see https://docs.amplify.aws/react/build-a-backend/auth/moving-to-production/#email
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-custom-email-sender.html
*/
email: Pick<UserPoolSESOptions, 'fromEmail' | 'fromName' | 'replyTo'>;
email:
| Pick<UserPoolSESOptions, 'fromEmail' | 'fromName' | 'replyTo'>
| CustomEmailSender;
};
/**
* The set of attributes that are required for every user in the user pool. Read more on attributes here - https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
Expand Down
14 changes: 13 additions & 1 deletion packages/backend-auth/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
```ts

import { AmazonProviderProps } from '@aws-amplify/auth-construct';
import { AmplifyFunction } from '@aws-amplify/plugin-types';
import { AppleProviderProps } from '@aws-amplify/auth-construct';
import { AuthProps } from '@aws-amplify/auth-construct';
import { AuthResources } from '@aws-amplify/plugin-types';
Expand All @@ -16,12 +17,14 @@ import { ExternalProviderOptions } from '@aws-amplify/auth-construct';
import { FacebookProviderProps } from '@aws-amplify/auth-construct';
import { FunctionResources } from '@aws-amplify/plugin-types';
import { GoogleProviderProps } from '@aws-amplify/auth-construct';
import { IFunction } from 'aws-cdk-lib/aws-lambda';
import { OidcProviderProps } from '@aws-amplify/auth-construct';
import { ResourceAccessAcceptor } from '@aws-amplify/plugin-types';
import { ResourceAccessAcceptorFactory } from '@aws-amplify/plugin-types';
import { ResourceProvider } from '@aws-amplify/plugin-types';
import { StackProvider } from '@aws-amplify/plugin-types';
import { TriggerEvent } from '@aws-amplify/auth-construct';
import { UserPoolSESOptions } from 'aws-cdk-lib/aws-cognito';

// @public
export type ActionIam = 'addUserToGroup' | 'createGroup' | 'createUser' | 'deleteGroup' | 'deleteUser' | 'deleteUserAttributes' | 'disableUser' | 'enableUser' | 'forgetDevice' | 'getDevice' | 'getGroup' | 'getUser' | 'listUsers' | 'listUsersInGroup' | 'listGroups' | 'listDevices' | 'listGroupsForUser' | 'removeUserFromGroup' | 'resetUserPassword' | 'setUserMfaPreference' | 'setUserPassword' | 'setUserSettings' | 'updateDeviceStatus' | 'updateGroup' | 'updateUserAttributes';
Expand All @@ -36,10 +39,13 @@ export type AmazonProviderFactoryProps = Omit<AmazonProviderProps, 'clientId' |
};

// @public (undocumented)
export type AmplifyAuthProps = Expand<Omit<AuthProps, 'outputStorageStrategy' | 'loginWith'> & {
export type AmplifyAuthProps = Expand<Omit<AuthProps, 'outputStorageStrategy' | 'loginWith' | 'senders'> & {
loginWith: Expand<AuthLoginWithFactoryProps>;
triggers?: Partial<Record<TriggerEvent, ConstructFactory<ResourceProvider<FunctionResources>>>>;
access?: AuthAccessGenerator;
senders?: {
email: Pick<UserPoolSESOptions, 'fromEmail' | 'fromName' | 'replyTo'> | CustomEmailSender;
};
}>;

// @public
Expand Down Expand Up @@ -80,6 +86,12 @@ export type AuthLoginWithFactoryProps = Omit<AuthProps['loginWith'], 'externalPr
// @public (undocumented)
export type BackendAuth = ResourceProvider<AuthResources> & ResourceAccessAcceptorFactory<AuthRoleName | string> & StackProvider;

// @public
export type CustomEmailSender = {
handler: ConstructFactory<AmplifyFunction> | IFunction;
kmsKeyArn?: string;
};

// @public
export const defineAuth: (props: AmplifyAuthProps) => ConstructFactory<BackendAuth>;

Expand Down
Loading
Loading