Files
AetherForge/server/web/src/components/SessionGate.tsx
drjones f9e26bb1a6 Fix bugs found in full security and stability audit.
Harden artifact paths and fusion uploads, repair pool reconnect and login ID tracking, fix agent/fusion/frontend regressions, and refresh PROBLEMS.md with the full findings list.
2026-05-29 09:57:22 -07:00

82 lines
2.5 KiB
TypeScript

import { useEffect, useState, type ReactNode } from 'react';
import { getStoredAuth, setStoredAuth } from '../api/auth';
export default function SessionGate({ children }: { children: ReactNode }) {
const [ready, setReady] = useState(false);
const [authed, setAuthed] = useState(!!getStoredAuth());
const [user, setUser] = useState('drjones');
const [pass, setPass] = useState('');
const [err, setErr] = useState('');
useEffect(() => {
const token = getStoredAuth();
if (!token) {
setAuthed(false);
setReady(true);
return;
}
fetch('/api/v1/config', { headers: { Authorization: `Basic ${token}` } })
.then((r) => {
setAuthed(r.ok);
setReady(true);
})
.catch(() => {
setAuthed(false);
setReady(true);
});
}, []);
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
setErr('');
const token = btoa(`${user}:${pass}`);
try {
const res = await fetch('/api/v1/config', { headers: { Authorization: `Basic ${token}` } });
if (!res.ok) {
setErr('Login failed — check username and password.');
return;
}
setStoredAuth(user, pass);
setAuthed(true);
} catch {
setErr('Cannot reach server — check that miner-server is running.');
}
};
if (!ready) {
return (
<div className="session-gate">
<p className="font-tech">Starting AetherForge</p>
</div>
);
}
if (!authed) {
return (
<div className="session-gate">
<form className="session-gate-card card" onSubmit={handleLogin}>
<h1 className="font-display">AetherForge</h1>
<p className="form-hint">Sign in to open the command deck.</p>
<label className="label">Username</label>
<input className="input" value={user} onChange={(e) => setUser(e.target.value)} autoComplete="username" />
<label className="label">Password</label>
<input
className="input"
type="password"
value={pass}
onChange={(e) => setPass(e.target.value)}
autoComplete="current-password"
/>
{err && <p className="form-hint" style={{ color: 'var(--accent-red)' }}>{err}</p>}
<button type="submit" className="btn btn-primary btn-lg">
Enter Command Deck
</button>
<p className="form-hint">Default: drjones / czapiewski (change under Calibrate Users)</p>
</form>
</div>
);
}
return <>{children}</>;
}