import { requireUser } from "../../utils/auth"; import { getActiveCooldown, createCooldown } from "../../db/cooldown"; import { signCooldownToken, generateJti } from "../../utils/cooldownToken"; import { usePrisma } from "../../utils/prisma"; /** POST /api/cooldown/request — Start a 24h cooldown before protection can be disabled. */ export default defineEventHandler(async (event) => { const user = await requireUser(event); const body = await readBody(event).catch(() => ({})); // ─── MDM-Guard: MDM-User können sich nie selbst deaktivieren. const db = usePrisma(); const profile = await db.profile.findUnique({ where: { id: user.id }, select: { mdmManaged: true }, }); if (profile?.mdmManaged) { throw createError({ statusCode: 400, data: { error: "mdm_managed_cannot_self_deactivate" }, }); } // Reject if a cooldown is already running (not resolved, not cancelled). const existing = await getActiveCooldown(user.id); if (existing) { const now = new Date(); // If the existing one already expired but wasn't resolved yet, that's fine — // it means canDisableProtection is already true. Return 409 so the client // calls /status instead. throw createError({ statusCode: 409, data: { error: "cooldown_already_active", existingEndsAt: existing.cooldownEndsAt.toISOString(), }, }); } // Test-Mode (5min statt 24h) — nur außerhalb von Production aktivierbar. // Detection via appUrl statt NODE_ENV, da staging.rebreak.org auch mit // NODE_ENV=production läuft (siehe start-staging.sh). const config = useRuntimeConfig(event); const appUrl = (config.public?.appUrl as string) ?? ""; const isProductionUrl = appUrl.includes("rebreak.org") && !appUrl.includes("staging"); const isTestMode = body?.testMode === true && !isProductionUrl; const cooldownMs = isTestMode ? 40 * 1000 : 24 * 60 * 60 * 1000; const now = new Date(); const cooldownEndsAt = new Date(now.getTime() + cooldownMs); const jti = generateJti(); await createCooldown(user.id, jti, cooldownEndsAt, body?.reason); const remainingSeconds = Math.max( 0, Math.floor((cooldownEndsAt.getTime() - Date.now()) / 1000), ); const token = await signCooldownToken(user.id, jti, cooldownEndsAt); return { success: true, data: { cooldownStartedAt: now.toISOString(), cooldownEndsAt: cooldownEndsAt.toISOString(), remainingSeconds, token, testMode: isTestMode, }, }; });