Skip to the content

Capsid menu

app/lib/smoke.server.ts

60 lines and 1 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.

Functions

The functions of smoke.server.ts
FunctionLinesComplexityCoveredCRAPMutation
authenticateSmoke30 to 749No data: no coverage report in this mapNo data: no coverage report in this mapNo data: no mutants in this code

Imports

It imports app/lib/bearer.server.ts, app/lib/rate-limit.mjs. Imported by app/routes/admin.tsx.

Source

/**
 * Read-only machine principal for the admin plane: `decide()` refuses it writes and the `/admin`
 * middleware refuses non-GET methods. Handle it like the operator token: never in a log or error body.
 */

import { safeEqual } from "@dustinedwards/site-runtime/compare";

import { tokenLabel } from "~/lib/bearer.server";
import { limitHit } from "~/lib/rate-limit.mjs";

/**
 * Own `smoke:` key prefix so a CI sweep and the publish path cannot exhaust each other. High because
 * nothing behind it costs money and a legitimate sweep bursts tens of loads in seconds.
 */
const SMOKE_RATE_LIMIT = 240;
const SMOKE_RATE_PERIOD_SECONDS = 60;

const MIN_TOKEN_LENGTH = 32;

/** A realistic length, because the topbar's width is what the smoke render measures. Not a real mailbox. */
const SMOKE_ACTOR_EMAIL = "smoke-reader@dustinedwards.info";

// `absent` is not a failure: most `/admin` requests are a browser and must fall through to the session gate.
type SmokeResult =
  | { kind: "ok"; id: string; email: string }
  | { kind: "absent" }
  | { kind: "refused"; status: number; error: string; retryAfter?: number };

// Authenticate before rate limiting, so an unauthenticated flood cannot drain the real budget.
export async function authenticateSmoke(env: Env, request: Request): Promise<SmokeResult> {
  const header = request.headers.get("authorization") ?? "";
  const presented = /^Bearer\s+(.+)$/i.exec(header.trim())?.[1] ?? "";

  if (!presented) return { kind: "absent" };

  const configured = env.SMOKE_TOKEN;

  // Refused, not fallen through: a token was presented, and a login redirect would mislead CI.
  if (!configured || configured.length < MIN_TOKEN_LENGTH) {
    return {
      kind: "refused",
      status: 503,
      error:
        "The smoke credential is not configured on this deployment. " +
        "Set the SMOKE_TOKEN wrangler secret to enable it.",
    };
  }

  if (!(await safeEqual(presented, configured))) {
    return { kind: "refused", status: 401, error: "Invalid smoke bearer token." };
  }

  const id = tokenLabel(presented);

  const verdict = await limitHit(env, `smoke:${id}`, SMOKE_RATE_LIMIT, SMOKE_RATE_PERIOD_SECONDS);
  if (verdict.status === "unavailable") {
    return {
      kind: "refused",
      status: 503,
      error: "Rate limiting is unavailable, so the smoke credential is disabled.",
    };
  }
  if (verdict.status === "limited") {
    return {
      kind: "refused",
      status: 429,
      error: `Rate limit: ${SMOKE_RATE_LIMIT} requests per ${SMOKE_RATE_PERIOD_SECONDS} seconds.`,
      retryAfter: verdict.retryAfterSeconds,
    };
  }

  // Resolved here, not in `admin.tsx`: the secrets boundary is a path rule and routes may not read secrets.
  return { kind: "ok", id, email: SMOKE_ACTOR_EMAIL };
}