Backend: - ProtectedDevice prisma model + migration add_protected_devices - DB helpers: list/count/get/create/confirm/revoke - mobileconfig.ts utility — XML-escape, unique UUIDs per request - 5 endpoints under /api/devices/* (avoid /api/devices conflict with existing Capacitor UserDevice route by using /api/devices/protected for list) Phase 1: backend ready. DoH-server token-routing comes in phase 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
37 lines
1.1 KiB
TypeScript
37 lines
1.1 KiB
TypeScript
import { revokeProtectedDevice } from "../../../db/protectedDevices";
|
|
|
|
/**
|
|
* DELETE /api/devices/:id/revoke
|
|
*
|
|
* User entfernt ein Protected-Device aus der App.
|
|
* Soft-delete: status=revoked, revokedAt=NOW(). Kein hard-delete (DSGVO-Audit-Trail).
|
|
*
|
|
* WICHTIG: Das Profil bleibt auf dem Mac installiert bis der User es manuell
|
|
* entfernt. Das Backend kann das nicht aus der Ferne erzwingen (Phase 2: MDM).
|
|
*
|
|
* Auth: requireUser + ownership (revokeProtectedDevice prüft userId).
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event);
|
|
const id = getRouterParam(event, "id");
|
|
if (!id) throw createError({ statusCode: 400, data: { error: "ID_REQUIRED" } });
|
|
|
|
const revoked = await revokeProtectedDevice(id, user.id);
|
|
|
|
if (!revoked) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
data: { error: "DEVICE_NOT_FOUND_OR_ALREADY_REVOKED" },
|
|
});
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
manualRemovalRequired: true,
|
|
data: {
|
|
error: "MANUAL_REMOVAL_REQUIRED",
|
|
// Frontend übersetzt diesen Code in die passende UI-Meldung
|
|
},
|
|
};
|
|
});
|