import { getApprovalRequest, markEmailSent } from "../../../../db/device-approvals"; import { getProfile } from "../../../../db/profile"; import { sendDeviceApprovalEmail } from "../../../../utils/device-approval-email"; /** * POST /api/devices/approvals/:id/email * * Email-Fallback: das NEUE Gerät triggert den Versand der Approval-Mail an die * User-Email. Nützlich wenn kein anderes Gerät online ist (User hat altes Phone * verloren / Reinstall). * * Rate-Limit: 1 Mail pro Approval-Request (markEmailSent ist idempotent). * skipDeviceCheck=true. */ export default defineEventHandler(async (event) => { const user = await requireUser(event, { skipDeviceCheck: true }); const id = getRouterParam(event, "id"); if (!id) { throw createError({ statusCode: 400, message: "id required" }); } const before = await getApprovalRequest(id, user.id); if (!before) { throw createError({ statusCode: 404, message: "approval not found" }); } if (before.status !== "pending") { throw createError({ statusCode: 409, message: `approval is ${before.status}`, }); } const updated = await markEmailSent(id, user.id); if (!updated || !updated.emailToken) { throw createError({ statusCode: 500, message: "failed to prepare email" }); } // Bereits einmal gesendet → kein Resend (Rate-Limit) if (before.emailSentAt) { return { approval: updated, alreadySent: true }; } const profile = await getProfile(user.id); const config = useRuntimeConfig(event); const resendApiKey = (config as any).resendApiKey as string | undefined; const appBaseUrl = ((config as any).public?.appBaseUrl as string | undefined) ?? "https://app.rebreak.org"; const newDeviceLabel = [ updated.newName ?? updated.newModel ?? "Unbekanntes Gerät", `(${updated.newPlatform})`, ].join(" "); // fire-and-forget — Mail-Fehler blockiert nicht den Endpoint sendDeviceApprovalEmail({ recipientNickname: profile?.nickname ?? "User", recipientEmail: user.email ?? "", code: updated.code, emailToken: updated.emailToken, newDeviceLabel, expiresAt: updated.expiresAt, resendApiKey: resendApiKey ?? "", appBaseUrl, }).catch((err) => console.error("[approvals/email] send failed:", err?.message ?? err), ); return { approval: updated, alreadySent: false }; });