queue-med/server/_core/trpc.ts

66 lines
1.8 KiB
TypeScript

import { initTRPC, TRPCError } from "@trpc/server";
import type { TrpcContext } from "./context.js";
import { isSubscriptionActive } from "../db.js";
const t = initTRPC.context<TrpcContext>().create({
errorFormatter({ shape }) {
return shape;
},
});
export const router = t.router;
export const middleware = t.middleware;
export const publicProcedure = t.procedure;
const isAuthed = t.middleware(({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Authentication required" });
}
if (ctx.user.disabled) {
throw new TRPCError({ code: "FORBIDDEN", message: "Compte désactivé" });
}
return next({
ctx: {
...ctx,
user: ctx.user,
},
});
});
export const protectedProcedure = t.procedure.use(isAuthed);
const isAdmin = t.middleware(({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Authentication required" });
}
if (ctx.user.disabled) {
throw new TRPCError({ code: "FORBIDDEN", message: "Compte désactivé" });
}
if (ctx.user.role !== "admin") {
throw new TRPCError({ code: "FORBIDDEN", message: "Accès réservé aux administrateurs" });
}
return next({
ctx: {
...ctx,
user: ctx.user,
},
});
});
export const adminProcedure = t.procedure.use(isAdmin);
const requireActiveSubscription = t.middleware(async ({ ctx, next }) => {
if (!ctx.user) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "Authentication required" });
}
const active = await isSubscriptionActive(ctx.user.id);
if (!active) {
throw new TRPCError({
code: "FORBIDDEN",
message: "Subscription expired or inactive",
});
}
return next({ ctx: { ...ctx, user: ctx.user } });
});
export const subscriptionProcedure = t.procedure.use(requireActiveSubscription);