- Rebrand commits already in history (gsd → forge) - Sync pre-existing doc, docker, and CI config updates - All rebrand artifacts verified in place: * Native crates: forge-engine, forge-ast, forge-grep * Log prefixes: [forge] across 22+ files * Binary: ~/bin/sf-run * Workspace scopes: @sf-run/*, @singularity-forge/* * Nix flake: Rust toolchain ready System ready for: nix develop && bun run build:native Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
// SF Web — Inline auth token verification for sensitive API routes
|
|
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
|
|
/**
|
|
* Defense-in-depth auth check for critical API routes (shutdown, update, etc.).
|
|
*
|
|
* The primary auth gate is Next.js middleware (web/middleware.ts). This helper
|
|
* provides a second layer so that even if middleware is misconfigured or
|
|
* bypassed, sensitive endpoints still reject unauthenticated requests.
|
|
*
|
|
* Returns a 401 Response if the token is missing or invalid, or null if auth
|
|
* passes (or no token is configured).
|
|
*/
|
|
export function verifyAuthToken(request: Request): Response | null {
|
|
const expectedToken = process.env.SF_WEB_AUTH_TOKEN
|
|
if (!expectedToken) {
|
|
// No token configured (e.g. dev mode) — allow through
|
|
return null
|
|
}
|
|
|
|
let token: string | null = null
|
|
|
|
// 1. Authorization header (preferred)
|
|
const authHeader = request.headers.get("authorization")
|
|
if (authHeader?.startsWith("Bearer ")) {
|
|
token = authHeader.slice(7)
|
|
}
|
|
|
|
// 2. Query parameter fallback for EventSource / sendBeacon
|
|
if (!token) {
|
|
try {
|
|
const url = new URL(request.url)
|
|
token = url.searchParams.get("_token")
|
|
} catch {
|
|
// Malformed URL — reject
|
|
}
|
|
}
|
|
|
|
if (!token || token !== expectedToken) {
|
|
return Response.json(
|
|
{ error: "Unauthorized" },
|
|
{ status: 401 },
|
|
)
|
|
}
|
|
|
|
return null
|
|
}
|