import { MUST_CHANGE_PASSWORD_ERR_MSG, 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().create({ transformer: superjson, }); export const router = t.router; export const publicProcedure = t.procedure; const requireSession = t.middleware(async opts => { const { ctx, next } = opts; if (!ctx.user) { throw new TRPCError({ code: "UNAUTHORIZED", message: UNAUTHED_ERR_MSG }); } return next({ ctx: { ...ctx, user: ctx.user, }, }); }); export const sessionProcedure = t.procedure.use(requireSession); const requireReadableUser = t.middleware(async opts => { if (!opts.ctx.user) { throw new TRPCError({ code: "UNAUTHORIZED", message: UNAUTHED_ERR_MSG }); } if (opts.ctx.user.mustChangePassword === 1) { throw new TRPCError({ code: "FORBIDDEN", message: MUST_CHANGE_PASSWORD_ERR_MSG }); } if (opts.type === "mutation" && opts.ctx.user.role === "user") { throw new TRPCError({ code: "FORBIDDEN", message: NOT_ADMIN_ERR_MSG }); } return opts.next({ ctx: { ...opts.ctx, user: opts.ctx.user } }); }); export const protectedProcedure = t.procedure.use(requireReadableUser); export const adminProcedure = t.procedure.use( t.middleware(async opts => { const { ctx, next } = opts; if (!ctx.user) { throw new TRPCError({ code: "UNAUTHORIZED", message: UNAUTHED_ERR_MSG }); } if (ctx.user.mustChangePassword === 1) { throw new TRPCError({ code: "FORBIDDEN", message: MUST_CHANGE_PASSWORD_ERR_MSG }); } if (ctx.user.role !== 'admin' && ctx.user.role !== 'super_admin') { throw new TRPCError({ code: "FORBIDDEN", message: NOT_ADMIN_ERR_MSG }); } return next({ ctx: { ...ctx, user: ctx.user, }, }); }), ); export const superAdminProcedure = t.procedure.use( t.middleware(async opts => { if (!opts.ctx.user) throw new TRPCError({ code: "UNAUTHORIZED", message: UNAUTHED_ERR_MSG }); if (opts.ctx.user.mustChangePassword === 1) { throw new TRPCError({ code: "FORBIDDEN", message: MUST_CHANGE_PASSWORD_ERR_MSG }); } if (opts.ctx.user.role !== "super_admin") { throw new TRPCError({ code: "FORBIDDEN", message: NOT_ADMIN_ERR_MSG }); } return opts.next({ ctx: { ...opts.ctx, user: opts.ctx.user } }); }), );