import { useState } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { api, ApiError } from '../lib/api'; import { notifyAuthChange, setSession } from '../lib/auth'; import { BrandMark } from '../components/BrandMark'; interface LoginResponse { access_token: string; refresh_token: string; account_id: number; username: string; display_name: string; } export function Login() { const navigate = useNavigate(); const location = useLocation(); const from = (location.state as { from?: { pathname: string } } | null)?.from?.pathname ?? '/'; const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [err, setErr] = useState(null); const [loading, setLoading] = useState(false); const onSubmit = async (e: React.FormEvent) => { e.preventDefault(); setErr(null); setLoading(true); try { const res = await api('/login', { method: 'POST', body: { username, password }, }); setSession(res.access_token, { id: res.account_id, username: res.username, displayName: res.display_name, }); notifyAuthChange(); navigate(from, { replace: true }); } catch (e) { if (e instanceof ApiError) { if (e.body && typeof e.body === 'object' && 'error' in e.body) { const code = (e.body as { error: string }).error; if (code === 'not_admin') setErr('That account is not an admin.'); else if (code === 'invalid_credentials') setErr('Invalid username or password.'); else setErr(e.message); } else setErr(e.message); } else setErr(String(e)); } finally { setLoading(false); } }; return (

DorkNet Admin

Sign in with an admin account.

setUsername(e.target.value)} />
setPassword(e.target.value)} />
{err && (
{err}
)}

DorkNet private server · admin console

); }