feat: add API authentication context to TRPC and refactor Stripe webhook handler

This commit is contained in:
Marco Pedone 2026-03-05 11:54:04 +01:00
parent 8d89be35d5
commit b27c06a18b
2 changed files with 20 additions and 7 deletions

View file

@ -4,17 +4,13 @@ import { env } from "~/env";
import stripe from "~/lib/stripe"; import stripe from "~/lib/stripe";
import type { PaymentsId } from "~/schemas/public/Payments"; import type { PaymentsId } from "~/schemas/public/Payments";
import { appRouter } from "~/server/api/root"; import { appRouter } from "~/server/api/root";
import { createTRPCContext, t } from "~/server/api/trpc"; import { addApiAuthToContext, createTRPCContext, t } from "~/server/api/trpc";
const handler = async ( const handler = async (
req: NextApiRequest, req: NextApiRequest,
res: NextApiResponse, res: NextApiResponse,
): Promise<void> => { ): Promise<void> => {
if (req.method === "POST") { if (req.method === "POST") {
const ctx = await createTRPCContext({ req: req, res: res });
const createCaller = t.createCallerFactory(appRouter);
const caller = createCaller(ctx);
const sig = req.headers["stripe-signature"]; const sig = req.headers["stripe-signature"];
let event: Stripe.Event; let event: Stripe.Event;
@ -34,6 +30,10 @@ const handler = async (
res.status(400).send(`Webhook Error: ${(err as Error).message}`); res.status(400).send(`Webhook Error: ${(err as Error).message}`);
return; return;
} }
const ctx = await createTRPCContext({ req: req, res: res });
addApiAuthToContext(ctx);
const createCaller = t.createCallerFactory(appRouter);
const caller = createCaller(ctx);
// Handle the event // Handle the event
switch (event.type) { switch (event.type) {

View file

@ -75,8 +75,19 @@ export const createTRPCContext = async ({
res, res,
}; };
}; };
export type Context = Awaited<ReturnType<typeof createInnerTRPCContext>>; export type Context = Awaited<ReturnType<typeof createInnerTRPCContext>>;
export const addApiAuthToContext = (ctx: Context) => {
if (!ctx.req || !ctx.res) {
throw new Error(
"You are missing `req` or `res` in your call to addApiAuthToContext.",
);
}
const authString = Buffer.from(
`${env.EXP_API_USER}:${env.EXP_API_PASS}`,
).toString("base64");
ctx.req.headers.authorization = `Basic ${authString}`;
return ctx;
};
/** /**
* 2. INITIALIZATION * 2. INITIALIZATION
@ -185,7 +196,9 @@ const enforceUserIsAuthedOrOverride = t.middleware(({ ctx, next, path }) => {
* @see https://trpc.io/docs/procedures * @see https://trpc.io/docs/procedures
*/ */
export const protectedProcedure = t.procedure.use(enforceUserIsAuthed); export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
export const overridableProcedure = t.procedure.use(enforceUserIsAuthedOrOverride); export const overridableProcedure = t.procedure.use(
enforceUserIsAuthedOrOverride,
);
/** Reusable middleware that enforces users are logged in before running the procedure. */ /** Reusable middleware that enforces users are logged in before running the procedure. */
const enforceUserIsAdmin = t.middleware(({ ctx, next, path }) => { const enforceUserIsAdmin = t.middleware(({ ctx, next, path }) => {