import { timingSafeEqual } from 'crypto' import { z } from 'zod' import { sendPushToUser } from '@/lib/push-server' const schema = z.object({ userId: z.string().min(1), payload: z.object({ title: z.string().max(80), body: z.string().max(300), url: z.string().startsWith('/').or(z.string().url()), tag: z.string().optional(), }), }) export async function POST(req: Request) { if (!process.env.INTERNAL_PUSH_SECRET) { return new Response(null, { status: 503 }) } const authHeader = req.headers.get('authorization') ?? '' const expected = `Bearer ${process.env.INTERNAL_PUSH_SECRET}` let authorized = false try { authorized = authHeader.length === expected.length && timingSafeEqual(Buffer.from(authHeader), Buffer.from(expected)) } catch { authorized = false } if (!authorized) { return new Response(null, { status: 401 }) } let body: unknown try { body = await req.json() } catch { return new Response(null, { status: 400 }) } const parsed = schema.safeParse(body) if (!parsed.success) { return Response.json({ errors: parsed.error.flatten().fieldErrors }, { status: 422 }) } await sendPushToUser(parsed.data.userId, parsed.data.payload) return new Response(null, { status: 204 }) }