feat(2FA): add 2FA settings for teams

This commit is contained in:
Rudy B. committed 2026-04-25 01:40:06 +02:00
1 parent 2359dbad64
commit 817dffff4d
2 files changed
+56

No files matched your search

@@ -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 }) {
</Row>
<TeamMembersDataTable teamId={teamId} allowEdit={canEdit} />
</Panel>
{isAdmin && (
<Panel>
<TeamTwoFactorSettings teamId={teamId} />
</Panel>
)}
{isTeamOwner && (
<Panel>
<TeamManage teamId={teamId} />
@@ -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 (
<Column gap="4">
<Text weight="bold">{t(labels.twoFactorAuth)}</Text>
<TooltipTrigger isDisabled={!isGlobalRequired}>
<Row alignItems="center" gap="3">
<Switch
isSelected={isGlobalRequired || twoFactorRequired}
isDisabled={isGlobalRequired}
onChange={handleToggle}
/>
<Text>{t(labels.twoFactorRequireTeam)}</Text>
</Row>
<Tooltip>{t(labels.twoFactorGlobalActiveTooltip)}</Tooltip>
</TooltipTrigger>
<Text size="sm" color="muted">
{t(messages.twoFactorRequireTeamDescription)}
</Text>
</Column>
);
}