feat: enforce bearer token auth on all /api/admin/* endpoints
All checks were successful
Release / Test backend (push) Successful in 1m1s
Release / Check ui (push) Successful in 2m12s
Release / Docker (push) Successful in 6m30s
Release / Gitea Release (push) Successful in 29s

Adds BACKEND_ADMIN_TOKEN env var (set in Doppler) as a required Bearer
token for every admin route. Also fixes PocketBase filter injection in
notification queries and wires BACKEND_ADMIN_TOKEN through docker-compose
to both backend and ui services. Includes CLAUDE.md for AI assistant guidance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Admin
2026-04-14 18:04:10 +05:00
parent 9f1c82fe05
commit 0f9977744a
7 changed files with 178 additions and 42 deletions

View File

@@ -15,18 +15,31 @@ import { env } from '$env/dynamic/private';
import * as cache from '$lib/server/cache';
export const BACKEND_URL = env.BACKEND_API_URL ?? 'http://localhost:8080';
const ADMIN_TOKEN = env.BACKEND_ADMIN_TOKEN ?? '';
/**
* Fetch a path on the backend, throwing a 502 on network failures.
*
* The `path` must start with `/` (e.g. `/api/voices`).
* Requests to `/api/admin/*` automatically include the Bearer token from
* the BACKEND_ADMIN_TOKEN environment variable.
*
* SvelteKit `error()` exceptions are always re-thrown so callers can
* short-circuit correctly inside their own catch blocks.
*/
export async function backendFetch(path: string, init?: RequestInit): Promise<Response> {
let finalInit = init;
if (ADMIN_TOKEN && path.startsWith('/api/admin')) {
finalInit = {
...init,
headers: {
Authorization: `Bearer ${ADMIN_TOKEN}`,
...((init?.headers ?? {}) as Record<string, string>)
}
};
}
try {
return await fetch(`${BACKEND_URL}${path}`, init);
return await fetch(`${BACKEND_URL}${path}`, finalInit);
} catch (e) {
// Re-throw SvelteKit HTTP errors so they propagate to the framework.
if (e instanceof Error && 'status' in e) throw e;