import { randomUUID } from "crypto"; import { findMagicDeviceByToken, ensureMagicRemovalPassword, } from "../../db/devices"; import { MAGIC_PROFILE_TEMPLATE } from "../../utils/magic-profile-template"; import { buildRemovalPasswordPayload, generateRemovalPassword, signProfileIfConfigured, } from "../../utils/magic-lock"; /** * GET /api/magic/profile.mobileconfig?token= * * Generiert das personalisierte, GESPERRTE DNS-Config-Profil für macOS/Windows. * Template: ops/mdm/rebreak-mac-dns-filter.mobileconfig (inlined als TS const). * * Hard-Lock-Payloads: * - DNS-Filter (com.apple.dnsSettings.managed) mit ProhibitDisablement * - PayloadRemovalDisallowed + PayloadScope=System (im Template) * - com.apple.profileRemovalPassword mit server-gehaltenem Passwort (hier * injiziert) — der User sieht es NIE, nur nach Cooldown-Release (Offboarding). * * Signing: wenn Cert via runtimeConfig konfiguriert → CMS-signiert (grünes * „Verifiziert"), sonst unsigniert (Lock greift trotzdem). Siehe magic-lock.ts. */ export default defineEventHandler(async (event) => { const query = getQuery(event); const token = query.token as string | undefined; if (!token) { throw createError({ statusCode: 400, message: "token query parameter required", }); } const device = await findMagicDeviceByToken(token); if (!device) { throw createError({ statusCode: 404, message: "Invalid or revoked DNS token", }); } // Removal-Passwort: aus DB oder Lazy-Backfill (Devices vor dem Hard-Lock). let removalPassword = device.magicRemovalPassword; if (!removalPassword) { removalPassword = generateRemovalPassword(); await ensureMagicRemovalPassword(device.id, removalPassword); } const deviceSlice = device.deviceId.slice(0, 8); // Personalisierung: ServerURL → token-spezifisch, UUIDs/Identifier unique. let personalizedProfile = MAGIC_PROFILE_TEMPLATE.replace( "https://dns.rebreak.org/dns-query", `https://dns.rebreak.org/dns-query/${token}`, ) .replace("7D2E8B1A-C3D4-4E76-8B23-A4B5C6D7E8F0", randomUUID().toUpperCase()) .replace("8C3F9A2B-D4E5-4F87-9A12-B5C6D7E8F901", randomUUID().toUpperCase()) .replace( "org.rebreak.protection.dns.filter", `org.rebreak.protection.dns.filter.${deviceSlice}`, ) .replace( "org.rebreak.protection.profile", `org.rebreak.protection.profile.${deviceSlice}`, ); // Removal-Passwort-Payload in die PayloadContent-Array injizieren. const removalPayload = buildRemovalPasswordPayload(removalPassword, deviceSlice); personalizedProfile = personalizedProfile.replace( " ", `${removalPayload}\n `, ); // Optional signieren (config-gated; inaktiv ohne Cert). const config = useRuntimeConfig(event); const signed = signProfileIfConfigured( personalizedProfile, (config as any).magicSigning, ); setHeader(event, "Content-Type", "application/x-apple-aspen-config"); setHeader( event, "Content-Disposition", `attachment; filename="RebreakMagic-${deviceSlice}.mobileconfig"`, ); return signed; });