diff --git a/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs b/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs index 817e3ff3f9c..6ded23a991b 100644 --- a/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs +++ b/packages/amplify-category-auth/resources/cloudformation-templates/auth-template.yml.ejs @@ -589,16 +589,27 @@ 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,' - ' };' - - ' return requestParams;' + - ' let providerDetails;' + - ' if (providerMeta.ProviderName === ''SignInWithApple'') {' + - ' 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 {' + - ' providerDetails = {' + - ' ''client_id'': providerCreds.client_id,' + - ' ''client_secret'': providerCreds.client_secret,' + - ' ''authorize_scopes'': providerMeta.authorize_scopes,' + - ' };' + - ' }' + - ' return { ProviderDetails: providerDetails, ...requestParams };' - ' };' - ' let createIdentityProvider = (providerName) => {' - ' let requestParams = getRequestParams(providerName);' @@ -1112,6 +1123,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 +1208,8 @@ Outputs : AmazonWebClient: Value: !Ref amazonAppId <% } %> + <%if (props.appleAppId) { %> + AppleWebClient: + Value: !Ref appleAppId + <% } %> <% } %> diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/assets/string-maps.js b/packages/amplify-category-auth/src/provider-utils/awscloudformation/assets/string-maps.js index aa046254d5b..eb752d7c8a7 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/assets/string-maps.js +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/assets/string-maps.js @@ -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 = [ diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/constants.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/constants.ts index 861bda0ce4a..b1872b61c2d 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/constants.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/constants.ts @@ -19,6 +19,10 @@ export const ENV_SPECIFIC_PARAMS = [ 'amazonAppId', 'loginwithamazonAppIdUserPool', 'loginwithamazonAppSecretUserPool', + 'signinwithappleClientIdUserPool', + 'signinwithappleTeamIdUserPool', + 'signinwithappleKeyIdUserPool', + 'signinwithapplePrivateKeyUserPool', 'hostedUIProviderCreds', ]; @@ -55,6 +59,10 @@ export const privateKeys = [ 'loginwithamazonAppIdUserPool', 'loginwithamazonAuthorizeScopes', 'loginwithamazonAppSecretUserPool', + 'signinwithappleClientIdUserPool', + 'signinwithappleTeamIdUserPool', + 'signinwithappleKeyIdUserPool', + 'signinwithapplePrivateKeyUserPool', 'CallbackURLs', 'LogoutURLs', 'AllowedOAuthFlows', diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/index.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/index.ts index a7b88f089d0..dd89637906c 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/index.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/index.ts @@ -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); }; diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts index 16ead2f0a90..d2adc441f23 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/import/types.ts @@ -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; diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js b/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js index 4a4251d7a46..232c11b657d 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/index.js @@ -217,8 +217,15 @@ function getOAuthProviderKeys(currentEnvSpecificValues, resourceParams) { const configuredProviders = JSON.parse(hostedUIProviderCreds).map(h => h.ProviderName); const deltaProviders = _.intersection(oAuthProviders, configuredProviders); deltaProviders.forEach(d => { - currentEnvSpecificValues[`${d.toLowerCase()}AppIdUserPool`] = configuredProviders[`${d.toLowerCase()}AppIdUserPool`]; - currentEnvSpecificValues[`${d.toLowerCase()}AppSecretUserPool`] = configuredProviders[`${d.toLowerCase()}AppSecretUserPool`]; + if (d === 'SignInWithApple') { + currentEnvSpecificValues[`${d.toLowerCase()}ClientIdUserPool`] = configuredProviders[`${d.toLowerCase()}ClientIdUserPool`]; + currentEnvSpecificValues[`${d.toLowerCase()}TeamIdUserPool`] = configuredProviders[`${d.toLowerCase()}TeamIdUserPool`]; + currentEnvSpecificValues[`${d.toLowerCase()}KeyIdUserPool`] = configuredProviders[`${d.toLowerCase()}KeyIdUserPool`]; + currentEnvSpecificValues[`${d.toLowerCase()}PrivateKeyUserPool`] = configuredProviders[`${d.toLowerCase()}PrivateKeyUserPool`]; + } else { + currentEnvSpecificValues[`${d.toLowerCase()}AppIdUserPool`] = configuredProviders[`${d.toLowerCase()}AppIdUserPool`]; + currentEnvSpecificValues[`${d.toLowerCase()}AppSecretUserPool`] = configuredProviders[`${d.toLowerCase()}AppSecretUserPool`]; + } }); return currentEnvSpecificValues; } @@ -249,15 +256,34 @@ function formatCredsforEnvParams(currentEnvSpecificValues, result, resourceParam function parseCredsForHeadless(mergedValues, envParams) { const oAuthProviders = JSON.parse(mergedValues.hostedUIProviderMeta).map(h => h.ProviderName); envParams.hostedUIProviderCreds = JSON.stringify( - oAuthProviders.map(el => ({ - ProviderName: el, - client_id: mergedValues[`${el.toLowerCase()}AppIdUserPool`], - client_secret: mergedValues[`${el.toLowerCase()}AppSecretUserPool`], - })), + oAuthProviders.map(el => { + if (el === 'SignInWithApple') { + return { + ProviderName: el, + client_id: mergedValues[`${el.toLowerCase()}ClientIdUserPool`], + team_id: mergedValues[`${el.toLowerCase()}TeamIdUserPool`], + key_id: mergedValues[`${el.toLowerCase()}KeyIdUserPool`], + private_key: mergedValues[`${el.toLowerCase()}PrivateKeyUserPool`], + }; + } else { + return { + ProviderName: el, + client_id: mergedValues[`${el.toLowerCase()}AppIdUserPool`], + client_secret: mergedValues[`${el.toLowerCase()}AppSecretUserPool`], + }; + } + }), ); oAuthProviders.forEach(i => { - delete envParams[`${i.toLowerCase()}AppIdUserPool`]; - delete envParams[`${i.toLowerCase()}AppSecretUserPool`]; + if (i === 'SignInWithApple') { + delete envParams[`${i.toLowerCase()}ClientIdUserPool`]; + delete envParams[`${i.toLowerCase()}TeamIdUserPool`]; + delete envParams[`${i.toLowerCase()}KeyIdUserPool`]; + delete envParams[`${i.toLowerCase()}PrivateKeyUserPool`]; + } else { + delete envParams[`${i.toLowerCase()}AppIdUserPool`]; + delete envParams[`${i.toLowerCase()}AppSecretUserPool`]; + } }); } @@ -280,14 +306,24 @@ function getRequiredParamsForHeadlessInit(projectType, previousValues) { if (previousValues.authProviders.includes('www.amazon.com')) { requiredParams.push('amazonAppId'); } + if (previousValues.authProviders.includes('appleid.apple.com')) { + requiredParams.push('appleAppId'); + } } if (previousValues.hostedUIProviderMeta) { const oAuthProviders = JSON.parse(previousValues.hostedUIProviderMeta).map(h => h.ProviderName); if (oAuthProviders && oAuthProviders.length > 0) { oAuthProviders.forEach(o => { - requiredParams.push(`${o.toLowerCase()}AppIdUserPool`); - requiredParams.push(`${o.toLowerCase()}AppSecretUserPool`); + if (o === 'SignInWithApple') { + requiredParams.push(`${o.toLowerCase()}ClientIdUserPool`); + requiredParams.push(`${o.toLowerCase()}TeamIdUserPool`); + requiredParams.push(`${o.toLowerCase()}KeyIdUserPool`); + requiredParams.push(`${o.toLowerCase()}PrivateKeyUserPool`); + } else { + requiredParams.push(`${o.toLowerCase()}AppIdUserPool`); + requiredParams.push(`${o.toLowerCase()}AppSecretUserPool`); + } }); } } diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthrough-types.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthrough-types.ts index 4d0133a1c03..a3f630bd1cf 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthrough-types.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthrough-types.ts @@ -50,6 +50,10 @@ export interface SocialProviderResult { googleAppSecretUserPool?: string; loginwithamazonAppIdUserPool?: string; loginwithamazonAppSecretUserPool?: string; + signinwithappleClientIdUserPool?: string; + signinwithappleTeamIdUserPool?: string; + signinwithappleKeyIdUserPool?: string; + signinwithapplePrivateKeyUserPool?: string; } export interface IdentityPoolResult { diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthroughs/auth-questions.js b/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthroughs/auth-questions.js index f85c2bc0f4b..0ae3a0ff579 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthroughs/auth-questions.js +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/service-walkthroughs/auth-questions.js @@ -162,6 +162,7 @@ async function serviceWalkthrough(context, defaultValuesFilename, stringMapsFile delete context.updatingAuth.googleIos; delete context.updatingAuth.googleAndroid; delete context.updatingAuth.amazonAppId; + delete context.updatingAuth.appleAppId; } // formatting data for identity pool providers @@ -401,7 +402,7 @@ function identityPoolProviders(coreAnswers, projectType) { /* Format hosted UI providers data per lambda spec hostedUIProviderMeta is saved in parameters.json. - hostedUIprovierCreds is saved in deployment-secrets. + hostedUIproviderCreds is saved in deployment-secrets. */ function userPoolProviders(oAuthProviders, coreAnswers, prevAnswers) { if (coreAnswers.useDefault === 'default') { @@ -415,7 +416,7 @@ function userPoolProviders(oAuthProviders, coreAnswers, prevAnswers) { if (answers.hostedUI) { res.hostedUIProviderMeta = JSON.stringify( oAuthProviders.map(el => { - const delimmiter = el === 'Facebook' ? ',' : ' '; + const delimmiter = ['Facebook', 'SignInWithApple'].includes(el) ? ',' : ' '; const scopes = []; const maps = {}; attributesForMapping.forEach(a => { @@ -440,11 +441,23 @@ function userPoolProviders(oAuthProviders, coreAnswers, prevAnswers) { }), ); res.hostedUIProviderCreds = JSON.stringify( - oAuthProviders.map(el => ({ - ProviderName: el, - client_id: coreAnswers[`${el.toLowerCase()}AppIdUserPool`], - client_secret: coreAnswers[`${el.toLowerCase()}AppSecretUserPool`], - })), + oAuthProviders.map(el => { + if (el === 'SignInWithApple') { + return { + ProviderName: el, + client_id: coreAnswers[`${el.toLowerCase()}ClientIdUserPool`], + team_id: coreAnswers[`${el.toLowerCase()}TeamIdUserPool`], + key_id: coreAnswers[`${el.toLowerCase()}KeyIdUserPool`], + private_key: coreAnswers[`${el.toLowerCase()}PrivateKeyUserPool`], + }; + } else { + return { + ProviderName: el, + client_id: coreAnswers[`${el.toLowerCase()}AppIdUserPool`], + client_secret: coreAnswers[`${el.toLowerCase()}AppSecretUserPool`], + }; + } + }), ); } return res; @@ -518,8 +531,15 @@ function parseOAuthCreds(providers, metadata, envCreds) { try { const provider = parsedMetaData.find(i => i.ProviderName === el); const creds = parsedCreds.find(i => i.ProviderName === el); - providerKeys[`${el.toLowerCase()}AppIdUserPool`] = creds.client_id; - providerKeys[`${el.toLowerCase()}AppSecretUserPool`] = creds.client_secret; + if (el === 'SignInWithApple') { + providerKeys[`${el.toLowerCase()}ClientIdUserPool`] = creds.client_id; + providerKeys[`${el.toLowerCase()}TeamIdUserPool`] = creds.team_id; + providerKeys[`${el.toLowerCase()}KeyIdUserPool`] = creds.key_id; + providerKeys[`${el.toLowerCase()}PrivateKeyUserPool`] = creds.private_key; + } else { + providerKeys[`${el.toLowerCase()}AppIdUserPool`] = creds.client_id; + providerKeys[`${el.toLowerCase()}AppSecretUserPool`] = creds.client_secret; + } providerKeys[`${el.toLowerCase()}AuthorizeScopes`] = provider.authorize_scopes.split(','); } catch (e) { return null; diff --git a/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-request-adaptors.ts b/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-request-adaptors.ts index d147916eff1..709611a2993 100644 --- a/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-request-adaptors.ts +++ b/packages/amplify-category-auth/src/provider-utils/awscloudformation/utils/auth-request-adaptors.ts @@ -146,6 +146,12 @@ const socialProviderMap = ( acc.loginwithamazonAppIdUserPool = it.clientId; acc.loginwithamazonAppSecretUserPool = it.clientSecret; break; + case 'SIGN_IN_WITH_APPLE': + acc.signinwithappleClientIdUserPool = it.clientId; + acc.signinwithappleTeamIdUserPool = it.teamId; + acc.signinwithappleKeyIdUserPool = it.keyId; + acc.signinwithapplePrivateKeyUserPool = it.privateKey; + break; } return acc; }, {} as any) as SocialProviderResult; diff --git a/packages/amplify-category-auth/src/provider-utils/supported-services.ts b/packages/amplify-category-auth/src/provider-utils/supported-services.ts index 6207faf08c4..d50fdf911ec 100644 --- a/packages/amplify-category-auth/src/provider-utils/supported-services.ts +++ b/packages/amplify-category-auth/src/provider-utils/supported-services.ts @@ -242,6 +242,20 @@ export const supportedServices = { }, ], }, + { + key: 'appleAppId', + prefix: + " \n You've opted to allow users to authenticate via Sign in with Apple. If you haven't already, you'll need to go to https://developer.apple.com/account/#/welcome and configure Sign in with Apple. \n", + question: 'Enter your Bundle Identifier for your identity pool: ', + required: true, + andConditions: [ + { + key: 'authProviders', + value: 'appleid.apple.com', + operator: 'includes', + }, + ], + }, { key: 'userPoolName', question: 'Please provide a name for your user pool:', @@ -308,7 +322,8 @@ export const supportedServices = { { key: 'adminQueries', question: 'Do you want to add an admin queries API?', - learnMore: 'Admin Queries API let you perform user admin functions from your frontend. See https://docs.amplify.aws/cli/auth/admin#admin-queries-api for more.', + learnMore: + 'Admin Queries API let you perform user admin functions from your frontend. See https://docs.amplify.aws/cli/auth/admin#admin-queries-api for more.', required: true, type: 'list', map: 'booleanOptions', @@ -733,7 +748,7 @@ export const supportedServices = { key: 'hostedUI', question: 'Do you want to use an OAuth flow?', learnMore: - 'When you create a user pool in Amazon Cognito and configure a domain for it, Amazon Cognito automatically provisions a hosted web UI to let you add sign-up and sign-in pages to your app. Selecting "No" will remove any existing OAuth configuration.', + 'When you create a user pool in Amazon Cognito and configure a domain for it, Amazon Cognito automatically provisions a hosted web UI to let you add sign-up and sign-in pages to your app. Selecting "No" will remove any existing OAuth configuration.', required: true, type: 'list', map: 'booleanOptions', @@ -1164,6 +1179,56 @@ export const supportedServices = { }, ], }, + { + key: 'signinwithappleClientIdUserPool', + prefix: + " \n You've opted to allow users to authenticate via Sign in with Apple. If you haven't already, you'll need to go to https://developer.apple.com/account/#/welcome and configure Sign in with Apple. \n", + question: 'Enter your Services ID for your OAuth flow: ', + required: true, + andConditions: [ + { + key: 'authProvidersUserPool', + value: 'SignInWithApple', + operator: 'includes', + }, + ], + }, + { + key: 'signinwithappleTeamIdUserPool', + question: 'Enter your Team ID for your OAuth flow: ', + required: true, + andConditions: [ + { + key: 'authProvidersUserPool', + value: 'SignInWithApple', + operator: 'includes', + }, + ], + }, + { + key: 'signinwithappleKeyIdUserPool', + question: 'Enter your Key ID for your OAuth flow: ', + required: true, + andConditions: [ + { + key: 'authProvidersUserPool', + value: 'SignInWithApple', + operator: 'includes', + }, + ], + }, + { + key: 'signinwithapplePrivateKeyUserPool', + question: 'Enter your Private Key for your OAuth flow: ', + required: true, + andConditions: [ + { + key: 'authProvidersUserPool', + value: 'SignInWithApple', + operator: 'includes', + }, + ], + }, ], cfnFilename: 'auth-template.yml.ejs', defaultValuesFilename: 'cognito-defaults.js', diff --git a/packages/amplify-console-integration-tests/__tests__/pullAndInit.test.ts b/packages/amplify-console-integration-tests/__tests__/pullAndInit.test.ts index 7bbf3cd69ac..9cac3088dcc 100644 --- a/packages/amplify-console-integration-tests/__tests__/pullAndInit.test.ts +++ b/packages/amplify-console-integration-tests/__tests__/pullAndInit.test.ts @@ -199,6 +199,10 @@ describe('amplify app console tests', () => { GOOGLE_APP_SECRET, AMAZON_APP_ID, AMAZON_APP_SECRET, + APPLE_APP_ID, + APPLE_TEAM_ID, + APPLE_KEY_ID, + APPLE_PRIVATE_KEY, } = getSocialProviders(); await initJSProjectWithProfile(projRoot, { disableAmplifyAppCreation: false, name: 'authConsoleTest', envName }); await addAuthWithDefaultSocial(projRoot, {}); @@ -226,6 +230,10 @@ describe('amplify app console tests', () => { googleAppSecretUserPool: GOOGLE_APP_SECRET, loginwithamazonAppIdUserPool: AMAZON_APP_ID, loginwithamazonAppSecretUserPool: AMAZON_APP_SECRET, + signinwithappleClientIdUserPool: APPLE_APP_ID, + signinwithappleTeamIdUserPool: APPLE_TEAM_ID, + signinwithappleKeyIdUserPool: APPLE_KEY_ID, + signinwithapplePrivateKeyUserPool: APPLE_PRIVATE_KEY, }, }); @@ -251,6 +259,10 @@ describe('amplify app console tests', () => { googleAppSecretUserPool: GOOGLE_APP_SECRET, loginwithamazonAppIdUserPool: AMAZON_APP_ID, loginwithamazonAppSecretUserPool: AMAZON_APP_SECRET, + signinwithappleClientIdUserPool: APPLE_APP_ID, + signinwithappleTeamIdUserPool: APPLE_TEAM_ID, + signinwithappleKeyIdUserPool: APPLE_KEY_ID, + signinwithapplePrivateKeyUserPool: APPLE_PRIVATE_KEY, }, }, { diff --git a/packages/amplify-e2e-core/src/categories/auth.ts b/packages/amplify-e2e-core/src/categories/auth.ts index a229f34df8a..8d9e33530a5 100644 --- a/packages/amplify-e2e-core/src/categories/auth.ts +++ b/packages/amplify-e2e-core/src/categories/auth.ts @@ -17,6 +17,10 @@ export type AddAuthUserPoolOnlyWithOAuthSettings = AddAuthUserPoolOnlyNoOAuthSet googleAppSecret: string; amazonAppId: string; amazonAppSecret: string; + appleAppClientId: string; + appleAppTeamId: string; + appleAppKeyID: string; + appleAppPrivateKey: string; }; export type AddAuthIdentityPoolAndUserPoolWithOAuthSettings = AddAuthUserPoolOnlyWithOAuthSettings & { @@ -462,7 +466,11 @@ export function addAuthWithDefaultSocial(cwd: string, settings: any): Promise { if (!err) { @@ -516,6 +536,19 @@ export function addAuthWithDefaultSocial(cwd: string, settings: any): Promise { return new Promise((resolve, reject) => { + const { + FACEBOOK_APP_ID, + FACEBOOK_APP_SECRET, + GOOGLE_APP_ID, + GOOGLE_APP_SECRET, + AMAZON_APP_ID, + AMAZON_APP_SECRET, + APPLE_APP_ID, + APPLE_TEAM_ID, + APPLE_KEY_ID, + APPLE_PRIVATE_KEY, + } = getSocialProviders(true); + spawn(getCLIPath(), ['add', 'auth'], { cwd, stripColors: true }) .wait('Do you want to use the default authentication and security configuration?') .send(KEY_DOWN_ARROW) @@ -608,22 +641,34 @@ export function addAuthUserPoolOnly(cwd: string, settings: any): Promise { .send('a') .sendCarriageReturn() .wait('Enter your Facebook App ID for your OAuth flow') - .send('fbOAUTHid') + .send(FACEBOOK_APP_ID) .sendCarriageReturn() .wait('Enter your Facebook App Secret for your OAuth flow') - .send('fbOAUTHsecret') + .send(FACEBOOK_APP_SECRET) .sendCarriageReturn() .wait('Enter your Google Web Client ID for your OAuth flow') - .send('googOAUTHid') + .send(GOOGLE_APP_ID) .sendCarriageReturn() .wait('Enter your Google Web Client Secret for your OAuth flow') - .send('googOAUTHsecret') + .send(GOOGLE_APP_SECRET) .sendCarriageReturn() .wait('Enter your Amazon App ID for your OAuth flow') - .send('amzOAUTHid') + .send(AMAZON_APP_ID) .sendCarriageReturn() .wait('Enter your Amazon App Secret for your OAuth flow') - .send('amzOAUTHsecret') + .send(AMAZON_APP_SECRET) + .sendCarriageReturn() + .wait('Enter your Sign in with Apple Client ID for your OAuth flow') + .send(APPLE_APP_ID) + .sendCarriageReturn() + .wait('Enter your Sign in with Apple Team ID for your OAuth flow') + .send(APPLE_TEAM_ID) + .sendCarriageReturn() + .wait('Enter your Sign in with Apple Key ID for your OAuth flow') + .send(APPLE_KEY_ID) + .sendCarriageReturn() + .wait('Enter your Sign in with Apple Private Key for your OAuth flow') + .send(APPLE_PRIVATE_KEY) .sendCarriageReturn() .wait('Do you want to configure Lambda Triggers for Cognito') .send('y') @@ -764,6 +809,19 @@ export function addAuthWithGroupsAndAdminAPI(cwd: string, settings: any): Promis } export function addAuthWithMaxOptions(cwd: string, settings: any): Promise { + const { + FACEBOOK_APP_ID, + FACEBOOK_APP_SECRET, + GOOGLE_APP_ID, + GOOGLE_APP_SECRET, + AMAZON_APP_ID, + AMAZON_APP_SECRET, + APPLE_APP_ID, + APPLE_TEAM_ID, + APPLE_KEY_ID, + APPLE_PRIVATE_KEY, + } = getSocialProviders(true); + return new Promise((resolve, reject) => { spawn(getCLIPath(), ['add', 'auth'], { cwd, stripColors: true }) .wait('Do you want to use the default authentication and security configuration?') @@ -792,6 +850,9 @@ export function addAuthWithMaxOptions(cwd: string, settings: any): Promise .wait('Enter your Amazon App ID for your identity pool') .send('amazonIDPOOL') .sendCarriageReturn() + .wait('Enter your Apple App ID for your identity pool') + .send('appleIDPOOL') + .sendCarriageReturn() .wait('Please provide a name for your user pool') .sendCarriageReturn() .wait('How do you want users to be able to sign in') @@ -870,17 +931,25 @@ export function addAuthWithMaxOptions(cwd: string, settings: any): Promise .send('a') .sendCarriageReturn() .wait('Enter your Facebook App ID for your OAuth flow') - .sendLine('fbOAUTHid') + .sendLine(FACEBOOK_APP_ID) .wait('Enter your Facebook App Secret for your OAuth flow') - .sendLine('fbOAUTHsecret') + .sendLine(FACEBOOK_APP_SECRET) .wait('Enter your Google Web Client ID for your OAuth flow') - .sendLine('googOAUTHid') + .sendLine(GOOGLE_APP_ID) .wait('Enter your Google Web Client Secret for your OAuth flow') - .sendLine('googOAUTHsecret') + .sendLine(GOOGLE_APP_SECRET) .wait('Enter your Amazon App ID for your OAuth flow') - .sendLine('amzOAUTHid') + .sendLine(AMAZON_APP_ID) .wait('Enter your Amazon App Secret for your OAuth flow') - .sendLine('amzOAUTHsecret') + .sendLine(AMAZON_APP_SECRET) + .wait('Enter your Sign in with Apple Client ID for your OAuth flow') + .sendLine(APPLE_APP_ID) + .wait('Enter your Sign in with Apple Team ID for your OAuth flow') + .sendLine(APPLE_TEAM_ID) + .wait('Enter your Sign in with Apple Key ID for your OAuth flow') + .sendLine(APPLE_KEY_ID) + .wait('Enter your Sign in with Apple Private Key for your OAuth flow') + .sendLine(APPLE_PRIVATE_KEY) .wait('Do you want to configure Lambda Triggers for Cognito') .sendLine('y') .wait('Which triggers do you want to enable for Cognito') @@ -1094,6 +1163,14 @@ export function addAuthUserPoolOnlyWithOAuth(cwd: string, settings: AddAuthUserP .sendLine(settings.amazonAppId) .wait('Enter your Amazon App Secret for your OAuth flow') .sendLine(settings.amazonAppSecret) + .wait('Enter your Sign in with Apple Client ID for your OAuth flow:') + .sendLine(settings.appleAppClientId) + .wait('Enter your Sign in with Apple Team ID for your OAuth flow:') + .sendLine(settings.appleAppTeamId) + .wait('Enter your Sign in with Apple Key ID for your OAuth flow:') + .sendLine(settings.appleAppKeyID) + .wait('Enter your Sign in with Apple Private Key for your OAuth flow:') + .sendLine(settings.appleAppPrivateKey) .wait('Do you want to configure Lambda Triggers for Cognito') .sendConfirmNo() .sendEof() diff --git a/packages/amplify-e2e-core/src/utils/envVars.ts b/packages/amplify-e2e-core/src/utils/envVars.ts index ffee62a5f53..253bcf5fcda 100644 --- a/packages/amplify-e2e-core/src/utils/envVars.ts +++ b/packages/amplify-e2e-core/src/utils/envVars.ts @@ -9,6 +9,10 @@ type SocialProviders = { GOOGLE_APP_SECRET?: string; AMAZON_APP_ID?: string; AMAZON_APP_SECRET?: string; + APPLE_APP_ID?: string; + APPLE_TEAM_ID?: string; + APPLE_KEY_ID?: string; + APPLE_PRIVATE_KEY?: string; }; type EnvironmentVariables = AWSCredentials & SocialProviders; @@ -26,9 +30,26 @@ export function getSocialProviders(getEnv: boolean = false): SocialProviders { GOOGLE_APP_SECRET: 'gglAppSecret', AMAZON_APP_ID: 'amaznAppID', AMAZON_APP_SECRET: 'amaznAppID', + APPLE_APP_ID: 'com.fake.app', + APPLE_TEAM_ID: '2QLEWNDK6K', + APPLE_KEY_ID: '2QLZXKYJ8J', + // Cognito validates the private key, this is an invalidated key. + APPLE_PRIVATE_KEY: + 'MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw', }; } - const { FACEBOOK_APP_ID, FACEBOOK_APP_SECRET, GOOGLE_APP_ID, GOOGLE_APP_SECRET, AMAZON_APP_ID, AMAZON_APP_SECRET }: any = getEnvVars(); + const { + FACEBOOK_APP_ID, + FACEBOOK_APP_SECRET, + GOOGLE_APP_ID, + GOOGLE_APP_SECRET, + AMAZON_APP_ID, + AMAZON_APP_SECRET, + APPLE_APP_ID, + APPLE_TEAM_ID, + APPLE_KEY_ID, + APPLE_PRIVATE_KEY, + }: any = getEnvVars(); const missingVars = []; if (!FACEBOOK_APP_ID) { @@ -49,9 +70,32 @@ export function getSocialProviders(getEnv: boolean = false): SocialProviders { if (!AMAZON_APP_SECRET) { missingVars.push('AMAZON_APP_SECRET'); } + if (!APPLE_APP_ID) { + missingVars.push('APPLE_APP_ID'); + } + if (!APPLE_TEAM_ID) { + missingVars.push('APPLE_TEAM_ID'); + } + if (!APPLE_KEY_ID) { + missingVars.push('APPLE_KEY_ID'); + } + if (!APPLE_PRIVATE_KEY) { + missingVars.push('APPLE_PRIVATE_KEY'); + } if (missingVars.length > 0) { throw new Error(`.env file is missing the following key/values: ${missingVars.join(', ')} `); } - return { FACEBOOK_APP_ID, FACEBOOK_APP_SECRET, GOOGLE_APP_ID, GOOGLE_APP_SECRET, AMAZON_APP_ID, AMAZON_APP_SECRET }; + return { + FACEBOOK_APP_ID, + FACEBOOK_APP_SECRET, + GOOGLE_APP_ID, + GOOGLE_APP_SECRET, + AMAZON_APP_ID, + AMAZON_APP_SECRET, + APPLE_APP_ID, + APPLE_TEAM_ID, + APPLE_KEY_ID, + APPLE_PRIVATE_KEY, + }; } diff --git a/packages/amplify-e2e-tests/sample.env b/packages/amplify-e2e-tests/sample.env index 2ab3ed3b95d..6d43c33a0f0 100644 --- a/packages/amplify-e2e-tests/sample.env +++ b/packages/amplify-e2e-tests/sample.env @@ -16,6 +16,11 @@ GOOGLE_APP_SECRET= AMAZON_APP_ID= AMAZON_APP_SECRET= +APPLE_APP_ID= +APPLE_TEAM_ID= +APPLE_KEY_ID= +APPLE_PRIVATE_KEY= + #Used for delete test AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= diff --git a/packages/amplify-e2e-tests/src/__tests__/import_auth_1.test.ts b/packages/amplify-e2e-tests/src/__tests__/import_auth_1.test.ts index a5a0302de36..db8900f783c 100644 --- a/packages/amplify-e2e-tests/src/__tests__/import_auth_1.test.ts +++ b/packages/amplify-e2e-tests/src/__tests__/import_auth_1.test.ts @@ -347,7 +347,7 @@ describe('auth import userpool only', () => { // Used for creating custom app clients. This should match with web app client setting for import to work const customAppClientSettings: AppClientSettings = { - supportedIdentityProviders: ['COGNITO', 'Facebook', 'Google', 'LoginWithAmazon'], + supportedIdentityProviders: ['COGNITO', 'Facebook', 'Google', 'LoginWithAmazon', 'SignInWithApple'], allowedOAuthFlowsUserPoolClient: true, callbackURLs: ['https://sin1/', 'https://sin2/'], logoutURLs: ['https://sout1/', 'https://sout2/'], diff --git a/packages/amplify-e2e-tests/src/environment/env.ts b/packages/amplify-e2e-tests/src/environment/env.ts index ed3f4ad7cce..a02468a871e 100644 --- a/packages/amplify-e2e-tests/src/environment/env.ts +++ b/packages/amplify-e2e-tests/src/environment/env.ts @@ -136,7 +136,18 @@ export function pullEnvironment(cwd: string): Promise { } export function addEnvironmentHostedUI(cwd: string, settings: { envName: string }): Promise { - const { FACEBOOK_APP_ID, FACEBOOK_APP_SECRET, GOOGLE_APP_ID, GOOGLE_APP_SECRET, AMAZON_APP_ID, AMAZON_APP_SECRET } = getSocialProviders(); + const { + FACEBOOK_APP_ID, + FACEBOOK_APP_SECRET, + GOOGLE_APP_ID, + GOOGLE_APP_SECRET, + AMAZON_APP_ID, + AMAZON_APP_SECRET, + APPLE_APP_ID, + APPLE_TEAM_ID, + APPLE_KEY_ID, + APPLE_PRIVATE_KEY, + } = getSocialProviders(); return new Promise((resolve, reject) => { spawn(getCLIPath(), ['env', 'add'], { cwd, stripColors: true }) .wait('Do you want to use an existing environment?') @@ -159,6 +170,14 @@ export function addEnvironmentHostedUI(cwd: string, settings: { envName: string .sendLine(AMAZON_APP_ID) .wait('Enter your Amazon App Secret for your OAuth flow:') .sendLine(AMAZON_APP_SECRET) + .wait('Enter your Sign in with Apple Client ID for your OAuth flow:') + .sendLine(APPLE_APP_ID) + .wait('Enter your Sign in with Apple Team ID for your OAuth flow:') + .sendLine(APPLE_TEAM_ID) + .wait('Enter your Sign in with Apple Key ID for your OAuth flow:') + .sendLine(APPLE_KEY_ID) + .wait('Enter your Sign in with Apple Private Key for your OAuth flow:') + .sendLine(APPLE_PRIVATE_KEY) .wait('Try "amplify add api" to create a backend API and then "amplify publish" to deploy everything') .run((err: Error) => { if (!err) { diff --git a/packages/amplify-e2e-tests/src/import-helpers/settings.ts b/packages/amplify-e2e-tests/src/import-helpers/settings.ts index ade57eb7c74..a1eccc3c300 100644 --- a/packages/amplify-e2e-tests/src/import-helpers/settings.ts +++ b/packages/amplify-e2e-tests/src/import-helpers/settings.ts @@ -22,12 +22,17 @@ export const createUserPoolOnlyWithOAuthSettings = (projectPrefix: string, short signInUrl2: 'https://sin2/', signOutUrl1: 'https://sout1/', signOutUrl2: 'https://sout2/', - facebookAppId: `facebookAppId`, - facebookAppSecret: `facebookAppSecret`, - googleAppId: `googleAppId`, - googleAppSecret: `googleAppSecret`, - amazonAppId: `amazonAppId`, - amazonAppSecret: `amazonAppSecret`, + facebookAppId: 'facebookAppId', + facebookAppSecret: 'facebookAppSecret', + googleAppId: 'googleAppId', + googleAppSecret: 'googleAppSecret', + amazonAppId: 'amazonAppId', + amazonAppSecret: 'amazonAppSecret', + appleAppClientId: 'com.fake.app', + appleAppTeamId: '2QLEWNDK6K', + appleAppKeyID: '2QLZXKYJ8J', + appleAppPrivateKey: + 'MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgIltgNsTgTfSzUadYiCS0VYtDDMFln/J8i1yJsSIw5g+gCgYIKoZIzj0DAQehRANCAASI8E0L/DhR/mIfTT07v3VwQu6q8I76lgn7kFhT0HvWoLuHKGQFcFkXXCgztgBrprzd419mUChAnKE6y89bWcNw', }; }; diff --git a/packages/amplify-frontend-javascript/lib/frontend-config-creator.js b/packages/amplify-frontend-javascript/lib/frontend-config-creator.js index f39ec02a3fe..9522ef64fa9 100644 --- a/packages/amplify-frontend-javascript/lib/frontend-config-creator.js +++ b/packages/amplify-frontend-javascript/lib/frontend-config-creator.js @@ -270,7 +270,12 @@ function getCognitoConfig(cognitoResources, projectRegion) { responseType, }; - if (cognitoResource.output.GoogleWebClient || cognitoResource.output.FacebookWebClient || cognitoResource.output.AmazonWebClient) { + if ( + cognitoResource.output.GoogleWebClient || + cognitoResource.output.FacebookWebClient || + cognitoResource.output.AmazonWebClient || + cognitoResource.output.AppleWebClient + ) { idpFederation = true; } diff --git a/packages/amplify-headless-interface/schemas/auth/1/AddAuthRequest.schema.json b/packages/amplify-headless-interface/schemas/auth/1/AddAuthRequest.schema.json index 5fca7a1c908..4cdb13d4dc5 100644 --- a/packages/amplify-headless-interface/schemas/auth/1/AddAuthRequest.schema.json +++ b/packages/amplify-headless-interface/schemas/auth/1/AddAuthRequest.schema.json @@ -419,7 +419,10 @@ "description": "If defined, users will be able to login with the specified social providers.", "type": "array", "items": { - "$ref": "#/definitions/CognitoSocialProviderConfiguration" + "anyOf": [ + { "$ref": "#/definitions/CognitoSocialProviderConfiguration" }, + { "$ref": "#/definitions/CognitoSignInWithAppleProviderConfiguration" } + ] } } }, @@ -458,6 +461,42 @@ "provider" ] }, + "CognitoSignInWithAppleProviderConfiguration": { + "description": "Defines the Cognito Sign in with Apple oAuth social provider", + "type": "object", + "properties": { + "provider": { + "description": "Sign in with Apple provider name", + "enum": [ + "SIGN_IN_WITH_APPLE" + ], + "type": "string" + }, + "clientId": { + "description": "The App client ID (sometimes called app ID or service ID). Usually takes the form com.yourapp.auth", + "type": "string" + }, + "teamId": { + "description": "The Team ID", + "type": "string" + }, + "keyId": { + "description": "The key id", + "type": "string" + }, + "privateKey": { + "description": "The private key cert", + "type": "string" + } + }, + "required": [ + "clientId", + "teamId", + "keyId", + "privateKey", + "provider" + ] + }, "NoCognitoIdentityPool": { "description": "Specifies that the Cognito configuration should not include an identity pool.", "type": "object", diff --git a/packages/amplify-headless-interface/schemas/auth/1/UpdateAuthRequest.schema.json b/packages/amplify-headless-interface/schemas/auth/1/UpdateAuthRequest.schema.json index 8786511cd82..3b147bdeb40 100644 --- a/packages/amplify-headless-interface/schemas/auth/1/UpdateAuthRequest.schema.json +++ b/packages/amplify-headless-interface/schemas/auth/1/UpdateAuthRequest.schema.json @@ -370,7 +370,10 @@ "description": "If defined, users will be able to login with the specified social providers.", "type": "array", "items": { - "$ref": "#/definitions/CognitoSocialProviderConfiguration" + "anyOf": [ + { "$ref": "#/definitions/CognitoSocialProviderConfiguration" }, + { "$ref": "#/definitions/CognitoSignInWithAppleProviderConfiguration" } + ] } } } @@ -403,6 +406,42 @@ "provider" ] }, + "CognitoSignInWithAppleProviderConfiguration": { + "description": "Defines the Cognito Sign in with Apple oAuth social provider", + "type": "object", + "properties": { + "provider": { + "description": "Sign in with Apple provider name", + "enum": [ + "SIGN_IN_WITH_APPLE" + ], + "type": "string" + }, + "clientId": { + "description": "The App client ID (sometimes called app ID or service ID). Usually takes the form com.yourapp.auth", + "type": "string" + }, + "teamId": { + "description": "The Team ID", + "type": "string" + }, + "keyId": { + "description": "The key id", + "type": "string" + }, + "privateKey": { + "description": "The private key cert", + "type": "string" + } + }, + "required": [ + "clientId", + "teamId", + "keyId", + "privateKey", + "provider" + ] + }, "NoCognitoIdentityPool": { "description": "Specifies that the Cognito configuration should not include an identity pool.", "type": "object", diff --git a/packages/amplify-headless-interface/src/interface/auth/add.ts b/packages/amplify-headless-interface/src/interface/auth/add.ts index 66a0f682cc4..ac6c95eddaa 100644 --- a/packages/amplify-headless-interface/src/interface/auth/add.ts +++ b/packages/amplify-headless-interface/src/interface/auth/add.ts @@ -169,10 +169,7 @@ export interface CognitoOAuthConfiguration { socialProviderConfigurations?: CognitoSocialProviderConfiguration[]; } -/** - * Defines a Cognito oAuth social provider - */ -export interface CognitoSocialProviderConfiguration { +interface SocialProviderConfig { /** * Social providers supported by Amplify and Cognito */ @@ -187,6 +184,27 @@ export interface CognitoSocialProviderConfiguration { clientSecret: string; } +interface SignInWithAppleSocialProviderConfig { + provider: 'SIGN_IN_WITH_APPLE'; + /** + * The client ID (sometimes called apple services ID) configured with the provider. + */ + clientId: string; + + teamId: string; + /** + * The key ID (sometimes called apple private key ID) configured with the provider. + */ + keyId: string; + + privateKey: string; +} + +/** + * Defines a Cognito oAuth social provider + */ +export type CognitoSocialProviderConfiguration = SocialProviderConfig | SignInWithAppleSocialProviderConfig; + export interface CognitoPasswordPolicy { minimumLength?: number; additionalConstraints?: CognitoPasswordConstraint[]; diff --git a/yarn.lock b/yarn.lock index 11070192cf7..d327e5181e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -87,10 +87,10 @@ "@aws-amplify/api-graphql" "^1.2.5" "@aws-amplify/api-rest" "^1.2.5" -"@aws-amplify/appsync-modelgen-plugin@1.22.10": - version "1.22.10" - resolved "https://registry.yarnpkg.com/@aws-amplify/appsync-modelgen-plugin/-/appsync-modelgen-plugin-1.22.10.tgz#f4ffc4543e96672c8a60152195a7cd97094084f3" - integrity sha512-FtncIYSeCAvOtMi45PKIB20DlpzEdW20NzTy/OGza3iNb6VPK7EEar+ZslxPOcMPK9ZSUD/eB4scK9ufKLfTCw== +"@aws-amplify/appsync-modelgen-plugin@1.23.1": + version "1.23.1" + resolved "https://registry.yarnpkg.com/@aws-amplify/appsync-modelgen-plugin/-/appsync-modelgen-plugin-1.23.1.tgz#58e143a88fac10c36c93dba6739df4a5c02363d3" + integrity sha512-Ydo+KUEuDtw72dH/8oWMsF16eT/gTlqTBg5TqOH3D8AZRPcu9kWl3VP9WcXeoFNXBX/P6iVlGUHruvKzS1wCDg== dependencies: "@graphql-codegen/plugin-helpers" "^1.12.2" "@graphql-codegen/visitor-plugin-common" "1.12.2" @@ -7808,11 +7808,11 @@ amdefine@>=0.0.4: integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= amplify-codegen@^2.23.1: - version "2.23.1" - resolved "https://registry.yarnpkg.com/amplify-codegen/-/amplify-codegen-2.23.1.tgz#87f8b6eeb47833923aeae8978266583784e1839f" - integrity sha512-+4lIJAvRbfkmcVAwWAinpmuZjYV+DJI848/WcVxnUPOIxrNDwo8aJOauMU2FycTSRl1FoTp5qCYMemlPVm3bZg== + version "2.24.2" + resolved "https://registry.yarnpkg.com/amplify-codegen/-/amplify-codegen-2.24.2.tgz#29711319e58c402395873f6972d032947e252d51" + integrity sha512-JIYvJ/VKCzkAAHm/hr65N7n06vP8+wryBYHQF88+yBk3QqHiHmPSFHGgejYyE1AL7MOH3Y4Z1rw7/S89JBUpRQ== dependencies: - "@aws-amplify/appsync-modelgen-plugin" "1.22.10" + "@aws-amplify/appsync-modelgen-plugin" "1.23.1" "@aws-amplify/graphql-docs-generator" "2.3.3" "@aws-amplify/graphql-types-generator" "2.7.3" "@graphql-codegen/core" "1.8.3" @@ -17103,6 +17103,11 @@ lodash@4.17.15: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + log-driver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8"