diff --git a/crates/defguard_core/src/handlers/auth.rs b/crates/defguard_core/src/handlers/auth.rs index ac1ba97774..c667776651 100644 --- a/crates/defguard_core/src/handlers/auth.rs +++ b/crates/defguard_core/src/handlers/auth.rs @@ -675,8 +675,9 @@ pub async fn totp_disable( session: SessionInfo, context: ApiRequestContext, State(appstate): State, + username: Path, ) -> ApiResult { - let mut user = session.user; + let mut user = user_for_admin_or_self(&appstate.pool, &session, &username).await?; debug!("Disabling TOTP for user {}", user.username); user.disable_totp(&appstate.pool).await?; user.verify_mfa_state(&appstate.pool).await?; @@ -840,8 +841,9 @@ pub async fn email_mfa_disable( session: SessionInfo, context: ApiRequestContext, State(appstate): State, + username: Path, ) -> ApiResult { - let mut user = session.user; + let mut user = user_for_admin_or_self(&appstate.pool, &session, &username).await?; debug!("Disabling email MFA for user {}", user.username); user.disable_email_mfa(&appstate.pool).await?; user.verify_mfa_state(&appstate.pool).await?; diff --git a/crates/defguard_core/src/lib.rs b/crates/defguard_core/src/lib.rs index 0a4a66bbff..6c973c290b 100644 --- a/crates/defguard_core/src/lib.rs +++ b/crates/defguard_core/src/lib.rs @@ -242,14 +242,12 @@ pub fn build_webapp( .route("/auth/webauthn/start", post(webauthn_start)) .route("/auth/webauthn", post(webauthn_end)) .route("/auth/totp/init", post(totp_secret)) - .route("/auth/totp", post(totp_enable).delete(totp_disable)) + .route("/auth/totp", post(totp_enable)) .route("/auth/totp/verify", post(totp_code)) .route("/auth/email/init", post(email_mfa_init)) .route( "/auth/email", - get(request_email_mfa_code) - .post(email_mfa_enable) - .delete(email_mfa_disable), + get(request_email_mfa_code).post(email_mfa_enable), ) .route("/auth/email/verify", post(email_mfa_code)) .route("/auth/recovery", post(recovery_code)) @@ -267,6 +265,9 @@ pub fn build_webapp( .route("/user/change_password", put(change_self_password)) .route("/user/{username}/password", put(change_password)) .route("/user/{username}/reset_password", post(reset_password)) + // disable mfa + .route("/user/{username}/email", delete(email_mfa_disable)) + .route("/user/{username}/totp", delete(totp_disable)) // auth keys .route( "/user/{username}/auth_key", diff --git a/web/src/pages/user-profile/UserProfilePage/tabs/ProfileDetailsTab/components/ProfileAuthCard/ProfileAuthCard.tsx b/web/src/pages/user-profile/UserProfilePage/tabs/ProfileDetailsTab/components/ProfileAuthCard/ProfileAuthCard.tsx index 368db73d42..36c514baf2 100644 --- a/web/src/pages/user-profile/UserProfilePage/tabs/ProfileDetailsTab/components/ProfileAuthCard/ProfileAuthCard.tsx +++ b/web/src/pages/user-profile/UserProfilePage/tabs/ProfileDetailsTab/components/ProfileAuthCard/ProfileAuthCard.tsx @@ -78,12 +78,12 @@ export const ProfileAuthCard = () => { }); const { mutate: mutateDisableEmailMfa } = useMutation({ - mutationFn: api.auth.mfa.email.disable, + mutationFn: api.user.mfa.email.disable, meta: invalidateAfterMfaChange, }); const { mutate: mutateDisableTotp } = useMutation({ - mutationFn: api.auth.mfa.totp.disable, + mutationFn: api.user.mfa.totp.disable, meta: invalidateAfterMfaChange, }); @@ -99,7 +99,6 @@ export const ProfileAuthCard = () => { }, meta: invalidateAfterMfaChange, }); - const emailMenuItems = useMemo(() => { const items: MenuItemProps[] = []; if (!user.email_mfa_enabled) { @@ -121,7 +120,7 @@ export const ProfileAuthCard = () => { items.push({ text: m.controls_disable(), icon: 'minus-circle', - onClick: () => mutateDisableEmailMfa(), + onClick: () => mutateDisableEmailMfa(user.username), }); } const res: MenuItemsGroup = { @@ -133,6 +132,7 @@ export const ProfileAuthCard = () => { mutateDisableEmailMfa, mutateSetDefaultMfa, user.mfa_method, + user.username, ]); const mfaMenuItems = useMemo(() => { @@ -227,16 +227,20 @@ export const ProfileAuthCard = () => { items.push({ icon: 'minus-circle', text: m.controls_disable(), - onClick: () => { - mutateDisableTotp(); - }, + onClick: () => mutateDisableTotp(user.username), }); } return { items, }; - }, [mutateDisableTotp, user.totp_enabled, mutateSetDefaultMfa, user.mfa_method]); + }, [ + mutateDisableTotp, + user.totp_enabled, + mutateSetDefaultMfa, + user.mfa_method, + user.username, + ]); return ( diff --git a/web/src/shared/api/api.ts b/web/src/shared/api/api.ts index fba2900e18..84a5ca8620 100644 --- a/web/src/shared/api/api.ts +++ b/web/src/shared/api/api.ts @@ -202,6 +202,14 @@ const api = { }); }, deleteUser: (username: string) => client.delete(`/user/${username}`), + mfa: { + totp: { + disable: (username: string) => client.delete(`/user/${username}/totp`), + }, + email: { + disable: (username: string) => client.delete(`/user/${username}/email`), + }, + }, }, webhook: { addWebhook: (data: AddWebhookRequest) => client.post('/webhook', data), @@ -232,7 +240,6 @@ const api = { client.post('/auth/totp/verify', { code, }), - disable: () => client.delete('/auth/totp'), }, email: { init: () => client.post('/auth/email/init'), @@ -240,7 +247,6 @@ const api = { client.post('/auth/email', { code, }), - disable: () => client.delete('/auth/email'), resend: () => client.get('/auth/email'), verify: (code: string) => client.post('/auth/email/verify', { code }),