-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🔧 feat(cron): enhance marketing notification endpoint security and er…
…ror handling
- Loading branch information
1 parent
8ce0f9a
commit 144338f
Showing
1 changed file
with
40 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,54 @@ | ||
import { NextResponse } from "next/server"; | ||
import { TRPCError } from "@trpc/server"; | ||
import { getHTTPStatusCodeFromError } from "@trpc/server/http"; | ||
|
||
import { appRouter } from "@soonlist/api"; | ||
import { createTRPCContext } from "@soonlist/api/trpc"; | ||
|
||
export async function GET(req: Request) { | ||
try { | ||
const caller = appRouter.createCaller( | ||
await createTRPCContext({ headers: req.headers }), | ||
); | ||
export const dynamic = "force-dynamic"; | ||
export const maxDuration = 300; | ||
|
||
// Helper function to validate the authorization token | ||
function isAuthorized(request: Request): boolean { | ||
const authHeader = request.headers.get("authorization"); | ||
const expectedToken = process.env.CRON_SECRET; | ||
return authHeader === `Bearer ${expectedToken}`; | ||
} | ||
|
||
export async function GET(request: Request) { | ||
// Check if the request is authorized | ||
if (!isAuthorized(request)) { | ||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); | ||
} | ||
|
||
const ctx = await createTRPCContext({ headers: new Headers() }); | ||
const caller = appRouter.createCaller(ctx); | ||
|
||
try { | ||
await caller.notification.sendMarketingNotification({ | ||
adminSecret: process.env.ADMIN_SECRET || "", | ||
adminSecret: process.env.CRON_SECRET || "", | ||
title: "📸 Soonlist Just Got Better!", | ||
body: "Tap to explore our streamlined capture flow, event stats & more. Not seeing it? Update in TestFlight.", | ||
data: { | ||
url: "/feed", | ||
}, | ||
}); | ||
|
||
return new Response("Marketing notification sent successfully", { | ||
status: 200, | ||
}); | ||
} catch (error) { | ||
console.error("Error sending marketing notification:", error); | ||
return new Response("Error sending marketing notification", { | ||
status: 500, | ||
}); | ||
return NextResponse.json({ success: true }); | ||
} catch (cause) { | ||
console.error("Error sending marketing notification:", cause); | ||
|
||
if (cause instanceof TRPCError) { | ||
const httpStatusCode = getHTTPStatusCodeFromError(cause); | ||
return NextResponse.json( | ||
{ success: false, error: { message: cause.message } }, | ||
{ status: httpStatusCode }, | ||
); | ||
} | ||
|
||
return NextResponse.json( | ||
{ success: false, error: { message: "Internal Server Error" } }, | ||
{ status: 500 }, | ||
); | ||
} | ||
} |