/** * GET /_emdash/api/settings/frontend-token — the frontend service * account's API token + backend URL, for building or developing the * frontend anywhere (container builds, previews, a laptop). * POST /_emdash/api/settings/frontend-token/rotate — replace it. * * Admins only: the token reads unpublished content. */ import type { APIRoute } from "astro"; import { requirePerm } from "#api/authorize.js"; import { apiError, apiSuccess, handleError } from "#api/error.js"; import { ensureFrontendServiceAccount, FRONTEND_USER_EMAIL } from "../../../../auth/frontend-account.js"; import { OptionsRepository } from "../../../../database/repositories/options.js"; export const prerender = false; export const GET: APIRoute = async ({ locals, url }) => { const { emdash, user } = locals; const denied = requirePerm(user, "settings:manage"); if (denied) return denied; if (!emdash?.db) return apiError("NOT_AVAILABLE", "Database not available", 503); try { const account = await ensureFrontendServiceAccount(emdash.db); const siteUrl = await new OptionsRepository(emdash.db).get("emdash:site_url"); const backendUrl = (typeof siteUrl === "string" && siteUrl ? siteUrl : url.origin).replace(/\/+$/, ""); return apiSuccess({ backendUrl, token: account.token, user: FRONTEND_USER_EMAIL, env: [`BACKEND_URL=${backendUrl}`, `SITE_URL=${backendUrl}`, `EMDASH_API_TOKEN=${account.token}`].join("\n"), usage: "EMDASH_API_TOKEN=… node bin/snapshot-to-sqlite.mjs snapshot.db, then astro dev / astro build", }); } catch (error) { return handleError(error); } };