feat(cli): включение 2FA инстанс-админа командой totp-setup
2FA обязательна для инстанс-администраторов, но до её включения вход закрыт — получался замкнутый круг. Добавлены команды обслуживания: - `glchat totp-setup --email <admin>`: создаёт секрет, подтверждает его кодом, печатает секрет, otpauth-ссылку и 8 резервных кодов (каждый одноразовый); - `glchat totp-reset --email <admin>`: удаляет секрет при потере устройства; - код `auth.2fa_enrollment_required` с подсказкой, какую команду выполнить; - установщик: флаг `--admin-2fa` для автоматического включения (по умолчанию печатает подсказку, чтобы секреты не оседали в логах установки). Проверено сквозным прогоном локально: bootstrap → 403 на входе без 2FA → totp-setup → вход с TOTP-кодом → профиль, серверы, комнаты, роли, участники, аудит, создание сервера админом, 429 на шестой попытке входа, секретов в логах нет.
This commit is contained in:
@@ -2,6 +2,7 @@ import { Navigate, Outlet, useLocation } from 'react-router';
|
||||
|
||||
import { ErrorNotice, LoadingNotice } from '@/components/ui/ErrorNotice';
|
||||
import { useCurrentUser } from '@/lib/hooks';
|
||||
import { isUnauthorized } from '@/lib/http';
|
||||
|
||||
interface AuthGuardProps {
|
||||
/**
|
||||
@@ -45,18 +46,3 @@ export function AuthGuard({ allowIncompleteOnboarding = false }: AuthGuardProps)
|
||||
|
||||
return <Outlet context={{ user }} />;
|
||||
}
|
||||
|
||||
/** Коды, которые означают именно отсутствие сессии. */
|
||||
const unauthorizedCodes = new Set(['auth.unauthorized', 'auth.session_invalid', 'auth.required']);
|
||||
|
||||
/** 401/403 или один из «сессионных» кодов; остальное — сеть или ошибка сервера. */
|
||||
export function isUnauthorized(error: unknown): boolean {
|
||||
if (typeof error !== 'object' || error === null) {
|
||||
return false;
|
||||
}
|
||||
const candidate = error as { status?: unknown; code?: unknown };
|
||||
if (candidate.status === 401) {
|
||||
return true;
|
||||
}
|
||||
return typeof candidate.code === 'string' && unauthorizedCodes.has(candidate.code);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user