- checkAuth() reads the expected token from a TOKEN_KINDS table (read -> HEALTH_TOKEN, ingest -> HOSTS_INGEST_TOKEN, claude-ingest -> CLAUDE_USAGE_INGEST_TOKEN); each ingestion token fails closed to a 503 naming its own variable. Still one gate, one tokenMatches() call. A route naming an unknown kind fails module load. - readBody() takes its ceiling per route: 4 KiB for /hosts/<id>, 64 KiB for /claude-usage. - claude-usage.js: pure, exported sanitizeClaudeUsage() for contract schemaVersion 1 (whitelist rebuild, invalid values dropped, list bounds). - POST /claude-usage: 400 on invalid JSON or schemaVersion, server-stamped receivedAt, atomic write (pid-suffixed temp, mode 600, rename), 204. - GET /claude-usage: re-sanitized snapshot with ageSeconds, stale and staleAfterSeconds (CLAUDE_USAGE_STALE_SECONDS, default 2700), or no_data. - Dockerfile COPY ships claude-usage.js. - auth.test.js: the checkAuth() equality allowlist loses the former `route.tokenKind === "ingest"` entry, which the table removes. The pin only got stricter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 lines
137 B
Docker
6 lines
137 B
Docker
FROM node:22-alpine
|
|
WORKDIR /app
|
|
COPY package.json index.js metrics.js claude-usage.js ./
|
|
EXPOSE 3001
|
|
USER node
|
|
CMD ["node", "index.js"]
|