Skip to content

Commit 1f5ad09

Browse files
authored
Merge pull request #19471 from mozilla/FXA-12235
task(settings): Wrap create account recovery keys with MFA guard
2 parents 7217918 + e8fc8ef commit 1f5ad09

21 files changed

Lines changed: 206 additions & 23 deletions

File tree

packages/functional-tests/tests/key-stretching-v2/recoveryKey.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ test.describe('severity-2 #smoke', () => {
114114
await settings.goto(`${resetVersion.query}`);
115115
await page.waitForURL(/settings/);
116116
await settings.recoveryKey.createButton.click();
117+
118+
await settings.confirmMfaGuard(accountDetails.email);
119+
117120
const key = await recoveryKey.createRecoveryKey(
118121
accountDetails.password,
119122
HINT

packages/functional-tests/tests/key-stretching-v2/recoveryKeyUpgrade.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ test.describe('severity-2 #smoke', () => {
2929
await expect(settings.recoveryKey.status).toHaveText('Not Set');
3030

3131
await settings.recoveryKey.createButton.click();
32+
33+
await settings.confirmMfaGuard(email);
34+
3235
await recoveryKey.createRecoveryKey(password, HINT);
3336

3437
await expect(settings.recoveryKey.status).toHaveText('Enabled');

packages/functional-tests/tests/misc/recoveryKeyPromoInline.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ test.describe('recovery key promo', () => {
6464
await signin.fillOutPasswordForm(credentials.password);
6565
await page.waitForURL(/settings/);
6666
await settings.recoveryKey.createButton.click();
67+
await settings.confirmMfaGuard(credentials.email);
6768
await recoveryKey.acknowledgeInfoForm();
6869
await recoveryKey.fillOutConfirmPasswordForm(credentials.password);
6970
await recoveryKey.clickDownload();

packages/functional-tests/tests/misc/recoveryKeyPromoSettingsBanner.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ test.describe('recovery key promo', () => {
2727

2828
await inlineRecoveryKey.getBannerCreateLink().click();
2929

30+
await settings.confirmMfaGuard(credentials.email);
31+
3032
await recoveryKey.acknowledgeInfoForm();
3133
await recoveryKey.fillOutConfirmPasswordForm(credentials.password);
3234

@@ -57,6 +59,8 @@ test.describe('recovery key promo', () => {
5759

5860
await inlineRecoveryKey.getBannerCreateLink().click();
5961

62+
await settings.confirmMfaGuard(credentials.email);
63+
6064
await recoveryKey.acknowledgeInfoForm();
6165
await recoveryKey.fillOutConfirmPasswordForm(credentials.password);
6266

packages/functional-tests/tests/resetPassword/oauthResetPasswordRecoveryKey.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ test.describe('severity-1 #smoke', () => {
2222

2323
// Goes to settings and enables the account recovery key on user's account.
2424
await settings.recoveryKey.createButton.click();
25+
26+
await settings.confirmMfaGuard(credentials.email);
27+
2528
const accountRecoveryKey = await recoveryKey.createRecoveryKey(
2629
credentials.password,
2730
'hint'

packages/functional-tests/tests/resetPassword/resetPassword2FA.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ test.describe('severity-1 #smoke', () => {
143143

144144
// Create recovery key
145145
await settings.recoveryKey.createButton.click();
146+
147+
await settings.confirmMfaGuard(credentials.email);
148+
146149
const key = await recoveryKey.createRecoveryKey(
147150
credentials.password,
148151
'hint'
@@ -218,6 +221,9 @@ test.describe('severity-1 #smoke', () => {
218221

219222
// Create recovery key
220223
await settings.recoveryKey.createButton.click();
224+
225+
await settings.confirmMfaGuard(credentials.email);
226+
221227
const key = await recoveryKey.createRecoveryKey(
222228
credentials.password,
223229
'hint'
@@ -287,6 +293,9 @@ test.describe('severity-1 #smoke', () => {
287293

288294
// Create recovery key
289295
await settings.recoveryKey.createButton.click();
296+
297+
await settings.confirmMfaGuard(credentials.email);
298+
290299
await recoveryKey.createRecoveryKey(credentials.password, 'hint');
291300

292301
// Verify status as 'enabled'
@@ -357,6 +366,9 @@ test.describe('severity-1 #smoke', () => {
357366

358367
// Create recovery key
359368
await settings.recoveryKey.createButton.click();
369+
370+
await settings.confirmMfaGuard(credentials.email);
371+
360372
await recoveryKey.createRecoveryKey(credentials.password, 'hint');
361373

362374
// Verify status as 'enabled'

packages/functional-tests/tests/resetPassword/resetPasswordRecoveryKey.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5+
import { emit } from 'node:process';
56
import { expect, test } from '../../lib/fixtures/standard';
67
import { SettingsPage } from '../../pages/settings';
78
import { RecoveryKeyPage } from '../../pages/settings/recoveryKey';
@@ -26,6 +27,7 @@ test.describe('severity-1 #smoke', () => {
2627
);
2728

2829
const key = await enableRecoveryKey(
30+
credentials.email,
2931
credentials.password,
3032
recoveryKey,
3133
settings
@@ -127,7 +129,12 @@ test.describe('severity-1 #smoke', () => {
127129
signin
128130
);
129131

130-
await enableRecoveryKey(credentials.password, recoveryKey, settings);
132+
await enableRecoveryKey(
133+
credentials.email,
134+
credentials.password,
135+
recoveryKey,
136+
settings
137+
);
131138

132139
await settings.signOut();
133140

@@ -170,6 +177,7 @@ test.describe('severity-1 #smoke', () => {
170177
);
171178

172179
const key = await enableRecoveryKey(
180+
credentials.email,
173181
credentials.password,
174182
recoveryKey,
175183
settings
@@ -223,13 +231,17 @@ test.describe('severity-1 #smoke', () => {
223231
}
224232

225233
async function enableRecoveryKey(
234+
email: string,
226235
password: string,
227236
recoveryKey: RecoveryKeyPage,
228237
settings: SettingsPage
229238
): Promise<string> {
230239
await expect(settings.recoveryKey.status).toHaveText('Not Set');
231240

232241
await settings.recoveryKey.createButton.click();
242+
243+
await settings.confirmMfaGuard(email);
244+
233245
const key = await recoveryKey.createRecoveryKey(password, 'hint');
234246

235247
await expect(settings.settingsHeading).toBeVisible();

packages/functional-tests/tests/settings/recoveryKey.spec.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ test.describe('severity-1 #smoke', () => {
1919
pages: { page, recoveryKey, settings, signin },
2020
testAccountTracker,
2121
}) => {
22-
const { password } = await signInAccount(
22+
const { email, password } = await signInAccount(
2323
target,
2424
page,
2525
settings,
@@ -33,6 +33,9 @@ test.describe('severity-1 #smoke', () => {
3333
await expect(settings.recoveryKey.status).toHaveText('Not Set');
3434

3535
await settings.recoveryKey.createButton.click();
36+
37+
await settings.confirmMfaGuard(email);
38+
3639
await recoveryKey.acknowledgeInfoForm();
3740
await recoveryKey.fillOutConfirmPasswordForm(password);
3841

@@ -61,6 +64,9 @@ test.describe('severity-1 #smoke', () => {
6164
await expect(settings.recoveryKey.status).toHaveText('Not Set');
6265

6366
await settings.recoveryKey.createButton.click();
67+
68+
await settings.confirmMfaGuard(credentials.email);
69+
6470
await recoveryKey.acknowledgeInfoForm();
6571
await recoveryKey.fillOutConfirmPasswordForm(credentials.password);
6672

@@ -118,6 +124,9 @@ test.describe('severity-1 #smoke', () => {
118124
await expect(settings.recoveryKey.status).toHaveText('Not Set');
119125

120126
await settings.recoveryKey.createButton.click();
127+
128+
await settings.confirmMfaGuard(credentials.email);
129+
121130
await recoveryKey.createRecoveryKey(credentials.password, HINT);
122131
await expect(page.getByRole('alert')).toHaveText(
123132
'Account recovery key created'

packages/fxa-auth-client/lib/client.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,16 @@ export default class AuthClient {
21072107
);
21082108
}
21092109

2110+
/**
2111+
* Creates an account recovery key that can be used to restore account data in the password is lost.
2112+
* @param sessionToken
2113+
* @param recoveryKeyId
2114+
* @param recoveryData
2115+
* @param enabled
2116+
* @param replaceKey
2117+
* @param headers
2118+
* @returns
2119+
*/
21102120
async createRecoveryKey(
21112121
sessionToken: hexstring,
21122122
recoveryKeyId: string,
@@ -2128,6 +2138,37 @@ export default class AuthClient {
21282138
);
21292139
}
21302140

2141+
/**
2142+
* Creates an account recovery key that can be used to restore account data in the password is lost.
2143+
* @param sessionToken
2144+
* @param recoveryKeyId
2145+
* @param recoveryData
2146+
* @param enabled
2147+
* @param replaceKey
2148+
* @param headers
2149+
* @returns
2150+
*/
2151+
async createRecoveryKeyWithJwt(
2152+
jwt: string,
2153+
recoveryKeyId: string,
2154+
recoveryData: any,
2155+
enabled: boolean = true,
2156+
replaceKey: boolean = false,
2157+
headers?: Headers
2158+
): Promise<{}> {
2159+
return this.jwtPost(
2160+
'/mfa/recoveryKey',
2161+
jwt,
2162+
{
2163+
recoveryKeyId,
2164+
recoveryData,
2165+
enabled,
2166+
replaceKey,
2167+
},
2168+
headers
2169+
);
2170+
}
2171+
21312172
async getRecoveryKey(
21322173
accountResetToken: hexstring,
21332174
recoveryKeyId: string,

packages/fxa-auth-server/config/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2498,7 +2498,7 @@ const convictConf = convict({
24982498
env: 'MFA__ENABLED',
24992499
},
25002500
actions: {
2501-
default: ['test', '2fa', 'email'],
2501+
default: ['test', '2fa', 'email', 'recovery_key'],
25022502
doc: 'Actions protected by MFA',
25032503
format: Array,
25042504
env: 'MFA__ACTIONS',

0 commit comments

Comments
 (0)