fix(web): simplify first-time token sign-in

This commit is contained in:
2026-10-14 18:43:06 -07:00
parent 844f48e9e0
commit 2e62bfa736
5 changed files with 71 additions and 18 deletions
+7 -8
View File
@@ -26,7 +26,7 @@ export function AuthScreen({ authTokenInput, setAuthTokenInput, isSigningIn, aut
</div>
<div>
<h1 className="text-lg font-semibold text-violet-50">Sign in to Sybil</h1>
<p className="mt-1 text-sm text-muted-foreground">Use your backend admin token.</p>
<p className="mt-1 text-sm text-muted-foreground">Enter your admin token.</p>
</div>
</div>
@@ -34,28 +34,27 @@ export function AuthScreen({ authTokenInput, setAuthTokenInput, isSigningIn, aut
className="space-y-3"
onSubmit={(event) => {
event.preventDefault();
void onSignIn(authTokenInput.trim() || null);
const token = authTokenInput.trim();
if (token) void onSignIn(token);
}}
>
<Input
type="password"
autoComplete="off"
aria-label="Admin token"
placeholder="ADMIN_TOKEN"
required
value={authTokenInput}
onInput={(event) => setAuthTokenInput(event.currentTarget.value)}
disabled={isSigningIn}
className="bg-[hsl(235_48%_6%_/_0.84)] text-violet-50"
/>
<Button className="w-full" type="submit" disabled={isSigningIn}>
<Button className="w-full" type="submit" disabled={isSigningIn || !authTokenInput.trim()}>
{isSigningIn ? "Signing in..." : "Sign in"}
</Button>
<Button className="w-full" type="button" variant="secondary" disabled={isSigningIn} onClick={() => void onSignIn(null)}>
Continue without token
</Button>
</form>
{authError ? <p className="mt-3 text-sm text-red-600">{authError}</p> : null}
<p className="mt-3 text-xs text-muted-foreground">If `ADMIN_TOKEN` is set in `/server/.env`, token login is required.</p>
{authError ? <p role="alert" className="mt-3 text-sm text-red-600">{authError}</p> : null}
</div>
</div>
);
+9 -5
View File
@@ -18,8 +18,11 @@ function persistToken(token: string | null) {
}
function normalizeAuthError(message: string) {
if (message.includes("missing bearer token") || message.includes("invalid bearer token")) {
return "Authentication failed. Enter the ADMIN_TOKEN configured in server/.env.";
if (message.includes("invalid bearer token")) {
return "Incorrect token. Please try again.";
}
if (message.includes("missing bearer token")) {
return "Enter your admin token.";
}
return message;
}
@@ -43,10 +46,10 @@ export function useSessionAuth() {
persistToken(tokenCandidate);
};
const handleAuthFailure = (message: string) => {
const handleAuthFailure = (message: string | null) => {
setIsAuthenticated(false);
setAuthMode(null);
setAuthError(normalizeAuthError(message));
setAuthError(message ? normalizeAuthError(message) : null);
setAuthToken(null);
persistToken(null);
};
@@ -81,7 +84,8 @@ export function useSessionAuth() {
await completeSessionCheck(token);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
handleAuthFailure(message);
// A first visit without a token is an invitation to sign in, not a failed attempt.
handleAuthFailure(!token && message.includes("missing bearer token") ? null : message);
} finally {
setIsCheckingSession(false);
}