- backend/api/magic/register: explicit import of MAGIC_DEVICE_LIMIT and createAdGuardClient (Nitro auto-import was missing them → ReferenceError → HTTP 500 on /api/magic/register) - mac-app: default backendBaseUrl falls back to staging.rebreak.org (app.rebreak.org serves wrong TLS cert) - native MagicSheet: fallback download/dmg URLs point to staging - native settings: Magic sheet capped at detents=[0.85] so AppHeader stays visible - bundles all in-flight Magic feature work (pair create/redeem, device endpoints, schema, adguard utils, mac-app, locales)
71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
/**
|
|
* POST /api/magic/devices/[deviceId]/request-release
|
|
*
|
|
* Startet 24h Cooldown für Magic-Device-Binding.
|
|
* Nach 24h wird Token automatisch via Cron invalidiert.
|
|
*
|
|
* Idempotent: wenn bereits gesetzt → return existing.
|
|
*/
|
|
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",
|
|
});
|
|
}
|
|
|
|
// Idempotent: wenn bereits gesetzt → return existing
|
|
if (device.releaseRequestedAt) {
|
|
const releaseAvailableAt = new Date(
|
|
device.releaseRequestedAt.getTime() + 24 * 60 * 60 * 1000,
|
|
);
|
|
return {
|
|
success: true,
|
|
data: {
|
|
releaseRequestedAt: device.releaseRequestedAt.toISOString(),
|
|
releaseAvailableAt: releaseAvailableAt.toISOString(),
|
|
},
|
|
};
|
|
}
|
|
|
|
// Setze releaseRequestedAt
|
|
const now = new Date();
|
|
await db.userDevice.update({
|
|
where: { id: device.id },
|
|
data: { releaseRequestedAt: now },
|
|
});
|
|
|
|
const releaseAvailableAt = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
releaseRequestedAt: now.toISOString(),
|
|
releaseAvailableAt: releaseAvailableAt.toISOString(),
|
|
},
|
|
};
|
|
});
|