Replace basic auth with session login

This commit is contained in:
2026-08-03 00:25:18 +03:30
parent f5f54bac66
commit 81d816ae54
10 changed files with 501 additions and 69 deletions
@@ -302,6 +302,7 @@ onMounted(async () => {
hasBackup.value = Boolean(localStorage.getItem(backupKey.value));
try {
const response = await fetch(`${apiBase.value}/api/settings`);
redirectToLoginIfExpired(response);
if (!response.ok) return;
const settings = (await response.json()) as { evidence_guard: boolean };
globalEvidenceGuard.value = settings.evidence_guard;
@@ -324,6 +325,7 @@ const toggleGlobalEvidenceGuard = async () => {
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ evidence_guard: next })
});
redirectToLoginIfExpired(response);
const settings = (await response.json()) as {
evidence_guard?: boolean;
detail?: string;
@@ -348,6 +350,7 @@ async function post<T>(path: string, payload: Record<string, unknown>): Promise<
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
redirectToLoginIfExpired(response);
const body = (await response.json()) as T & { detail?: string };
if (!response.ok) throw new Error(body.detail || "The Signal API returned an error.");
@@ -362,6 +365,7 @@ async function postTask<T>(path: string, payload: Record<string, unknown>): Prom
await new Promise((resolve) => window.setTimeout(resolve, 1200));
try {
const response = await fetch(`${apiBase.value}/api/tasks/${started.task_id}`);
redirectToLoginIfExpired(response);
if (!response.ok) {
const body = (await response.json()) as { detail?: string };
throw new Error(body.detail || "Could not read the model task status.");
@@ -392,6 +396,13 @@ async function postTask<T>(path: string, payload: Record<string, unknown>): Prom
}
}
function redirectToLoginIfExpired(response: Response): void {
if (response.status !== 401) return;
const next = `${window.location.pathname}${window.location.search}${window.location.hash}`;
window.location.assign(`/login?next=${encodeURIComponent(next)}`);
throw new Error("Your session expired. Redirecting to sign in…");
}
const jobPayload = () => ({
job_url: mode.value === "url" ? jobURL.value.trim() : null,
job_text: mode.value === "text" ? jobText.value.trim() : null
+13
View File
@@ -63,6 +63,19 @@
<SharedToggleDark />
<form action="/logout" method="post">
<UiButton
type="submit"
variant="ghost-secondary"
size="xs"
class="h-8 gap-x-1"
aria-label="Sign out of Signal"
>
<span class="i-material-symbols:logout text-lg" />
<span class="hide-on-mobile text-base">Sign out</span>
</UiButton>
</form>
<UiButton
as="a"
variant="ghost-secondary"