feat(auth): add remembered local login to the frontend

This commit is contained in:
2026-08-17 04:52:39 +02:00
parent 8c67cb75dc
commit 202822f3ba
36 changed files with 2649 additions and 163 deletions
+9 -1
View File
@@ -1,9 +1,10 @@
import { useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { useSessionStore } from "../store/sessionStore";
import { resolve } from "../widgets";
import { postResponse } from "../api/sessions";
import type { UiResponse } from "../api/types";
import { ErrorBoundary } from "../components/ErrorBoundary";
import { captureAuthOperation, isAuthOperationCurrent } from "../auth/authOperation";
export function WidgetHost({ sessionId }: { sessionId: string | null }) {
const pending = useSessionStore((s) => s.pendingWidget);
@@ -12,17 +13,23 @@ export function WidgetHost({ sessionId }: { sessionId: string | null }) {
const setLastUserEntry = useSessionStore((s) => s.setLastUserEntry);
const [responding, setResponding] = useState(false);
const responseInFlight = useRef(false);
const operationEpochRef = useRef(0);
useEffect(() => () => { operationEpochRef.current += 1; }, []);
if (!pending) return null;
const Renderer = resolve(pending.widget);
const onRespond = async (r: UiResponse) => {
if (responseInFlight.current) return;
const operation = captureAuthOperation({ sessionId, disposalEpoch: operationEpochRef.current });
if (!operation) return;
responseInFlight.current = true;
setResponding(true);
if (sessionId) {
try {
await postResponse(sessionId, r);
if (!isAuthOperationCurrent(operation, { sessionId, disposalEpoch: operationEpochRef.current })) return;
} catch (err) {
if (!isAuthOperationCurrent(operation, { sessionId, disposalEpoch: operationEpochRef.current })) return;
// Surface feedback and keep the widget pending so the user can retry.
pushToast({
level: "error",
@@ -36,6 +43,7 @@ export function WidgetHost({ sessionId }: { sessionId: string | null }) {
return;
}
}
if (!isAuthOperationCurrent(operation, { sessionId, disposalEpoch: operationEpochRef.current })) return;
responseInFlight.current = false;
setResponding(false);
setLastUserEntry({