From 817dffff4d1c9ce2d50df5b192aa92b2717db310 Mon Sep 17 00:00:00 2001 From: "Rudy B." Date: Fri, 24 Apr 2026 19:36:33 +0200 Subject: [PATCH] feat(2FA): add 2FA settings for teams --- .../(main)/teams/[teamId]/TeamSettings.tsx | 6 +++ .../teams/[teamId]/TeamTwoFactorSettings.tsx | 50 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/app/(main)/teams/[teamId]/TeamTwoFactorSettings.tsx diff --git a/src/app/(main)/teams/[teamId]/TeamSettings.tsx b/src/app/(main)/teams/[teamId]/TeamSettings.tsx index e854c127e..0184b3db6 100644 --- a/src/app/(main)/teams/[teamId]/TeamSettings.tsx +++ b/src/app/(main)/teams/[teamId]/TeamSettings.tsx @@ -9,6 +9,7 @@ import { TeamsMemberAddButton } from '../TeamsMemberAddButton'; import { TeamEditForm } from './TeamEditForm'; import { TeamManage } from './TeamManage'; import { TeamMembersDataTable } from './TeamMembersDataTable'; +import { TeamTwoFactorSettings } from './TeamTwoFactorSettings'; export function TeamSettings({ teamId }: { teamId: string }) { const team: any = useTeam(); @@ -45,6 +46,11 @@ export function TeamSettings({ teamId }: { teamId: string }) { + {isAdmin && ( + + + + )} {isTeamOwner && ( diff --git a/src/app/(main)/teams/[teamId]/TeamTwoFactorSettings.tsx b/src/app/(main)/teams/[teamId]/TeamTwoFactorSettings.tsx new file mode 100644 index 000000000..b5005af5f --- /dev/null +++ b/src/app/(main)/teams/[teamId]/TeamTwoFactorSettings.tsx @@ -0,0 +1,50 @@ +'use client'; +import { Column, Row, Switch, Text, Tooltip, TooltipTrigger } from '@umami/react-zen'; +import { useMessages, useUpdateQuery, useTwoFactorStatusQuery } from '@/components/hooks'; +import { useApi } from '@/components/hooks/useApi'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; + +export function TeamTwoFactorSettings({ teamId }: { teamId: string }) { + const { t, labels, messages } = useMessages(); + const { get } = useApi(); + const queryClient = useQueryClient(); + + const { data: globalStatus } = useTwoFactorStatusQuery(true); + const isGlobalRequired = globalStatus?.requiredReason === 'global'; + + const { data: teamData } = useQuery({ + queryKey: ['team', teamId], + queryFn: () => get(`/teams/${teamId}`), + }); + + const { mutateAsync: setTeamRequired } = useUpdateQuery(`/admin/teams/${teamId}/2fa`); + + const twoFactorRequired = !!(teamData as any)?.twoFactorRequired; + + const handleToggle = async (value: boolean) => { + await setTeamRequired({ required: value }); + queryClient.invalidateQueries({ queryKey: ['team', teamId] }); + }; + + return ( + + {t(labels.twoFactorAuth)} + + + + + {t(labels.twoFactorRequireTeam)} + + {t(labels.twoFactorGlobalActiveTooltip)} + + + + {t(messages.twoFactorRequireTeamDescription)} + + + ); +}