mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-19 05:56:39 +07:00
feat: branded login screen in front of Basic Auth
The browser's native Basic Auth prompt can't be restyled — it's chrome UI, not part of the page. Replace it with Aurum's own login screen: nginx keeps auth_basic on /api/* (the actual protection, unchanged), but drops it from the SPA shell (just HTML/JS/CSS, no data) so the app can render its own branded form instead. On submit the app validates the credentials against a real protected endpoint, then attaches the resulting Authorization header to every request itself — sessionStorage-backed, so closing the tab signs out. Instances with Basic Auth left off (the default) never see this screen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01855PiW5Wd8n4aRW4n9kByY
This commit is contained in:
@@ -1,8 +1,15 @@
|
||||
import { api } from "@/api/client";
|
||||
import { getAuthHeader } from "@/lib/auth";
|
||||
import { t } from "@/lib/i18n";
|
||||
|
||||
export async function exportBackup(): Promise<void> {
|
||||
const response = await fetch("/api/backup/export");
|
||||
// Raw fetch (not api/client.ts's request()) — the response is a file
|
||||
// download, not JSON — so the Authorization header has to be attached
|
||||
// here by hand too, same as every other request.
|
||||
const authHeader = getAuthHeader();
|
||||
const response = await fetch("/api/backup/export", {
|
||||
headers: authHeader ? { Authorization: authHeader } : {},
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(await response.text());
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { clearCredentials, getAuthHeader } from "@/lib/auth";
|
||||
|
||||
const API_BASE = "/api";
|
||||
|
||||
export class ApiError extends Error {
|
||||
@@ -9,11 +11,22 @@ export class ApiError extends Error {
|
||||
}
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const authHeader = getAuthHeader();
|
||||
const response = await fetch(`${API_BASE}${path}`, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...(authHeader ? { Authorization: authHeader } : {}),
|
||||
},
|
||||
...init,
|
||||
});
|
||||
|
||||
if (response.status === 401) {
|
||||
// Stored credentials are missing/stale (password changed, or Basic Auth
|
||||
// was just turned on) — drop them so LoginGate falls back to the login
|
||||
// screen instead of every request failing silently forever.
|
||||
clearCredentials();
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
const body = await response.text();
|
||||
let message = body || response.statusText;
|
||||
|
||||
Reference in New Issue
Block a user