Skip to content

Commit

Permalink
feat: support for sign in with apple (#7413)
Browse files Browse the repository at this point in the history
  • Loading branch information
letsbelopez authored Jul 2, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 03973ee commit 00d6676
Showing 25 changed files with 728 additions and 121 deletions.
Original file line number Diff line number Diff line change
@@ -589,15 +589,25 @@ Resources:
- ' let providerCredsIndex = hostedUIProviderCreds.findIndex((provider) => provider.ProviderName === providerName);'
- ' let providerCreds = hostedUIProviderCreds[providerCredsIndex];'
- ' let requestParams = {'
- ' ProviderDetails: {'
- ' ''client_id'': providerCreds.client_id,'
- ' ''client_secret'': providerCreds.client_secret,'
- ' ''authorize_scopes'': providerMeta.authorize_scopes'
- ' },'
- ' ProviderName: providerMeta.ProviderName,'
- ' UserPoolId: userPoolId,'
- ' AttributeMapping: providerMeta.AttributeMapping'
- ' AttributeMapping: providerMeta.AttributeMapping,'
- ' };'
- ' if (providerMeta.ProviderName === ''SignInWithApple'') {'
- ' requestParams.ProviderDetails = {'
- ' ''client_id'': providerCreds.client_id,'
- ' ''team_id'': providerCreds.team_id,'
- ' ''key_id'': providerCreds.key_id,'
- ' ''private_key'': providerCreds.private_key,'
- ' ''authorize_scopes'': providerMeta.authorize_scopes,'
- ' };'
- ' } else {'
- ' requestParams.ProviderDetails = {'
- ' ''client_id'': providerCreds.client_id,'
- ' ''client_secret'': providerCreds.client_secret,'
- ' ''authorize_scopes'': providerMeta.authorize_scopes,'
- ' };'
- ' }'
- ' return requestParams;'
- ' };'
- ' let createIdentityProvider = (providerName) => {'
@@ -1112,6 +1122,9 @@ Resources:
<%if (props.authProviders.indexOf('www.amazon.com') !== -1) { %>
www.amazon.com: !Ref amazonAppId
<% } %>
<%if (props.authProviders.indexOf('appleid.apple.com') !== -1) { %>
appleid.apple.com: !Ref appleAppId
<% } %>
<% } %>
AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
<%if (props.audiences && props.audiences.length > 0) { %>
@@ -1194,4 +1207,8 @@ Outputs :
AmazonWebClient:
Value: !Ref amazonAppId
<% } %>
<%if (props.appleAppId) { %>
AppleWebClient:
Value: !Ref appleAppId
<% } %>
<% } %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { extractApplePrivateKey } from '../../../../provider-utils/awscloudformation/utils/extract-apple-private-key';

