Harden auth and improve user management

This commit is contained in:
2026-03-12 20:28:06 +01:00
parent 1a8e37bd36
commit eb699666d9
26 changed files with 1105 additions and 283 deletions

View File

@@ -1,4 +1,4 @@
import { USER_STORAGE_KEY } from "./storage";
import { AUTH_TOKEN_STORAGE_KEY } from "./storage";
const API_ROOT = import.meta.env.VITE_API_URL ?? (import.meta.env.DEV ? "http://localhost:8090/api" : "/api");
@@ -30,22 +30,16 @@ async function readErrorMessage(response: Response): Promise<string> {
return `Anfrage fehlgeschlagen (${response.status})`;
}
function actorHeaders(): Record<string, string> {
function authHeaders(): Record<string, string> {
if (typeof window === "undefined") {
return {};
}
const rawUser = window.localStorage.getItem(USER_STORAGE_KEY);
if (!rawUser) {
return {};
}
try {
const user = JSON.parse(rawUser) as { id?: string | null };
return user.id ? { "X-MUH-Actor-Id": user.id } : {};
} catch {
const token = window.localStorage.getItem(AUTH_TOKEN_STORAGE_KEY);
if (!token) {
return {};
}
return { Authorization: `Bearer ${token}` };
}
async function handleResponse<T>(response: Response): Promise<T> {
@@ -55,13 +49,17 @@ async function handleResponse<T>(response: Response): Promise<T> {
if (response.status === 204) {
return undefined as T;
}
return (await response.json()) as T;
const text = await response.text();
if (!text.trim()) {
return undefined as T;
}
return JSON.parse(text) as T;
}
export async function apiGet<T>(path: string): Promise<T> {
return handleResponse<T>(
await fetch(`${API_ROOT}${path}`, {
headers: actorHeaders(),
headers: authHeaders(),
}),
);
}
@@ -72,7 +70,7 @@ export async function apiPost<T>(path: string, body: unknown): Promise<T> {
method: "POST",
headers: {
"Content-Type": "application/json",
...actorHeaders(),
...authHeaders(),
},
body: JSON.stringify(body),
}),
@@ -85,7 +83,7 @@ export async function apiPut<T>(path: string, body: unknown): Promise<T> {
method: "PUT",
headers: {
"Content-Type": "application/json",
...actorHeaders(),
...authHeaders(),
},
body: JSON.stringify(body),
}),
@@ -98,7 +96,7 @@ export async function apiPatch<T>(path: string, body: unknown): Promise<T> {
method: "PATCH",
headers: {
"Content-Type": "application/json",
...actorHeaders(),
...authHeaders(),
},
body: JSON.stringify(body),
}),
@@ -109,7 +107,7 @@ export async function apiDelete(path: string): Promise<void> {
await handleResponse<void>(
await fetch(`${API_ROOT}${path}`, {
method: "DELETE",
headers: actorHeaders(),
headers: authHeaders(),
}),
);
}