-
Notifications
You must be signed in to change notification settings - Fork 8.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Allow disabling MFA using recovery code #11908
base: master
Are you sure you want to change the base?
fix: Allow disabling MFA using recovery code #11908
Conversation
@@ -2,6 +2,6 @@ import { ForbiddenError } from './forbidden.error'; | |||
|
|||
export class InvalidMfaCodeError extends ForbiddenError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should change the name of this error class as well, if it's not only about mfa code anymore. Is this used in other places where the error might now be incorrect?
@@ -331,9 +331,10 @@ export const useUsersStore = defineStore(STORES.USERS, () => { | |||
} | |||
}; | |||
|
|||
const disableMfa = async (mfaCode: string) => { | |||
const disableMfa = async (mfaCode: string, recoveryCode: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be:
const disableMfa = async (mfaCode: string, recoveryCode: string) => { | |
const disableMfa = async (mfaCode?: string, recoveryCode?: string) => { |
?
@@ -2608,7 +2609,8 @@ | |||
"mfa.setup.step2.toast.setupFinished.message": "Two-factor authentication enabled", | |||
"mfa.setup.step2.toast.setupFinished.error.message": "Error enabling two-factor authentication", | |||
"mfa.setup.step2.toast.tokenExpired.error.message": "MFA token expired. Close the modal and enable MFA again", | |||
"mfa.prompt.code.modal.title": "Two-factor code required", | |||
"mfa.prompt.code.modal.title": "Two-factor code or recovery code required", | |||
"mfa.prompt.code.modal.divider": "Or", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"mfa.prompt.code.modal.divider": "Or", | |
"mfa.prompt.code.modal.divider": "or", |
promptMfaCodeBus.emit('close', { | ||
mfaCode: mfaCode.value, | ||
recoveryCode: recoveryCode.value, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should map this to an object that only has one or the other, not both.
packages/editor-ui/src/api/mfa.ts
Outdated
export type DisableMfaParams = { | ||
token: string; | ||
recoveryCode: string; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type is incorrect, as only one or the other is required. Would this work?
export type DisableMfaParams = { | |
token: string; | |
recoveryCode: string; | |
}; | |
export type DisableMfaParams = { token: string; } | { recoveryCode: string; } |
or this?
export type DisableMfaParams = { | |
token: string; | |
recoveryCode: string; | |
}; | |
export type DisableMfaParams = { | |
token?: string; | |
recoveryCode?: string; | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I always send both because in the backend we have a function that check both and return true/false depending on whether one of the them is valid. It's the same function to login with MFA. The alternative would have been to check in the FE, and in the BE for which one we are sending and validate always only the one we send, and that would have been some IF's conditions that I wanted to avoid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But yeah, I see where you are coming from that is kind of consuming that you need to send both. Will address
The form now allows entering both MFA code and recovery code. I think it prefers the MFA code in that case. Would probably make more sense to allow user to input only one or the other, and have the TS types match that |
We could: 1 - Add an info box saying that if you send both, the token takes priority. |
Yeah I think option #4 would be the best one 👍 |
Also updates the UI to allow the use of recovery codes when disabling MFA
Codecov ReportAttention: Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work 👌 Few comments. Also I would prefer if the separated the renaming refactor into a separate PR. That way the changes stay separate and are easier to for example revert if ever needed
packages/editor-ui/src/components/PromptMfaCodeModal/PromptMfaCodeModal.vue
Outdated
Show resolved
Hide resolved
packages/editor-ui/src/components/PromptMfaCodeModal/PromptMfaCodeModal.vue
Outdated
Show resolved
Hide resolved
@tomi 🙏 Thanks for the feedback. Applied it all and whenever I have time I will split this PR into two as you suggested. |
Summary
1 - Allow users to disable MFA also using the recovery code
2 - Standardize how we refer to MFA code and recovery code
Before
Now
Related Linear tickets, Github issues, and Community forum posts
https://linear.app/n8n/issue/ADO-2936/can-not-disable-mfa-with-recovery-code
Review / Merge checklist
release/backport
(if the PR is an urgent fix that needs to be backported)