chahinebrini 77edd67cbe fix(magic): explicit imports + staging defaults + sheet height
- 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)
2026-06-03 08:25:02 +02:00

89 lines
2.5 KiB
TypeScript

import { usePrisma } from "./prisma";
import { deleteAdGuardClient } from "./adguard";
/**
* Cron-Worker für RebreakMagic Release-Requests (24h Cooldown).
* Findet alle Devices mit abgelaufenem Release-Request und invalidiert Token.
*
* USAGE:
* - Via Nitro scheduled task (nitro.config.ts)
* - Via externer Cron (curl POST /api/cron/magic-releases mit Auth-Header)
* - Manuell für Testing: await processMagicReleases()
*/
export async function processMagicReleases(): Promise<{
processed: number;
errors: Array<{ deviceId: string; error: string }>;
}> {
const db = usePrisma();
const now = new Date();
const releaseThreshold = new Date(now.getTime() - 24 * 60 * 60 * 1000);
// Finde Devices mit abgelaufenem Release (24h Cooldown rum)
const devicesToRelease = await db.userDevice.findMany({
where: {
releaseRequestedAt: {
lte: releaseThreshold,
},
magicRevokedAt: null,
magicEnrolledAt: { not: null },
},
select: {
id: true,
deviceId: true,
userId: true,
magicDnsToken: true,
releaseRequestedAt: true,
},
});
console.log(
`[MagicCron] Processing ${devicesToRelease.length} devices for release`,
);
const errors: Array<{ deviceId: string; error: string }> = [];
let processed = 0;
for (const device of devicesToRelease) {
try {
// 1. Invalidate DNS-Token (AdGuard Client löschen)
const clientName = `magic_${device.deviceId}`;
try {
await deleteAdGuardClient(clientName);
console.log(`[MagicCron] Deleted AdGuard client: ${clientName}`);
} catch (err: any) {
console.warn(
`[MagicCron] AdGuard deletion failed for ${clientName}: ${err.message}`,
);
// Continue — DB-Invalidierung erfolgt trotzdem (Failsafe)
}
// 2. Setze magicRevokedAt (Token serverseitig tot)
await db.userDevice.update({
where: { id: device.id },
data: {
magicRevokedAt: now,
},
});
console.log(
`[MagicCron] Released Magic binding: userId=${device.userId} deviceId=${device.deviceId}`,
);
processed++;
} catch (err: any) {
console.error(
`[MagicCron] Failed to release device ${device.deviceId}:`,
err,
);
errors.push({
deviceId: device.deviceId,
error: err.message || String(err),
});
}
}
console.log(
`[MagicCron] Finished: ${processed} released, ${errors.length} errors`,
);
return { processed, errors };
}