Skip to content

Commit

Permalink
fix: attribute mappings ignored (aws-amplify#1012)
Browse files Browse the repository at this point in the history
* fix: bug causing attribute mappings to be ignored

* chore: add tests to prevent overriding customer mappings

* chore: fix lint
  • Loading branch information
awsluja authored Feb 9, 2024
1 parent 065614f commit 3cb2a52
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .changeset/smooth-penguins-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@aws-amplify/auth-construct-alpha': patch
---

Fix a bug that would cause attribute mappings to be ignored.
1 change: 1 addition & 0 deletions .eslint_dictionary.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"formatter",
"frontend",
"frontends",
"fullname",
"func",
"geofence",
"gitignore",
Expand Down
34 changes: 17 additions & 17 deletions package-lock.json

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

251 changes: 251 additions & 0 deletions packages/auth-construct/src/construct.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import {
CfnIdentityPool,
CfnUserPoolClient,
ProviderAttribute,
UserPool,
UserPoolClient,
} from 'aws-cdk-lib/aws-cognito';
Expand Down Expand Up @@ -1945,6 +1946,256 @@ void describe('Auth construct', () => {
);
});
});

void it('automatically maps email attributes for external providers and keeps existing configuration', () => {
const app = new App();
const stack = new Stack(app);
new AmplifyAuth(stack, 'test', {
loginWith: {
email: true,
externalProviders: {
google: {
clientId: googleClientId,
clientSecret: SecretValue.unsafePlainText(googleClientSecret),
attributeMapping: {
fullname: ProviderAttribute.GOOGLE_NAME,
},
},
facebook: {
clientId: facebookClientId,
clientSecret: facebookClientSecret,
attributeMapping: {
fullname: ProviderAttribute.FACEBOOK_NAME,
},
},
signInWithApple: {
clientId: appleClientId,
keyId: appleKeyId,
privateKey: applePrivateKey,
teamId: appleTeamId,
attributeMapping: {
fullname: ProviderAttribute.APPLE_NAME,
},
},
loginWithAmazon: {
clientId: amazonClientId,
clientSecret: amazonClientSecret,
attributeMapping: {
fullname: ProviderAttribute.AMAZON_NAME,
},
},
oidc: {
clientId: oidcClientId,
clientSecret: oidcClientSecret,
issuerUrl: oidcIssuerUrl,
name: oidcProviderName,
attributeMapping: {
fullname: {
attributeName: 'name',
},
},
},
callbackUrls: ['https://redirect.com'],
logoutUrls: ['https://logout.com'],
},
},
});
const template = Template.fromStack(stack);
template.hasResourceProperties('AWS::Cognito::UserPool', {
UsernameAttributes: ['email'],
AutoVerifiedAttributes: ['email'],
});
const expectedAutoMappedAttributes = {
AttributeMapping: {
// 'email' is a standardized claim for oauth and oidc IDPS
// so we can map it to cognito's 'email' claim
email: 'email',
},
};
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedAmazonIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.AMAZON_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedAppleIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.APPLE_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedFacebookIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.FACEBOOK_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedGoogleIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.GOOGLE_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedOidcIDPProperties,
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: 'name',
},
});
template.hasResourceProperties('AWS::Cognito::IdentityPool', {
SupportedLoginProviders: {
'www.amazon.com': amazonClientId,
'accounts.google.com': googleClientId,
'appleid.apple.com': appleClientId,
'graph.facebook.com': facebookClientId,
},
});
});

void it('should not override email attribute mapping if customer providers their own mapping', () => {
const app = new App();
const stack = new Stack(app);
const customEmailMapping = 'customMapping';
new AmplifyAuth(stack, 'test', {
loginWith: {
email: true,
externalProviders: {
google: {
clientId: googleClientId,
clientSecret: SecretValue.unsafePlainText(googleClientSecret),
attributeMapping: {
email: {
attributeName: customEmailMapping,
},
fullname: ProviderAttribute.GOOGLE_NAME,
},
},
facebook: {
clientId: facebookClientId,
clientSecret: facebookClientSecret,
attributeMapping: {
email: {
attributeName: customEmailMapping,
},
fullname: ProviderAttribute.FACEBOOK_NAME,
},
},
signInWithApple: {
clientId: appleClientId,
keyId: appleKeyId,
privateKey: applePrivateKey,
teamId: appleTeamId,
attributeMapping: {
email: {
attributeName: customEmailMapping,
},
fullname: ProviderAttribute.APPLE_NAME,
},
},
loginWithAmazon: {
clientId: amazonClientId,
clientSecret: amazonClientSecret,
attributeMapping: {
email: {
attributeName: customEmailMapping,
},
fullname: ProviderAttribute.AMAZON_NAME,
},
},
oidc: {
clientId: oidcClientId,
clientSecret: oidcClientSecret,
issuerUrl: oidcIssuerUrl,
name: oidcProviderName,
attributeMapping: {
email: {
attributeName: customEmailMapping,
},
fullname: {
attributeName: 'name',
},
},
},
callbackUrls: ['https://redirect.com'],
logoutUrls: ['https://logout.com'],
},
},
});
const template = Template.fromStack(stack);
template.hasResourceProperties('AWS::Cognito::UserPool', {
UsernameAttributes: ['email'],
AutoVerifiedAttributes: ['email'],
});
const expectedAutoMappedAttributes = {
AttributeMapping: {
email: customEmailMapping,
},
};
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedAmazonIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.AMAZON_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedAppleIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.APPLE_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedFacebookIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.FACEBOOK_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedGoogleIDPProperties,
...{
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: ProviderAttribute.GOOGLE_NAME.attributeName,
},
},
});
template.hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', {
...ExpectedOidcIDPProperties,
AttributeMapping: {
...expectedAutoMappedAttributes.AttributeMapping,
name: 'name',
},
});
template.hasResourceProperties('AWS::Cognito::IdentityPool', {
SupportedLoginProviders: {
'www.amazon.com': amazonClientId,
'accounts.google.com': googleClientId,
'appleid.apple.com': appleClientId,
'graph.facebook.com': facebookClientId,
},
});
});
});

void it('sets resource names based on id and name property', () => {
Expand Down
Loading

0 comments on commit 3cb2a52

Please sign in to comment.