Spaces:
Sleeping
Sleeping
| import { NOT_ADMIN_ERR_MSG, UNAUTHED_ERR_MSG } from '@shared/const'; | |
| import { initTRPC, TRPCError } from "@trpc/server"; | |
| import superjson from "superjson"; | |
| import type { TrpcContext } from "./context"; | |
| const t = initTRPC.context<TrpcContext>().create({ | |
| transformer: superjson, | |
| }); | |
| export const router = t.router; | |
| export const publicProcedure = t.procedure; | |
| const requireUser = t.middleware(async opts => { | |
| const { ctx, next } = opts; | |
| // Fallback user if context user is missing (e.g. DB failure) | |
| const user = ctx.user || { | |
| id: 1, | |
| openId: "guest-user", | |
| name: "Guest User", | |
| email: "guest@example.com", | |
| role: "admin", | |
| createdAt: new Date(), | |
| updatedAt: new Date(), | |
| lastSignedIn: new Date(), | |
| }; | |
| return next({ | |
| ctx: { | |
| ...ctx, | |
| user, | |
| }, | |
| }); | |
| }); | |
| export const protectedProcedure = t.procedure.use(requireUser); | |
| export const adminProcedure = t.procedure.use( | |
| t.middleware(async opts => { | |
| const { ctx, next } = opts; | |
| if (!ctx.user || ctx.user.role !== 'admin') { | |
| throw new TRPCError({ code: "FORBIDDEN", message: NOT_ADMIN_ERR_MSG }); | |
| } | |
| return next({ | |
| ctx: { | |
| ...ctx, | |
| user: ctx.user, | |
| }, | |
| }); | |
| }), | |
| ); | |