Move the softAuth middleware from devices.js into a new shared lib/api/soft_auth.js module. Apply router.use(softAuth) and router.use(errorMiddleware) to icon_sets.js so that POST/DELETE owner-only routes return 401 (not 500) when no auth is present. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
26 lines
1.1 KiB
JavaScript
26 lines
1.1 KiB
JavaScript
// lib/api/soft_auth.js — shared middleware
|
|
// Soft auth: identifies the actor if auth is present but never blocks the request.
|
|
// Owner-only sub-routes enforce 401/403 via requireOwner.
|
|
import * as agents from '../db/repos/agents.js';
|
|
import { timingSafeStrEqual } from '../auth/safe_compare.js';
|
|
import { accessOwnerEmail } from '../auth/cf_access.js';
|
|
|
|
export async function softAuth(req, _res, next) {
|
|
try {
|
|
const cfEmail = await accessOwnerEmail(req);
|
|
if (cfEmail) { req.actor = { kind: 'user', id: null }; return next(); }
|
|
const auth = req.headers.authorization || '';
|
|
const [scheme, token] = auth.split(' ');
|
|
if (scheme === 'Bearer' && token) {
|
|
if (process.env.OWNER_TOKEN && timingSafeStrEqual(token, process.env.OWNER_TOKEN)) {
|
|
req.actor = { kind: 'user', id: null }; return next();
|
|
}
|
|
try {
|
|
const agent = await agents.verifyToken(token);
|
|
if (agent) req.actor = { kind: 'agent', id: agent.id, capabilities: agent.capabilities || {}, scopes: agent.scopes || {} };
|
|
} catch { /* ignore */ }
|
|
}
|
|
} catch { /* ignore */ }
|
|
next();
|
|
}
|