Skip to content

Commit

Permalink
Merge pull request #1331 from govuk-one-login/revert-1293-AUT-2032-mf…
Browse files Browse the repository at this point in the history
…a-pw-reset-required

Revert "mfa password reset required journey"
  • Loading branch information
dbes-gds authored Feb 2, 2024
2 parents c4419d9 + 4132958 commit fc13c80
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 328 deletions.
46 changes: 45 additions & 1 deletion src/components/common/state-machine/state-machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,51 @@ const authStateMachine = createMachine(
],
},
},
[PATH_NAMES.RESET_PASSWORD_REQUIRED]: {},
[PATH_NAMES.RESET_PASSWORD_REQUIRED]: {
on: {
[USER_JOURNEY_EVENTS.PASSWORD_CREATED]: [
{
target: [PATH_NAMES.GET_SECURITY_CODES],
cond: "isAccountPartCreated",
},
{
target: [PATH_NAMES.ENTER_AUTHENTICATOR_APP_CODE],
cond: "requiresMFAAuthAppCode",
},
{ target: [PATH_NAMES.ENTER_MFA], cond: "requiresTwoFactorAuth" },
{
target: [PATH_NAMES.UPDATED_TERMS_AND_CONDITIONS],
cond: "isLatestTermsAndConditionsAccepted",
},
{
target: [PATH_NAMES.SHARE_INFO],
cond: "isConsentRequired",
},
{ target: [PATH_NAMES.AUTH_CODE] },
],
},
[PATH_NAMES.CREATE_ACCOUNT_ENTER_PHONE_NUMBER]: {
on: {
[USER_JOURNEY_EVENTS.VERIFY_PHONE_NUMBER]: [
PATH_NAMES.CHECK_YOUR_PHONE,
],
},
meta: {
optionalPaths: [
PATH_NAMES.SECURITY_CODE_WAIT,
PATH_NAMES.SECURITY_CODE_INVALID,
PATH_NAMES.SECURITY_CODE_REQUEST_EXCEEDED,
],
},
},
meta: {
optionalPaths: [
PATH_NAMES.ENTER_EMAIL_SIGN_IN,
PATH_NAMES.ACCOUNT_LOCKED,
PATH_NAMES.SIGN_IN_OR_CREATE,
],
},
},
[PATH_NAMES.PROVE_IDENTITY]: {
on: {
[USER_JOURNEY_EVENTS.PROVE_IDENTITY_INIT]: [
Expand Down
102 changes: 47 additions & 55 deletions src/components/reset-password/reset-password-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,67 +79,59 @@ export function resetPasswordPost(
);
}
}
let mfaMethodType;
let isMfaMethodVerified;
if (support2FABeforePasswordReset && req.session.user.isAuthenticated) {
mfaMethodType = req.session.user.accountRecoveryVerifiedMfaType;
isMfaMethodVerified = !req.session.user.isAccountPartCreated;
} else {
const loginResponse = await loginService.loginUser(

const loginResponse = await loginService.loginUser(
sessionId,
email,
newPassword,
clientSessionId,
req.ip,
persistentSessionId
);

if (!loginResponse.success) {
throw new BadRequestError(
loginResponse.data.message,
loginResponse.data.code
);
}

req.session.user.redactedPhoneNumber =
loginResponse.data.redactedPhoneNumber;
req.session.user.isConsentRequired = loginResponse.data.consentRequired;
req.session.user.isLatestTermsAndConditionsAccepted =
loginResponse.data.latestTermsAndConditionsAccepted;
req.session.user.isAccountPartCreated =
!loginResponse.data.mfaMethodVerified;
if (req.session.user.isPasswordChangeRequired) {
req.session.user.isPasswordChangeRequired = false;
}

if (
!support2FABeforePasswordReset() &&
loginResponse.data.mfaMethodVerified &&
loginResponse.data.mfaMethodType === MFA_METHOD_TYPE.SMS
) {
const mfaResponse = await mfaCodeService.sendMfaCode(
sessionId,
email,
newPassword,
clientSessionId,
email,
req.ip,
persistentSessionId
persistentSessionId,
false,
xss(req.cookies.lng as string)
);

if (!loginResponse.success) {
if (!mfaResponse.success) {
const path = getErrorPathByCode(mfaResponse.data.code);
if (path) {
return res.redirect(path);
}
throw new BadRequestError(
loginResponse.data.message,
loginResponse.data.code
);
}

req.session.user.redactedPhoneNumber =
loginResponse.data.redactedPhoneNumber;
req.session.user.isConsentRequired = loginResponse.data.consentRequired;
req.session.user.isLatestTermsAndConditionsAccepted =
loginResponse.data.latestTermsAndConditionsAccepted;
req.session.user.isAccountPartCreated =
!loginResponse.data.mfaMethodVerified;
if (req.session.user.isPasswordChangeRequired) {
req.session.user.isPasswordChangeRequired = false;
}

if (
!support2FABeforePasswordReset() &&
loginResponse.data.mfaMethodVerified &&
loginResponse.data.mfaMethodType === MFA_METHOD_TYPE.SMS
) {
const mfaResponse = await mfaCodeService.sendMfaCode(
sessionId,
clientSessionId,
email,
req.ip,
persistentSessionId,
false,
xss(req.cookies.lng as string)
mfaResponse.data.message,
mfaResponse.data.code
);

if (!mfaResponse.success) {
const path = getErrorPathByCode(mfaResponse.data.code);
if (path) {
return res.redirect(path);
}
throw new BadRequestError(
mfaResponse.data.message,
mfaResponse.data.code
);
}
}
mfaMethodType = loginResponse.data.mfaMethodType;
isMfaMethodVerified = loginResponse.data.mfaMethodVerified;
}

return res.redirect(
Expand All @@ -152,8 +144,8 @@ export function resetPasswordPost(
requiresTwoFactorAuth: !support2FABeforePasswordReset(),
isLatestTermsAndConditionsAccepted:
req.session.user.isLatestTermsAndConditionsAccepted,
mfaMethodType: mfaMethodType,
isMfaMethodVerified: isMfaMethodVerified,
mfaMethodType: loginResponse.data.mfaMethodType,
isMfaMethodVerified: loginResponse.data.mfaMethodVerified,
support2FABeforePasswordReset: support2FABeforePasswordReset(),
},
res.locals.sessionId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,50 +270,5 @@ describe("reset password controller (in 6 digit code flow)", () => {

expect(res.redirect).to.have.calledWith(PATH_NAMES.ENTER_MFA);
});

it("should not request 2fa and not login user when user already logged in", async () => {
process.env.SUPPORT_2FA_B4_PASSWORD_RESET = "1";
const fakeResetService: ResetPasswordServiceInterface = {
updatePassword: sinon.fake.returns({ success: true }),
} as unknown as ResetPasswordServiceInterface;
const fakeLoginService: EnterPasswordServiceInterface = {
loginUser: sinon.fake.returns({
success: true,
data: {
redactedPhoneNumber: "1234",
consentRequired: false,
latestTermsAndConditionsAccepted: true,
mfaMethodVerified: true,
mfaRequired: false,
mfaMethodType: MFA_METHOD_TYPE.SMS,
passwordChangeRequired: params.passwordChangeRequired,
},
}),
} as unknown as EnterPasswordServiceInterface;
fakeLoginService.loginUser;
const fakeMfAService: MfaServiceInterface = {
sendMfaCode: sinon.fake.returns({ success: true }),
} as unknown as MfaServiceInterface;

req.session.user = {
email: "[email protected]",
isAuthenticated: true,
isAccountPartCreated: false,
accountRecoveryVerifiedMfaType: MFA_METHOD_TYPE.SMS,
};
req.body.password = "Password1";

await resetPasswordPost(
fakeResetService,
fakeLoginService,
fakeMfAService
)(req as Request, res as Response);

expect(fakeResetService.updatePassword).to.have.been.calledOnce;
expect(fakeLoginService.loginUser).to.not.have.been.called;
expect(fakeMfAService.sendMfaCode).to.not.have.been.called;

expect(res.redirect).to.have.calledWith(PATH_NAMES.AUTH_CODE);
});
});
});
Loading

0 comments on commit fc13c80

Please sign in to comment.