describe('When extracting apple private key...', () => {
const expectedOutput =
'MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw';

it('it should remove new lines and space and comments', () => {
const input = `-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadY
iCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIf
TT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6
y89bWcNw
-----END PRIVATE KEY-----`;
expect(extractApplePrivateKey(input)).toEqual(expectedOutput);
});

it('it should not alter a pre extracted key', () => {
const input = expectedOutput;
expect(extractApplePrivateKey(input)).toEqual(expectedOutput);
});
});
Original file line number Diff line number Diff line change
@@ -136,6 +136,7 @@ const attributeProviderMap = {
facebook: {},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
birthdate: {
facebook: {
@@ -147,6 +148,7 @@ const attributeProviderMap = {
scope: 'profile',
},
loginwithamazon: {},
signinwithapple: {},
},
email: {
facebook: {
@@ -161,6 +163,10 @@ const attributeProviderMap = {
attr: 'email',
scope: 'profile',
},
signinwithapple: {
attr: 'email',
scope: 'email',
},
},
family_name: {
facebook: {
@@ -172,6 +178,10 @@ const attributeProviderMap = {
scope: 'profile',
},
loginwithamazon: {},
signinwithapple: {
attr: 'lastName',
scope: 'name',
},
},
gender: {
facebook: {
@@ -183,6 +193,7 @@ const attributeProviderMap = {
scope: 'profile',
},
loginwithamazon: {},
signinwithapple: {},
},
given_name: {
facebook: {
@@ -194,6 +205,10 @@ const attributeProviderMap = {
scope: 'profile',
},
loginwithamazon: {},
signinwithapple: {
attr: 'firstName',
scope: 'name',
},
},
locale: {
facebook: {},
@@ -202,6 +217,7 @@ const attributeProviderMap = {
attr: 'postal_code',
scope: 'postal_code',
},
signinwithapple: {},
},
middle_name: {
facebook: {
@@ -210,6 +226,7 @@ const attributeProviderMap = {
},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
name: {
facebook: {
@@ -224,11 +241,13 @@ const attributeProviderMap = {
attr: 'name',
scope: 'profile',
},
signinwithapple: {},
},
nickname: {
facebook: {},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
phone_number: {
facebook: {},
@@ -237,6 +256,7 @@ const attributeProviderMap = {
scope: 'profile',
},
loginwithamazon: {},
signinwithapple: {},
},
picture: {
facebook: {
@@ -248,26 +268,31 @@ const attributeProviderMap = {
scope: 'profile',
},
loginwithamazon: {},
signinwithapple: {},
},
preferred_username: {
facebook: {},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
profile: {
facebook: {},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
zoneinfo: {
facebook: {},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
website: {
facebook: {},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
username: {
facebook: {
@@ -282,6 +307,7 @@ const attributeProviderMap = {
attr: 'user_id',
scope: 'profile:user_id',
},
signinwithapple: {},
},
updated_at: {
facebook: {
@@ -290,6 +316,7 @@ const attributeProviderMap = {
},
google: {},
loginwithamazon: {},
signinwithapple: {},
},
};

@@ -392,6 +419,11 @@ const authProviders = [
value: 'www.amazon.com',
answerHashKey: 'amazonAppId',
},
{
name: 'Apple',
value: 'appleid.apple.com',
answerHashKey: 'appleAppId',
},
];

const hostedUIProviders = [
@@ -407,6 +439,10 @@ const hostedUIProviders = [
name: 'Login With Amazon',
value: 'LoginWithAmazon',
},
{
name: 'Sign in with Apple',
value: 'SignInWithApple',
},
];

const authorizeScopes = [
Original file line number Diff line number Diff line change
@@ -19,6 +19,11 @@ export const ENV_SPECIFIC_PARAMS = [
'amazonAppId',
'loginwithamazonAppIdUserPool',
'loginwithamazonAppSecretUserPool',
'appleAppId',
'signinwithappleClientIdUserPool',
'signinwithappleTeamIdUserPool',
'signinwithappleKeyIdUserPool',
'signinwithapplePrivateKeyUserPool',
'hostedUIProviderCreds',
];

@@ -55,6 +60,10 @@ export const privateKeys = [
'loginwithamazonAppIdUserPool',
'loginwithamazonAuthorizeScopes',
'loginwithamazonAppSecretUserPool',
'signinwithappleClientIdUserPool',
'signinwithappleTeamIdUserPool',
'signinwithappleKeyIdUserPool',
'signinwithapplePrivateKeyUserPool',
'CallbackURLs',
'LogoutURLs',
'AllowedOAuthFlows',
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ import { importMessages } from './messages';
import uuid from 'uuid';

// Currently the CLI only supports the output generation of these providers
const supportedIdentityProviders = ['COGNITO', 'Facebook', 'Google', 'LoginWithAmazon'];
const supportedIdentityProviders = ['COGNITO', 'Facebook', 'Google', 'LoginWithAmazon', 'SignInWithApple'];

export const importResource = async (
context: $TSContext,
@@ -752,6 +752,9 @@ const createMetaOutput = (answers: ImportAnswers, hasOAuthConfig: boolean): Meta
case 'accounts.google.com':
output.GoogleWebClient = answers.identityPool!.SupportedLoginProviders![key];
break;
case 'appleid.apple.com':
output.AppleWebClient = answers.identityPool!.SupportedLoginProviders![key];
break;
default:
// We don't do anything with the providers that the CLI currently does not support.
break;
@@ -815,6 +818,9 @@ const createEnvSpecificResourceParameters = (
case 'graph.facebook.com':
envSpecificResourceParameters.facebookAppId = answers.identityPool!.SupportedLoginProviders![key];
break;
case 'appleid.apple.com':
envSpecificResourceParameters.appleAppId = answers.identityPool!.SupportedLoginProviders![key];
break;
case 'accounts.google.com': {
switch (projectType) {
case 'javascript':
@@ -840,11 +846,23 @@ const createEnvSpecificResourceParameters = (
};

const createOAuthCredentials = (identityProviders: IdentityProviderType[]): string => {
const credentials = identityProviders.map(idp => ({
ProviderName: idp.ProviderName!,
client_id: idp.ProviderDetails!.client_id,
client_secret: idp.ProviderDetails!.client_secret,
}));
const credentials = identityProviders.map(idp => {
if (idp.ProviderName === 'SignInWithApple') {
return {
ProviderName: idp.ProviderName!,
client_id: idp.ProviderDetails!.client_id,
team_id: idp.ProviderDetails!.team_id,
key_id: idp.ProviderDetails!.key_id,
private_key: idp.ProviderDetails!.private_key,
};
} else {
return {
ProviderName: idp.ProviderName!,
client_id: idp.ProviderDetails!.client_id,
client_secret: idp.ProviderDetails!.client_secret,
};
}
});

return JSON.stringify(credentials);
};
Original file line number Diff line number Diff line change
@@ -44,6 +44,7 @@ export type MetaOutput = {
AmazonWebClient?: string;
FacebookWebClient?: string;
GoogleWebClient?: string;
AppleWebClient?: string;
HostedUIDomain?: string;
OAuthMetadata?: string;
CreatedSNSRole?: string;
@@ -59,6 +60,7 @@ export type EnvSpecificResourceParameters = {
identityPoolName?: string;
facebookAppId?: string;
amazonAppId?: string;
appleAppId?: string;
googleIos?: string;
googleAndroid?: string;
googleClientId?: string;
Loading

0 comments on commit 00d6676

Please sign in to comment.