Skip to content

Commit

Permalink
BREAKING CHANGE: remove shouldProceedWithEmailAuthenticator for idx m…
Browse files Browse the repository at this point in the history
…odule (#1274)

OKTA-494493 BREAKING CHANGE: remove shouldProceedWithEmailAuthenticator for idx module
  • Loading branch information
shuowu committed Aug 30, 2022
1 parent 9daddc1 commit 6506f30
Show file tree
Hide file tree
Showing 15 changed files with 100 additions and 102 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- [#1181](https://github.com/okta/okta-auth-js/pull/1181) Removes legacy PKCE/OAuth storage
- [#1271](https://github.com/okta/okta-auth-js/pull/1271) Removes `options` field from `NextStep` of IDX transaction

- [#1274](https://github.com/okta/okta-auth-js/pull/1274) Removes shouldProceedWithEmailAuthenticator option from idx module
## 6.8.0

### Other
Expand Down
41 changes: 0 additions & 41 deletions lib/idx/remediators/AuthenticatorVerificationData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,55 +11,14 @@
* See the License for the specific language governing permissions and limitations under the License.
*/


import { AuthSdkError } from '../../errors';
import { AuthenticatorData, AuthenticatorDataValues } from './Base/AuthenticatorData';
import { IdxRemediation, RemediateOptions } from '../types';

export type AuthenticatorVerificationDataValues = AuthenticatorDataValues;

export class AuthenticatorVerificationData extends AuthenticatorData<AuthenticatorVerificationDataValues> {
static remediationName = 'authenticator-verification-data';

shouldProceedWithEmailAuthenticator: boolean; // will be removed in next major version

constructor(
remediation: IdxRemediation,
values: AuthenticatorDataValues = {},
options: RemediateOptions = {}
) {
super(remediation, values);

// will be removed in next major version
this.shouldProceedWithEmailAuthenticator = options.shouldProceedWithEmailAuthenticator !== false
&& this.authenticator.methods.length === 1
&& this.authenticator.methods[0].type === 'email';
}

canRemediate() {
// auto proceed if there is only one method (will be removed in next major version)
if (this.shouldProceedWithEmailAuthenticator !== false) {
return true;
}
return super.canRemediate();
}

mapAuthenticator() {
// auto proceed with the only methodType option
if (this.shouldProceedWithEmailAuthenticator !== false) {
const authenticatorFromRemediation = this.getAuthenticatorFromRemediation();
return authenticatorFromRemediation.form?.value.reduce((acc, curr) => {
if (curr.value) {
acc[curr.name] = curr.value;
} else if (curr.options) {
acc[curr.name] = curr.options![0].value;
} else {
throw new AuthSdkError(`Unsupported authenticator data type: ${curr}`);
}
return acc;
}, {});
}

return this.getAuthenticatorData();
}

Expand Down
3 changes: 0 additions & 3 deletions lib/idx/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ function initializeValues(options: RunOptions) {
'step',
'useGenericRemediator',
'exchangeCodeForTokens',
'shouldProceedWithEmailAuthenticator'
];
const values = { ...options };
knownOptions.forEach(option => {
Expand Down Expand Up @@ -164,7 +163,6 @@ async function getDataFromRemediate(authClient, data: RunData): Promise<RunData>
actions,
flow,
step,
shouldProceedWithEmailAuthenticator, // will be removed in next major version
useGenericRemediator,
} = options;

Expand Down Expand Up @@ -192,7 +190,6 @@ async function getDataFromRemediate(authClient, data: RunData): Promise<RunData>
actions,
flow,
step,
shouldProceedWithEmailAuthenticator, // will be removed in next major version
useGenericRemediator,
}
);
Expand Down
1 change: 0 additions & 1 deletion lib/idx/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export interface IntrospectOptions extends IdxOptions {
export interface RemediateOptions extends IdxOptions {
remediators?: RemediationFlow;
actions?: RemediateAction[];
shouldProceedWithEmailAuthenticator?: boolean; // will be removed in next major version
useGenericRemediator?: boolean; // beta
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,25 +80,26 @@ router.post('/challenge-authenticator/okta_email', async (req, res, next) => {
});

router.get('/verify-authenticator/okta_email', (req, res) => {
const {
idx: { nextStep: { inputs } }
} = req.getFlowStates();
const { options } = inputs[0];
renderPage({
req, res,
render: () => renderTemplate(req, res, 'authenticator', {
title: 'Verify email authenticator',
input: {
type: 'text',
name: 'verificationCode',
},
action: '/challenge-authenticator/okta_email',
render: () => renderTemplate(req, res, 'select-authenticator-method', {
title: 'Verify using email authenticator',
action: '/verify-authenticator/okta_email',
options,
})
});
});

router.post('/verify-authenticator/okta_email', async (req, res, next) => {
const { verificationCode } = req.body;
const { methodType } = req.body;
const authClient = getAuthClient(req);
const transaction = await authClient.idx.proceed({ verificationCode });
const transaction = await authClient.idx.proceed({ methodType });
handleTransaction({ req, res, next, authClient, transaction });
});
});

// Handle enroll authenticator -- email
router.get('/enroll-authenticator/okta_email', (req, res) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
{{>head}}
</head>
<body id="samples">

{{>menu}}

<div class="okta-sign-in-form ui center aligned relaxed grid">
<div class="row">
<div id="page-title-header" class="ui header">
<h2>{{title}}</h2>
</div>
</div>

<div class="row">
{{>formMessages}}
</div>

<div class="row">
<form id="verify-form" class="ui large form" action="{{action}}" method="POST">
<div class="field">
<div class="default text">Please choose the method for this factor</div>
<select id="authenticator-method-options" class="ui selection dropdown" name="methodType">
{{#options}}
<option value="{{value}}">{{label}}</option>
{{/options}}
</select>
</div>
<button id="submit-button" class="ui fluid large primary submit button" type="submit">
Next
</button>
</form>
</div>

{{>cancel}}

</div>
</body>
</html>
6 changes: 6 additions & 0 deletions samples/test/features/identifier-first-auth.feature
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ Feature: Login with Identifier First
Then she is redirected to the "Select Authenticator" page
When she selects the "Email" factor
And she submits the form
Then she is redirected to the "Verify Email" page
When she selects "Email" from the list of methods
And she submits the form
Then the screen changes to receive an input for a Email code
When she inputs the correct code from her "Email"
And she submits the form
Expand All @@ -38,6 +41,9 @@ Feature: Login with Identifier First
Then she is redirected to the "Select Authenticator" page
When she selects the "Email" factor
And she submits the form
Then she is redirected to the "Verify Email" page
When she selects "Email" from the list of methods
And she submits the form
And she clicks the Email magic link
Then she is redirected to the "Root" page
And she sees a table with her profile info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ Feature: Multi-Factor Authentication with Password and Email Magic Link
And she has inserted her password
And her password is correct
When she submits the form
# ENG_REMEMBER_LAST_USED_FACTOR_OIE feature avoids these steps
# Then she is redirected to the "Select Authenticator" page
# When she selects the "Email" factor
# And she submits the form
Then she is redirected to the "Verify Email" page
When she selects "Email" from the list of methods
And she submits the form
And she clicks the Email magic link
Then she is redirected to the "Root" page
And she sees a table with her profile info
Expand Down
14 changes: 6 additions & 8 deletions samples/test/features/mfa-password-and-email.feature
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ Feature: Multi-Factor Authentication with Password and Email
When she fills in her username
And she fills in her correct password
And she submits the form
# ENG_REMEMBER_LAST_USED_FACTOR_OIE feature avoids these steps
# Then she is redirected to the "Select Authenticator" page
# When she selects the "Email" factor
# And she submits the form
Then she is redirected to the "Verify Email" page
When she selects "Email" from the list of methods
And she submits the form
Then she is redirected to the "Challenge email authenticator" page
When she inputs an incorrect code
And she submits the form
Expand All @@ -29,10 +28,9 @@ Feature: Multi-Factor Authentication with Password and Email
And she has inserted her password
And her password is correct
When she submits the form
# ENG_REMEMBER_LAST_USED_FACTOR_OIE feature avoids these steps
# Then she is redirected to the "Select Authenticator" page
# When she selects the "Email" factor
# And she submits the form
Then she is redirected to the "Verify Email" page
When she selects "Email" from the list of methods
And she submits the form
Then the screen changes to receive an input for a Email code
When she inputs the correct code from her "Email"
And she submits the form
Expand Down
8 changes: 3 additions & 5 deletions samples/test/features/self-service-password-recovery.feature
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,9 @@ Background:
Then she is redirected to the "Self Service Password Reset" page
When she inputs her correct Email
And she submits the form
# ENG_REMEMBER_LAST_USED_FACTOR_OIE feature avoids these steps
# Then she is redirected to the "Select Authenticator" page
# And password authenticator is not in options
# When she selects the "Email" factor
# And she submits the form
Then she is redirected to the "Verify Email" page
When she selects "Email" from the list of methods
And she submits the form
Then she sees a page to challenge her email authenticator
When she inputs the correct code from her "Email"
And she submits the form
Expand Down
8 changes: 8 additions & 0 deletions samples/test/steps/when.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import setInputField from '../support/action/setInputField';
import { camelize } from '../util';
import getCodeFromSMS from '../support/action/getCodeFromSMS';
import selectEnrollMethod from '../support/action/selectEnrollMethod';
import selectOption from '../support/action/selectOption';

When(
'she clicks the {string} button',
Expand Down Expand Up @@ -297,6 +298,13 @@ When(
selectVerifyBySms
);

When(
'she selects {string} from the list of methods',
async (methodType: string) => {
await selectOption('value', methodType, '#authenticator-method-options');
}
);

When(
/^She inputs a invalid phone number$/,
enterIncorrectPhoneNumberFormat
Expand Down
19 changes: 19 additions & 0 deletions samples/test/support/selectors/VerifyEmail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*!
* Copyright (c) 2015-present, Okta, Inc. and/or its affiliates. All rights reserved.
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/

import { PageWithTitle } from './Page';

class VerifyEmail extends PageWithTitle {
title = 'Verify using email authenticator';
}

export default new VerifyEmail();
2 changes: 2 additions & 0 deletions samples/test/support/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import SelectAuthenticator from './SelectAuthenticator';
import PasswordReset from './PasswordReset';
import Home from './Home';
import { Page } from './Page';
import VerifyEmail from './VerifyEmail';
import VerifyPhone from './VerifyPhone';
import EnrollGoogleAuthenticator from './EnrollGoogleAuthenticator';
import ChallengeEmailAuthenticator from './ChallengeEmailAuthenticator';
Expand Down Expand Up @@ -67,6 +68,7 @@ const pages: { [key: string]: Page } = {
'Root View': Home,
'Set up Password': PasswordSetup,
'Enroll email authenticator': EnrollEmailAuthenticator,
'Verify Email': VerifyEmail,
'Verify Phone': VerifyPhone,
'Challenge phone authenticator': ChallengePhoneAuthenticator,
'Challenge Security Question': ChallengeSecurityQuestion,
Expand Down
23 changes: 0 additions & 23 deletions test/spec/idx/authenticate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1203,29 +1203,6 @@ describe('idx/authenticate', () => {
});
});

it('can auto select email methodType as authenticator verification data', async () => {
const {
authClient,
verificationDataResponse,
verifyEmailResponse
} = testContext;

jest.spyOn(verificationDataResponse, 'proceed').mockResolvedValue(verifyEmailResponse);
jest.spyOn(mocked.introspect, 'introspect').mockResolvedValue(verificationDataResponse);
const res = await authenticate(authClient);
expect(verificationDataResponse.proceed).toHaveBeenCalledWith('authenticator-verification-data', {
authenticator: {
id: 'id-email'
}
});
expect(res).toMatchObject({
status: IdxStatus.PENDING,
nextStep: {
name: 'challenge-authenticator'
}
});
});

it('returns a PENDING error if an invalid code is provided', async () => {
const {
authClient,
Expand Down
6 changes: 0 additions & 6 deletions test/spec/idx/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,11 @@ describe('idx/run', () => {
const flow = 'register';
const username = 'x';
const password = 'y';
const shouldProceedWithEmailAuthenticator = false;
const options: AuthenticationOptions = {
username,
password,
flow,
useGenericRemediator: true,
shouldProceedWithEmailAuthenticator // will be removed in next major version
};
const values = {
username,
Expand All @@ -243,7 +241,6 @@ describe('idx/run', () => {
flow,
flowMonitor,
useGenericRemediator: true,
shouldProceedWithEmailAuthenticator, // will be removed in next major version
});
});

Expand All @@ -260,12 +257,10 @@ describe('idx/run', () => {
const flow = 'register';
const username = 'x';
const password = 'y';
const shouldProceedWithEmailAuthenticator = false;
const options: AuthenticationOptions = {
username,
password,
flow,
shouldProceedWithEmailAuthenticator // will be removed in next major version
};
const values = {
username,
Expand All @@ -280,7 +275,6 @@ describe('idx/run', () => {
actions,
flow,
flowMonitor,
shouldProceedWithEmailAuthenticator, // will be removed in next major version
useGenericRemediator: true,
});
});
Expand Down

0 comments on commit 6506f30

Please sign in to comment.