Skip to content

Commit bcab498

Browse files
Merge pull request #2805 from govuk-one-login/AUT-4249/allow-auth-app-when-picking-mfa-method
AUT-4249: Allow auth app when picking MFA method
2 parents 6f0ca10 + 33e42c9 commit bcab498

6 files changed

Lines changed: 272 additions & 140 deletions

File tree

src/components/common/state-machine/state-machine.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const USER_JOURNEY_EVENTS = {
5959
IPV_REVERIFICATION_FAILED_OR_DID_NOT_MATCH:
6060
"IPV_REVERIFICATION_FAILED_OR_DID_NOT_MATCH",
6161
MFA_RESET_ATTEMPTED_VIA_AUTH_APP: "MFA_RESET_ATTEMPTED_VIA_AUTH_APP",
62+
SELECT_AUTH_APP_MFA_METHOD: "SELECT_AUTH_APP_MFA_METHOD",
6263
};
6364

6465
const authStateMachine = createMachine(
@@ -731,6 +732,13 @@ const authStateMachine = createMachine(
731732
],
732733
},
733734
},
735+
[PATH_NAMES.HOW_DO_YOU_WANT_SECURITY_CODES]: {
736+
on: {
737+
[USER_JOURNEY_EVENTS.SELECT_AUTH_APP_MFA_METHOD]: [
738+
PATH_NAMES.ENTER_AUTHENTICATOR_APP_CODE,
739+
],
740+
},
741+
},
734742
},
735743
},
736744
{

src/components/enter-authenticator-app-code/index.njk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
classes: "govuk-label--l",
2222
isPageHeading: true
2323
},
24-
classes: "govuk-input--width-10",
24+
classes: "govuk-input--width-10 govuk-!-font-weight-bold",
2525
id: "code",
2626
name: "code",
2727
inputmode: "numeric",

src/components/how-do-you-want-security-codes/how-do-you-want-security-codes-controller.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import type { Request, Response } from "express";
2-
import { PATH_NAMES } from "../../app.constants.js";
2+
import { MFA_METHOD_TYPE, PATH_NAMES } from "../../app.constants.js";
33
import type { MfaMethod } from "../../types.js";
4+
import { getNextPathAndUpdateJourney } from "../common/constants.js";
5+
import { USER_JOURNEY_EVENTS } from "../common/state-machine/state-machine.js";
6+
import { BadRequestError } from "../../utils/error.js";
47

58
export function sortMfaMethodsBackupFirst(
69
mfaMethods: MfaMethod[]
@@ -24,9 +27,30 @@ export function howDoYouWantSecurityCodesGet(
2427
});
2528
}
2629

27-
export function howDoYouWantSecurityCodesPost(
30+
export async function howDoYouWantSecurityCodesPost(
2831
req: Request,
2932
res: Response
30-
): void {
31-
res.send("Unimplemented");
33+
): Promise<void> {
34+
const selectedMfaMethod: MfaMethod | undefined =
35+
req.session.user.mfaMethods?.find(
36+
(mfaMethod: MfaMethod) => mfaMethod.id === req.body["mfa-method-id"]
37+
);
38+
39+
if (!selectedMfaMethod) {
40+
throw new BadRequestError("No MFA methods found");
41+
}
42+
43+
if (selectedMfaMethod.type === MFA_METHOD_TYPE.AUTH_APP) {
44+
return res.redirect(
45+
await getNextPathAndUpdateJourney(
46+
req,
47+
req.path,
48+
USER_JOURNEY_EVENTS.SELECT_AUTH_APP_MFA_METHOD,
49+
null,
50+
res.locals.sessionId
51+
)
52+
);
53+
} else {
54+
res.send("Unimplemented");
55+
}
3256
}

src/components/how-do-you-want-security-codes/tests/__snapshots__/how-do-you-want-security-codes-integration.test.ts.snap

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,38 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Integration::how do you want security codes GET /how-do-you-want-security-codes should return page as expected for AUTH APP user with SMS backup 1`] = `
4+
Object {
5+
"contentId": "",
6+
"taxonomyLevel1": "authentication",
7+
"taxonomyLevel2": "",
8+
"taxonomyLevel3": "",
9+
"taxonomyLevel4": "",
10+
"taxonomyLevel5": "",
11+
}
12+
`;
13+
14+
exports[`Integration::how do you want security codes GET /how-do-you-want-security-codes should return page as expected for SMS user with AUTH APP backup 1`] = `
15+
Object {
16+
"contentId": "",
17+
"taxonomyLevel1": "authentication",
18+
"taxonomyLevel2": "",
19+
"taxonomyLevel3": "",
20+
"taxonomyLevel4": "",
21+
"taxonomyLevel5": "",
22+
}
23+
`;
24+
25+
exports[`Integration::how do you want security codes GET /how-do-you-want-security-codes should return page as expected for SMS user with SMS backup 1`] = `
26+
Object {
27+
"contentId": "",
28+
"taxonomyLevel1": "authentication",
29+
"taxonomyLevel2": "",
30+
"taxonomyLevel3": "",
31+
"taxonomyLevel4": "",
32+
"taxonomyLevel5": "",
33+
}
34+
`;
35+
336
exports[`Integration::how do you want security codes should include link to reset mfa methods 1`] = `
437
Object {
538
"contentId": "",

src/components/how-do-you-want-security-codes/tests/how-do-you-want-security-codes-controller.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import { describe } from "mocha";
22
import type { Request, Response } from "express";
33
import { expect } from "chai";
4-
import { howDoYouWantSecurityCodesGet } from "../how-do-you-want-security-codes-controller.js";
4+
import { strict as assert } from "assert";
5+
import {
6+
howDoYouWantSecurityCodesGet,
7+
howDoYouWantSecurityCodesPost,
8+
} from "../how-do-you-want-security-codes-controller.js";
59
import { mockResponse } from "mock-req-res";
610
import type { RequestOutput, ResponseOutput } from "mock-req-res";
711
import { createMockRequest } from "../../../../test/helpers/mock-request-helper.js";
812
import { PATH_NAMES } from "../../../app.constants.js";
913
import { sinon } from "../../../../test/utils/test-utils.js";
14+
import { BadRequestError } from "../../../utils/error.js";
15+
import { buildMfaMethods } from "../../../../test/helpers/mfa-helper.js";
1016

1117
describe("how do you want security codes controller", () => {
1218
let req: RequestOutput;
@@ -59,4 +65,33 @@ describe("how do you want security codes controller", () => {
5965
);
6066
});
6167
});
68+
69+
describe("howDoYouWantSecurityCodesPost", () => {
70+
it("should throw error if the user has no MFA methods", async () => {
71+
req.session.user.mfaMethods = [];
72+
73+
await assert.rejects(
74+
async () => howDoYouWantSecurityCodesPost(req, res),
75+
BadRequestError,
76+
"No MFA methods found"
77+
);
78+
});
79+
80+
it("should redirect to /enter-authenticator-app-code if 'authenticator app' is selected", async () => {
81+
req.body["mfa-method-id"] = "testAuthApp";
82+
req.session.user.mfaMethods = buildMfaMethods([
83+
{
84+
id: "testPhone",
85+
redactedPhoneNumber: "07000000000",
86+
},
87+
{ id: "testAuthApp", authApp: true },
88+
]);
89+
90+
await howDoYouWantSecurityCodesPost(req, res);
91+
92+
expect(res.redirect).to.have.been.calledWith(
93+
PATH_NAMES.ENTER_AUTHENTICATOR_APP_CODE
94+
);
95+
});
96+
});
6297
});

0 commit comments

Comments
 (0)