feat(core): Add MFA (#4767)

https://linear.app/n8n/issue/ADO-947/sync-branch-with-master-and-fix-fe-e2e-tets

---------

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
Ricardo Espinoza
2023-08-23 22:59:16 -04:00
committed by GitHub
parent a01c3fbc19
commit 2b7ba6fdf1
61 changed files with 2301 additions and 105 deletions

View File

@@ -38,6 +38,7 @@ import { usePostHog } from './posthog.store';
import { useSettingsStore } from './settings.store';
import { useUIStore } from './ui.store';
import { useCloudPlanStore } from './cloudPlan.store';
import { disableMfa, enableMfa, getMfaQR, verifyMfaToken } from '@/api/mfa';
const isDefaultUser = (user: IUserResponse | null) =>
Boolean(user && user.isPending && user.globalRole && user.globalRole.name === ROLE.Owner);
@@ -68,6 +69,9 @@ export const useUsersStore = defineStore(STORES.USERS, {
isInstanceOwner(): boolean {
return isInstanceOwner(this.currentUser);
},
mfaEnabled(): boolean {
return this.currentUser?.mfaEnabled ?? false;
},
getUserById(state) {
return (userId: string): IUser | null => state.users[userId];
},
@@ -167,7 +171,12 @@ export const useUsersStore = defineStore(STORES.USERS, {
usePostHog().init(user.featureFlags);
},
async loginWithCreds(params: { email: string; password: string }): Promise<void> {
async loginWithCreds(params: {
email: string;
password: string;
mfaToken?: string;
mfaRecoveryCode?: string;
}): Promise<void> {
const rootStore = useRootStore();
const user = await login(rootStore.getRestApiContext, params);
if (!user) {
@@ -233,7 +242,11 @@ export const useUsersStore = defineStore(STORES.USERS, {
const rootStore = useRootStore();
await validatePasswordToken(rootStore.getRestApiContext, params);
},
async changePassword(params: { token: string; password: string }): Promise<void> {
async changePassword(params: {
token: string;
password: string;
mfaToken?: string;
}): Promise<void> {
const rootStore = useRootStore();
await changePassword(rootStore.getRestApiContext, params);
},
@@ -326,5 +339,31 @@ export const useUsersStore = defineStore(STORES.USERS, {
uiStore.openModal(PERSONALIZATION_MODAL_KEY);
}
},
async getMfaQR(): Promise<{ qrCode: string; secret: string; recoveryCodes: string[] }> {
const rootStore = useRootStore();
return getMfaQR(rootStore.getRestApiContext);
},
async verifyMfaToken(data: { token: string }): Promise<void> {
const rootStore = useRootStore();
return verifyMfaToken(rootStore.getRestApiContext, data);
},
async enableMfa(data: { token: string }) {
const rootStore = useRootStore();
const usersStore = useUsersStore();
await enableMfa(rootStore.getRestApiContext, data);
const currentUser = usersStore.currentUser;
if (currentUser) {
currentUser.mfaEnabled = true;
}
},
async disabledMfa() {
const rootStore = useRootStore();
const usersStore = useUsersStore();
await disableMfa(rootStore.getRestApiContext);
const currentUser = usersStore.currentUser;
if (currentUser) {
currentUser.mfaEnabled = false;
}
},
},
});