feat: enforce bearer token auth on all /api/admin/* endpoints
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user