rebreak-monorepo/backend/server/api/magic/profile.mobileconfig.get.ts
chahinebrini c1edef8abd feat(magic): RebreakMagic device-binding + DNS profile
- backend: /api/magic/{register,devices,profile,release} + AdGuard provisioning + 24h cooldown
- prisma: magic_binding_fields migration (additive on UserDevice)
- mac-app: Phase 2 - Login + MacRegistration + Profile install
- marketing: landing section + /download/rebreakmagic + DMG
- lyra: forbidden phrases + RebreakMagic coach guidance
2026-06-02 09:15:19 +02:00

94 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { randomUUID } from 'crypto';
import { readFile } from 'fs/promises';
import { resolve } from 'path';
/**
* GET /api/magic/profile.mobileconfig?token=<dnsToken>
*
* Generiert personalisiertes DNS-Configuration-Profile für macOS.
* Template: ops/mdm/rebreak-mac-dns-filter.mobileconfig
*
* Ersetzt:
* - ServerURL: /dns-query → /dns-query/{token}
* - PayloadUUID: 2× neu generieren (DNSSettings + Profile root)
* - PayloadIdentifier: unique pro Device
*
* TODO: Profile-Signierung via Apple Developer Certificate (Phase 2)
*/
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',
});
}
// Token in DB suchen (nur aktive, nicht revoked)
const device = await findMagicDeviceByToken(token);
if (!device) {
throw createError({
statusCode: 404,
message: 'Invalid or revoked DNS token',
});
}
// Template lesen
const templatePath = resolve(
process.cwd(),
'ops/mdm/rebreak-mac-dns-filter.mobileconfig',
);
let template: string;
try {
template = await readFile(templatePath, 'utf-8');
} catch (err: any) {
console.error('[Magic] Failed to read profile template:', err);
throw createError({
statusCode: 500,
message: 'Profile template not found',
});
}
// ServerURL ersetzen: /dns-query → /dns-query/{token}
const personalizedProfile = template
.replace(
'https://dns.rebreak.org/dns-query',
`https://dns.rebreak.org/dns-query/${token}`,
)
// PayloadUUID neu generieren (2 Stellen im Template)
.replace(
'7D2E8B1A-C3D4-4E76-8B23-A4B5C6D7E8F0',
randomUUID().toUpperCase(),
)
.replace(
'8C3F9A2B-D4E5-4F87-9A12-B5C6D7E8F901',
randomUUID().toUpperCase(),
)
// PayloadIdentifier unique machen (optional, verhindert Konflikt bei Multi-Device)
.replace(
'org.rebreak.protection.dns.filter',
`org.rebreak.protection.dns.filter.${device.deviceId.slice(0, 8)}`,
)
.replace(
'org.rebreak.protection.profile',
`org.rebreak.protection.profile.${device.deviceId.slice(0, 8)}`,
);
// Response-Headers
setHeader(event, 'Content-Type', 'application/x-apple-aspen-config');
setHeader(
event,
'Content-Disposition',
`attachment; filename="RebreakMagic-${device.deviceId.slice(0, 8)}.mobileconfig"`,
);
// TODO: Profile-Signierung via /usr/bin/security cms -S
// Requires: Apple Developer Certificate + Private Key in Keychain
// Siehe: https://developer.apple.com/documentation/devicemanagement/profile-specific_payload_keys
return personalizedProfile;
});