Skip to content

Commit

Permalink
fix: map headless auth pw recovery to auto-verified attrs (#9786)
Browse files Browse the repository at this point in the history
* fix: map headless auth pw recovery to auto-verified attrs

* Update packages/amplify-e2e-tests/src/__tests__/auth_7.test.ts

* Update packages/amplify-headless-interface/schemas/auth/1/AddAuthRequest.schema.json

* Update packages/amplify-headless-interface/schemas/auth/1/UpdateAuthRequest.schema.json
  • Loading branch information
edwardfoyle committed Feb 25, 2022
1 parent 409c5dc commit f8c9100
Show file tree
Hide file tree
Showing 18 changed files with 1,455 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,42 @@ Object {
}
`;

exports[`get add auth request adaptor translates request with autoVerifiedAttributes 1`] = `
Object {
"adminQueries": false,
"adminQueryGroup": undefined,
"aliasAttributes": Array [],
"authProviders": Array [],
"authSelections": "userPoolOnly",
"autoVerifiedAttributes": Array [
"email",
"phone_number",
],
"emailVerificationMessage": "test email verificaiton message {####}",
"emailVerificationSubject": "test email verification subject",
"identityPoolName": undefined,
"mfaConfiguration": "OFF",
"requiredAttributes": Array [
"email",
],
"resourceName": "myTestAuth",
"serviceName": "Cognito",
"smsVerificationMessage": "test sms verification message {####}",
"thirdPartyAuth": false,
"updateFlow": "manual",
"useDefault": "manual",
"userPoolGroupList": Array [],
"userPoolGroups": false,
"userPoolName": undefined,
"usernameAttributes": Array [
"email",
],
"userpoolClientReadAttributes": Array [],
"userpoolClientRefreshTokenValidity": undefined,
"userpoolClientWriteAttributes": Array [],
}
`;

exports[`get add auth request adaptor translates request without aliasAttributes 1`] = `
Object {
"adminQueries": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('get add auth request adaptor', () => {
describe('valid translations', () => {
it('translates request with minimal user pool config only', () => {
const addAuthRequest: AddAuthRequest = {
version: 1,
version: 2,
resourceName: 'myTestAuth',
serviceConfiguration: {
serviceName: 'Cognito',
Expand All @@ -36,7 +36,7 @@ describe('get add auth request adaptor', () => {
it('translates request with aliasAttributes', () => {
FeatureFlags.getBoolean = () => true;
const addAuthRequest: AddAuthRequest = {
version: 1,
version: 2,
resourceName: 'myTestAuth',
serviceConfiguration: {
serviceName: 'Cognito',
Expand All @@ -58,7 +58,7 @@ describe('get add auth request adaptor', () => {
it('translates request without aliasAttributes', () => {
FeatureFlags.getBoolean = () => true;
const addAuthRequest: AddAuthRequest = {
version: 1,
version: 2,
resourceName: 'myTestAuth',
serviceConfiguration: {
serviceName: 'Cognito',
Expand All @@ -77,13 +77,42 @@ describe('get add auth request adaptor', () => {

expect(getAddAuthRequestAdaptor('javascript')(addAuthRequest)).toMatchSnapshot();
});

it('translates request with autoVerifiedAttributes', () => {
FeatureFlags.getBoolean = () => true;
const addAuthRequest: AddAuthRequest = {
version: 2,
resourceName: 'myTestAuth',
serviceConfiguration: {
serviceName: 'Cognito',
includeIdentityPool: false,
userPoolConfiguration: {
signinMethod: CognitoUserPoolSigninMethod.EMAIL,
requiredSignupAttributes: [CognitoUserProperty.EMAIL],
autoVerifiedAttributes: [
{
type: 'EMAIL',
verificationMessage: 'test email verificaiton message {####}',
verificationSubject: 'test email verification subject',
},
{
type: 'PHONE_NUMBER',
verificationMessage: 'test sms verification message {####}',
},
],
},
},
};

expect(getAddAuthRequestAdaptor('javascript')(addAuthRequest)).toMatchSnapshot();
});
});

describe('get update auth request adaptor', () => {
describe('valid translations', () => {
it('translates empty oAuth config into hostedUI: false', () => {
const updateAuthRequest: UpdateAuthRequest = {
version: 1,
version: 2,
serviceModification: {
serviceName: 'Cognito',
userPoolModification: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export type ServiceQuestionHeadlessResult = ServiceQuestionsBaseResult &
SocialProviderResult &
IdentityPoolResult &
PasswordPolicyResult &
PasswordRecoveryResult &
AutoVerifiedAttributesResult &
MfaResult &
AdminQueriesResult &
Triggers;
Expand Down Expand Up @@ -102,7 +102,7 @@ export interface IdentityPoolResult {
audiences?: string[];
}

export interface PasswordRecoveryResult {
export interface AutoVerifiedAttributesResult {
emailVerificationMessage?: string;
emailVerificationSubject?: string;
smsVerificationMessage?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
CognitoUserPoolSigninMethod,
CognitoAdminQueries,
CognitoMFAConfiguration,
CognitoPasswordRecoveryConfiguration,
CognitoPasswordPolicy,
CognitoPasswordConstraint,
CognitoIdentityPoolConfiguration,
Expand All @@ -14,6 +13,7 @@ import {
CognitoUserPoolConfiguration,
CognitoUserPoolModification,
CognitoIdentityPoolModification,
CognitoAutoVerifiedAttributesConfiguration,
} from 'amplify-headless-interface';
import { identityPoolProviders, userPoolProviders } from '../service-walkthroughs/auth-questions';
import { isEmpty, merge } from 'lodash';
Expand All @@ -26,11 +26,11 @@ import {
AdminQueriesResult,
MfaResult,
PasswordPolicy,
PasswordRecoveryResult,
UsernameAttributes,
AliasAttributes,
AttributeType,
ServiceQuestionHeadlessResult,
AutoVerifiedAttributesResult,
} from '../service-walkthrough-types/cognito-user-input-types';
import { pascalCase } from 'change-case';
import { FeatureFlags } from 'amplify-cli-core';
Expand Down Expand Up @@ -103,7 +103,7 @@ const mutableAttributeAdaptor = (
userpoolClientWriteAttributes: (userPoolConfig.writeAttributes || []).map(att => att.toLowerCase()),
...adminQueriesMap(userPoolConfig.adminQueries),
...mfaMap(userPoolConfig.mfa),
...passwordRecoveryMap(userPoolConfig.passwordRecovery),
...autoVerifiedAttributesMap(userPoolConfig.autoVerifiedAttributes),
...passwordPolicyMap(userPoolConfig.passwordPolicy),
...mutableIdentityPoolMap(projectType, identityPoolConfig),
...oauthMap(userPoolConfig.oAuth, requiredAttributes),
Expand Down Expand Up @@ -234,25 +234,27 @@ const mfaMap = (mfaConfig: CognitoMFAConfiguration = { mode: 'OFF' }): MfaResult
};
};

// converts password recovery config to existing format
const passwordRecoveryMap = (pwRecoveryConfig?: CognitoPasswordRecoveryConfiguration): PasswordRecoveryResult => {
switch (pwRecoveryConfig?.deliveryMethod) {
case 'SMS':
return {
smsVerificationMessage: pwRecoveryConfig?.smsMessage,
autoVerifiedAttributes: ['phone_number'],
};
case 'EMAIL':
return {
emailVerificationMessage: pwRecoveryConfig?.emailMessage,
emailVerificationSubject: pwRecoveryConfig?.emailSubject,
autoVerifiedAttributes: ['email'],
};
default:
return {
autoVerifiedAttributes: [],
};
const autoVerifiedAttributesMap = (autoVerifiedAttrConfig?: CognitoAutoVerifiedAttributesConfiguration): AutoVerifiedAttributesResult => {
const result: AutoVerifiedAttributesResult = {
autoVerifiedAttributes: [],
};
if (!Array.isArray(autoVerifiedAttrConfig)) {
return result;
}

return autoVerifiedAttrConfig.reduce((result, config) => {
switch (config.type) {
case 'EMAIL':
result.autoVerifiedAttributes.push('email');
result.emailVerificationMessage = config.verificationMessage;
result.emailVerificationSubject = config.verificationSubject;
break;
case 'PHONE_NUMBER':
result.autoVerifiedAttributes.push('phone_number');
result.smsVerificationMessage = config.verificationMessage;
}
return result;
}, result);
};

const passwordConstraintMap: Record<CognitoPasswordConstraint, PasswordPolicy> = {
Expand Down
30 changes: 7 additions & 23 deletions packages/amplify-e2e-tests/src/__tests__/auth_5.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,11 @@ import {
updateHeadlessAuth,
removeHeadlessAuth,
getCloudBackendConfig,
headlessAuthImport,
} from 'amplify-e2e-core';
import { addAuthWithDefault, getBackendAmplifyMeta } from 'amplify-e2e-core';
import { createNewProjectDir, deleteProjectDir, getProjectMeta, getUserPool, getMFAConfiguration } from 'amplify-e2e-core';
import {
AddAuthRequest,
CognitoUserPoolSigninMethod,
CognitoPasswordRecoveryConfiguration,
CognitoUserProperty,
ImportAuthRequest,
UpdateAuthRequest,
} from 'amplify-headless-interface';
import { AddAuthRequest, CognitoUserPoolSigninMethod, CognitoUserProperty, UpdateAuthRequest } from 'amplify-headless-interface';
import _ from 'lodash';
import {
expectAuthProjectDetailsMatch,
expectLocalAndCloudMetaFilesMatching,
expectLocalTeamInfoHasNoCategories,
expectNoAuthInMeta,
getAuthProjectDetails,
removeImportedAuthWithDefault,
setupOgProjectWithAuth,
} from '../import-helpers';

const PROJECT_NAME = 'authTest';
const defaultsSettings = {
Expand All @@ -46,7 +29,7 @@ describe('headless auth', () => {
});
it('adds auth resource', async () => {
const addAuthRequest: AddAuthRequest = {
version: 1,
version: 2,
resourceName: 'myAuthResource',
serviceConfiguration: {
serviceName: 'Cognito',
Expand All @@ -68,7 +51,7 @@ describe('headless auth', () => {
});
it('adds auth resource with TOTP only', async () => {
const addAuthRequest: AddAuthRequest = {
version: 1,
version: 2,
resourceName: 'myAuthResource',
serviceConfiguration: {
serviceName: 'Cognito',
Expand Down Expand Up @@ -105,7 +88,7 @@ describe('headless auth', () => {

it('adds auth resource with TOTP only but enable SMS through signUp Attributes', async () => {
const addAuthRequest: AddAuthRequest = {
version: 1,
version: 2,
resourceName: 'myAuthResource',
serviceConfiguration: {
serviceName: 'Cognito',
Expand Down Expand Up @@ -136,7 +119,8 @@ describe('headless auth', () => {
});

it('adds auth resource with TOTP only but enables SMS through password recovery', async () => {
const addAuthRequest: AddAuthRequest = {
// AddAuthRequest v1
const addAuthRequest: any = {
version: 1,
resourceName: 'myAuthResource',
serviceConfiguration: {
Expand Down Expand Up @@ -173,7 +157,7 @@ describe('headless auth', () => {

it('updates existing auth resource', async () => {
const updateAuthRequest: UpdateAuthRequest = {
version: 1,
version: 2,
serviceModification: {
serviceName: 'Cognito',
userPoolModification: {
Expand Down
18 changes: 4 additions & 14 deletions packages/amplify-e2e-tests/src/__tests__/auth_7.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,11 @@ import {
initJSProjectWithProfile,
deleteProject,
amplifyPushAuth,
addHeadlessAuth,
updateHeadlessAuth,
removeHeadlessAuth,
getCloudBackendConfig,
headlessAuthImport,
createNewProjectDir,
deleteProjectDir
} from 'amplify-e2e-core';
import { addAuthWithDefault, getBackendAmplifyMeta } from 'amplify-e2e-core';
import { createNewProjectDir, deleteProjectDir, getProjectMeta, getUserPool } from 'amplify-e2e-core';
import {
AddAuthRequest,
CognitoUserPoolSigninMethod,
CognitoUserProperty,
ImportAuthRequest,
UpdateAuthRequest,
} from 'amplify-headless-interface';
import { ImportAuthRequest } from 'amplify-headless-interface';
import _ from 'lodash';
import {
expectAuthProjectDetailsMatch,
Expand Down Expand Up @@ -45,7 +35,7 @@ describe('headless auth', () => {
});

describe(' import', () => {
let ogProjectSettings: {name: string};
let ogProjectSettings: { name: string };
let ogProjectRoot: string;

beforeEach(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
]
},
"passwordRecovery": {
"description": "If defined, specifies password recovery configiuration. Default is email recovery.",
"description": "DEPRECATED. Use autoVerifiedAttributes in headless schema version 2 instead. If defined, specifies password recovery configuration. Default is email recovery.",
"anyOf": [
{
"$ref": "#/definitions/CognitoEmailPasswordRecoveryConfiguration"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"description": "If defined, specifies password constraint configuration. Default is minimum length of 8 characters."
},
"passwordRecovery": {
"description": "If defined, specifies password recovery configiuration. Default is email recovery.",
"description": "DEPRECATED. Use autoVerifiedAttributes in headless schema version 2 instead. If defined, specifies password recovery configuration. Default is email recovery.",
"anyOf": [
{
"$ref": "#/definitions/CognitoEmailPasswordRecoveryConfiguration"
Expand Down

0 comments on commit f8c9100

Please sign in to comment.