globalThis.process ??= {};
globalThis.process.env ??= {};
import { r as __exportAll } from "./rolldown-runtime_-UtK6b3T.mjs";
import { E as eq, t as createD1Client } from "./d1_DTqC4o_t.mjs";
import { U as ContentAuthzError, W as ContentValidationError, d as mapContentError, f as parseIdBody, i as createNeonHttpClient, u as jsonOk } from "./crypto_CY2zBtG3.mjs";
import { a as issueServiceToken, c as revokeServiceToken, o as listServiceTokensForUser, r as customAuthSchema } from "./engine-custom_BJVTPCgT.mjs";
import { c as assertCsrf, i as requireAdmin } from "./auth_B0DWM0G6.mjs";
import { env } from "cloudflare:workers";
//#region src/pages/api/admin/service-tokens.ts
var service_tokens_exports = /* @__PURE__ */ __exportAll({
	DELETE: () => DELETE,
	GET: () => GET,
	POST: () => POST,
	prerender: () => false
});
var DEFAULT_SERVICE_TOKEN_TTL_MS = 7776e6;
var SERVICE_TOKEN_TABLES = {
	authUsers: customAuthSchema.authUsers,
	serviceTokens: customAuthSchema.serviceTokens
};
function getAuthDb(currentEnv) {
	if (currentEnv.DB) return createD1Client(currentEnv.DB, { schema: customAuthSchema });
	if (currentEnv.DATABASE_URL) return createNeonHttpClient({
		connectionString: currentEnv.DATABASE_URL,
		schema: customAuthSchema
	});
	throw new Error("No database configured: set DB binding (D1) or DATABASE_URL secret (Neon)");
}
function parseLabelBody(data) {
	if (typeof data !== "object" || data === null) throw new ContentValidationError("input", "must be an object");
	const label = data.label;
	if (typeof label !== "string") throw new ContentValidationError("label", "required string");
	const trimmed = label.trim();
	if (!trimmed) throw new ContentValidationError("label", "must not be empty");
	if (trimmed.length > 200) throw new ContentValidationError("label", "must be at most 200 characters");
	return trimmed;
}
async function loadServiceTokenOwner(db, id) {
	const [row] = await db.select({ userId: customAuthSchema.serviceTokens.userId }).from(customAuthSchema.serviceTokens).where(eq(customAuthSchema.serviceTokens.id, id)).limit(1);
	return row?.userId ?? null;
}
var GET = async ({ request, cookies }) => {
	try {
		const { actor } = await requireAdmin(request, env, cookies);
		const db = getAuthDb(env);
		const tokens = await listServiceTokensForUser(db, SERVICE_TOKEN_TABLES, actor.id);
		return jsonOk({ tokens });
	} catch (error) {
		return mapContentError(error);
	}
};
var POST = async ({ request, cookies }) => {
	try {
		const { actor, authMode } = await requireAdmin(request, env, cookies);
		if (authMode !== "session") throw new ContentAuthzError("create", actor.id, "service tokens may only be issued from an interactive session", "service-token");
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		const label = parseLabelBody(await request.json());
		const db = getAuthDb(env);
		const { id, token } = await issueServiceToken(db, SERVICE_TOKEN_TABLES, {
			userId: actor.id,
			label,
			ttlMs: DEFAULT_SERVICE_TOKEN_TTL_MS
		});
		return jsonOk({
			id,
			token
		});
	} catch (error) {
		return mapContentError(error);
	}
};
var DELETE = async ({ request, cookies }) => {
	try {
		const { actor, authMode } = await requireAdmin(request, env, cookies);
		assertCsrf(request, {
			authMode,
			siteOrigin: env.SITE_ORIGIN
		});
		const id = parseIdBody(await request.json());
		const db = getAuthDb(env);
		if (await loadServiceTokenOwner(db, id) !== actor.id) throw new ContentAuthzError("remove", actor.id, "service token may only be revoked by its issuing user", id);
		await revokeServiceToken(db, SERVICE_TOKEN_TABLES.serviceTokens, id);
		return jsonOk({ ok: true });
	} catch (error) {
		return mapContentError(error);
	}
};
//#endregion
//#region \0virtual:astro:page:src/pages/api/admin/service-tokens@_@ts
var page = () => service_tokens_exports;
//#endregion
export { page };
