43 lines
1.2 KiB
TypeScript
43 lines
1.2 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" });
|
|
}
|
|
return next({
|
|
ctx: {
|
|
...ctx,
|
|
user: ctx.user,
|
|
},
|
|
});
|
|
});
|
|
|
|
export const protectedProcedure = t.procedure.use(isAuthed);
|
|
|
|
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);
|