// POST /api/__site__/cache/purge: removes every Nitro route-cache entry // (pages, _payload.json and feeds), so an admin save shows on the next page // view. The backend calls it on loopback after the save commits, with // `Authorization: Bearer ` and the body // {"kind":"","slug":""}; the answer is {"purged":}. The kind // and slug only reach the log line. // // 404 without a token of at least 32 characters, and for any request that // came through a reverse proxy (X-Forwarded-For, X-Real-IP or Forwarded) // unless runtimeConfig.siteCache.allowProxied (NUXT_SITE_CACHE_ALLOW_PROXIED) // is true or "true": a backend that reaches the site through a TLS-terminating // proxy opts in, and the bearer token is then the only gate. 401 for a // missing or wrong bearer token. The '/api/__site__/**' route rule keeps this // route out of the route cache. // // Shared: several layers ship this file byte for byte, and Nitro keeps one // handler per route and method. import { authorizeSitePurge, parseSitePurgeEvent, purgeSiteRouteCache } from '../../../lib/siteCachePurge.ts' const PROXY_HEADERS = ['x-forwarded-for', 'x-real-ip', 'forwarded'] export default defineEventHandler(async (event) => { setResponseHeader(event, 'cache-control', 'no-store') const config = useRuntimeConfig(event) const siteCache = config.siteCache as { purgeToken?: unknown; allowProxied?: unknown } | undefined const verdict = authorizeSitePurge({ token: siteCache?.purgeToken, authorization: getRequestHeader(event, 'authorization'), proxied: PROXY_HEADERS.some((name) => getRequestHeader(event, name) !== undefined), allowProxied: siteCache?.allowProxied === true || siteCache?.allowProxied === 'true', }) if (verdict === 'disabled' || verdict === 'proxied') { throw createError({ statusCode: 404, statusMessage: 'Not Found' }) } if (verdict === 'unauthorized') { throw createError({ statusCode: 401, statusMessage: 'Unauthorized' }) } const { kind, slug } = parseSitePurgeEvent(await readBody(event).catch(() => null)) const purged = await purgeSiteRouteCache(useStorage('cache')) console.info(`[site-cache] purge: removed ${purged} route cache entries (${kind} ${slug})`) return { purged } })