import type { Metadata } from "next"; import { headers } from "next/headers"; import { notFound } from "next/navigation"; /* The operations console lives under /ops and is served only on ops.threadcount.tech. * * proxy.ts already refuses /ops on every other hostname, but the proxy is not the only guard: a * matcher change can silently remove its coverage, so the host is checked here again, from the * request headers, before anything under this layout renders. Same comparison as the proxy — * exact, lower-cased, port-stripped, never `includes`. * * Every page under here is dynamic. ISR is not keyed by host, so a cached ops page could be * served on threadcount.tech; `force-dynamic` on the layout keeps the whole subtree out of the * prerender cache. */ export const dynamic = "force-dynamic"; export const metadata: Metadata = { title: { default: "ThreadCount ops", template: "%s — ThreadCount ops" }, robots: { index: false, follow: false }, }; const OPS_HOST = "ops.threadcount.tech"; export default async function OpsLayout({ children }: { children: React.ReactNode }) { const h = await headers(); const host = (h.get("x-forwarded-host") ?? h.get("host") ?? "").split(":")[0].toLowerCase(); if (host !== OPS_HOST) notFound(); return