- 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
58 lines
1.3 KiB
TypeScript
58 lines
1.3 KiB
TypeScript
|
|
|
|
/**
|
|
* POST /api/magic/devices/[deviceId]/cancel-release
|
|
*
|
|
* User zieht Release-Request zurück. Setzt releaseRequestedAt zurück auf NULL.
|
|
*/
|
|
export default defineEventHandler(async (event) => {
|
|
const user = await requireUser(event);
|
|
const deviceId = getRouterParam(event, 'deviceId');
|
|
|
|
if (!deviceId) {
|
|
throw createError({
|
|
statusCode: 400,
|
|
message: 'deviceId required',
|
|
});
|
|
}
|
|
|
|
const db = usePrisma();
|
|
|
|
// Ownership-Check + Magic-Binding-Check
|
|
const device = await db.userDevice.findUnique({
|
|
where: { userId_deviceId: { userId: user.id, deviceId } },
|
|
select: {
|
|
id: true,
|
|
magicEnrolledAt: true,
|
|
magicRevokedAt: true,
|
|
releaseRequestedAt: true,
|
|
},
|
|
});
|
|
|
|
if (!device || !device.magicEnrolledAt || device.magicRevokedAt) {
|
|
throw createError({
|
|
statusCode: 404,
|
|
message: 'Magic-Binding nicht gefunden oder bereits revoked',
|
|
});
|
|
}
|
|
|
|
if (!device.releaseRequestedAt) {
|
|
// Idempotent: kein offener Request → noop
|
|
return {
|
|
success: true,
|
|
data: { ok: true },
|
|
};
|
|
}
|
|
|
|
// Clear releaseRequestedAt
|
|
await db.userDevice.update({
|
|
where: { id: device.id },
|
|
data: { releaseRequestedAt: null },
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
data: { ok: true },
|
|
};
|
|
});
|