feat(auth): add TOTP 2FA setup and login verification
Some checks failed
CI / test (push) Failing after 21s
Some checks failed
CI / test (push) Failing after 21s
- add user twofa fields and migration - add 2FA setup/enable/disable endpoints - enforce OTP on login when 2FA enabled - add web login OTP field and settings UI
This commit is contained in:
@@ -12,6 +12,7 @@ export function AuthPanel() {
|
||||
const [name, setName] = useState("");
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [otpCode, setOtpCode] = useState("");
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [success, setSuccess] = useState<string | null>(null);
|
||||
|
||||
@@ -26,7 +27,7 @@ export function AuthPanel() {
|
||||
setMode("login");
|
||||
return;
|
||||
}
|
||||
await login(email, password);
|
||||
await login(email, password, otpCode.trim() || undefined);
|
||||
} catch {
|
||||
setError("Auth request failed.");
|
||||
}
|
||||
@@ -51,6 +52,14 @@ export function AuthPanel() {
|
||||
</>
|
||||
)}
|
||||
<input className="w-full rounded bg-slate-800 px-3 py-2" placeholder="Password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
|
||||
{mode === "login" ? (
|
||||
<input
|
||||
className="w-full rounded bg-slate-800 px-3 py-2"
|
||||
placeholder="2FA code (if enabled)"
|
||||
value={otpCode}
|
||||
onChange={(e) => setOtpCode(e.target.value.replace(/\D/g, "").slice(0, 8))}
|
||||
/>
|
||||
) : null}
|
||||
<button className="w-full rounded bg-accent px-3 py-2 font-semibold text-black disabled:opacity-50" disabled={loading} type="submit">
|
||||
{mode === "login" ? "Sign in" : "Create account"}
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user