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 }; }