MicProtocol / apps /api /dist /trpc /trpc.init.js
Benaah's picture
Upload folder using huggingface_hub (part 2)
9f29339 verified
Raw History Blame Contribute Delete
11.2 kB
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rateLimitedWorkspaceProcedure = exports.rateLimitedProcedure = exports.adminPermissionProcedure = exports.adminProcedure = exports.requireActiveSubscription = exports.requireFeature = exports.studioProcedure = exports.creatorProcedure = exports.hobbyProcedure = exports.workspaceProc = exports.workspaceProcedure = exports.protectedProcedure = exports.middleware = exports.publicProcedure = exports.router = void 0;
const server_1 = require("@trpc/server");
const zod_1 = require("zod");
const shared_types_1 = require("@micprotocol/shared-types");
const platform_admin_1 = require("../common/platform-admin");
const subscription_features_1 = require("../billing/subscription-features");
const rate_limit_runtime_1 = require("./rate-limit.runtime");
const t = server_1.initTRPC.context().create({
errorFormatter({ shape, error }) {
let zodError = null;
if (error.cause instanceof zod_1.ZodError) {
zodError = error.cause.flatten();
}
else if (error.code === "BAD_REQUEST" && error.cause instanceof Error) {
zodError = error.cause.message;
}
return {
...shape,
data: {
...shape.data,
zodError,
timestamp: new Date().toISOString(),
},
};
},
});
exports.router = t.router;
exports.publicProcedure = t.procedure;
exports.middleware = t.middleware;
const isAuthenticated = (0, exports.middleware)(async ({ ctx, next }) => {
if (!ctx.userId) {
throw new server_1.TRPCError({
code: "UNAUTHORIZED",
message: "You must be logged in to perform this action",
});
}
return next({
ctx: {
...ctx,
userId: ctx.userId,
},
});
});
exports.protectedProcedure = exports.publicProcedure.use(isAuthenticated);
const hasWorkspace = (0, exports.middleware)(async ({ ctx, next }) => {
if (!ctx.userId) {
throw new server_1.TRPCError({
code: "BAD_REQUEST",
message: "Workspace context is required",
});
}
let workspaceId = ctx.workspaceId;
if (!workspaceId && ctx.prisma) {
const firstMembership = await ctx.prisma.workspaceMember.findFirst({
where: { userId: ctx.userId },
orderBy: { joinedAt: "asc" },
select: { workspaceId: true, role: true },
});
if (firstMembership) {
workspaceId = firstMembership.workspaceId;
}
}
if (!workspaceId) {
throw new server_1.TRPCError({
code: "BAD_REQUEST",
message: "Workspace context is required. You do not belong to any workspace yet.",
});
}
if (ctx.prisma) {
const membership = await ctx.prisma.workspaceMember.findUnique({
where: {
userId_workspaceId: {
userId: ctx.userId,
workspaceId,
},
},
});
if (!membership) {
throw new server_1.TRPCError({
code: "FORBIDDEN",
message: "You do not have access to this workspace",
});
}
return next({
ctx: {
...ctx,
workspaceId,
workspaceRole: membership.role,
},
});
}
return next({
ctx: {
...ctx,
workspaceId,
},
});
});
const subscriptionGuard = (0, exports.middleware)(async ({ ctx, next }) => {
if (!ctx.workspaceId || !ctx.prisma) {
return next({ ctx });
}
const workspace = await ctx.prisma.workspace.findUnique({
where: { id: ctx.workspaceId },
select: {
subscriptionPlanId: true,
subscriptionStatus: true,
},
});
const planId = workspace?.subscriptionPlanId || shared_types_1.SubscriptionPlanId.HOBBY;
const status = workspace?.subscriptionStatus || shared_types_1.SubscriptionStatus.ACTIVE;
const hasFeature = (feature) => {
if (status !== shared_types_1.SubscriptionStatus.ACTIVE && status !== shared_types_1.SubscriptionStatus.TRIALING) {
return subscription_features_1.PLAN_FEATURES[shared_types_1.SubscriptionPlanId.HOBBY].includes(feature);
}
return (0, subscription_features_1.planHasFeature)(planId, feature);
};
const getLimit = (limitKey) => {
if (status !== shared_types_1.SubscriptionStatus.ACTIVE && status !== shared_types_1.SubscriptionStatus.TRIALING) {
return (0, subscription_features_1.getPlanLimit)(shared_types_1.SubscriptionPlanId.HOBBY, limitKey);
}
return (0, subscription_features_1.getPlanLimit)(planId, limitKey);
};
const isUnlimitedCheck = (limitKey) => {
if (status !== shared_types_1.SubscriptionStatus.ACTIVE && status !== shared_types_1.SubscriptionStatus.TRIALING) {
return (0, subscription_features_1.isUnlimited)(shared_types_1.SubscriptionPlanId.HOBBY, limitKey);
}
return (0, subscription_features_1.isUnlimited)(planId, limitKey);
};
return next({
ctx: {
...ctx,
subscriptionPlanId: planId,
subscriptionStatus: status,
hasFeature,
getLimit,
isUnlimited: isUnlimitedCheck,
},
});
});
exports.workspaceProcedure = exports.protectedProcedure.use(hasWorkspace).use(subscriptionGuard);
exports.workspaceProc = exports.workspaceProcedure;
exports.hobbyProcedure = exports.workspaceProc.use(({ ctx, next }) => {
return next({ ctx });
});
exports.creatorProcedure = exports.workspaceProc.use(({ ctx, next }) => {
if (!ctx.hasFeature?.(subscription_features_1.SubscriptionFeature.AUTOMATED_OUTREACH)) {
throw new server_1.TRPCError({
code: "FORBIDDEN",
message: "This feature requires the Creator plan or higher. Upgrade to access automated outreach sequences.",
});
}
return next({ ctx });
});
exports.studioProcedure = exports.workspaceProc.use(({ ctx, next }) => {
if (!ctx.hasFeature?.(subscription_features_1.SubscriptionFeature.VIRALCLIP_ENGINE)) {
throw new server_1.TRPCError({
code: "FORBIDDEN",
message: "This feature requires the Studio plan. Upgrade to access ViralClip Engine and AI-powered clip detection.",
});
}
return next({ ctx });
});
const requireFeature = (feature) => exports.workspaceProc.use(({ ctx, next }) => {
if (!ctx.hasFeature?.(feature)) {
const featureLabel = feature.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
throw new server_1.TRPCError({
code: "FORBIDDEN",
message: `This feature requires a higher subscription plan. ` +
`The "${featureLabel}" feature is not available on your current plan. ` +
`Upgrade your plan to access this feature.`,
});
}
return next({ ctx });
});
exports.requireFeature = requireFeature;
exports.requireActiveSubscription = exports.workspaceProc.use(({ ctx, next }) => {
if (ctx.subscriptionStatus === shared_types_1.SubscriptionStatus.PAST_DUE || ctx.subscriptionStatus === shared_types_1.SubscriptionStatus.CANCELED || ctx.subscriptionStatus === shared_types_1.SubscriptionStatus.INCOMPLETE) {
throw new server_1.TRPCError({
code: "FORBIDDEN",
message: "Your subscription is not active. Please update your payment method or upgrade your plan.",
});
}
return next({ ctx });
});
exports.adminProcedure = exports.protectedProcedure.use(async ({ ctx, next }) => {
if (!ctx.prisma) {
throw new server_1.TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Prisma not available" });
}
const user = await ctx.prisma.user.findUnique({
where: { id: ctx.userId },
select: { isAdmin: true, adminRole: true, suspendedAt: true },
});
if (!user) {
throw new server_1.TRPCError({ code: "FORBIDDEN", message: "Admin privileges required" });
}
if (user.suspendedAt) {
throw new server_1.TRPCError({ code: "FORBIDDEN", message: "Account is suspended" });
}
if (!user.isAdmin && !user.adminRole) {
throw new server_1.TRPCError({ code: "FORBIDDEN", message: "Admin privileges required" });
}
return next({ ctx });
});
const adminPermissionProcedure = (permission) => exports.protectedProcedure.use(async ({ ctx, next }) => {
if (!ctx.prisma) {
throw new server_1.TRPCError({ code: "INTERNAL_SERVER_ERROR", message: "Prisma not available" });
}
if (!ctx.userId) {
throw new server_1.TRPCError({ code: "UNAUTHORIZED", message: "Authentication required" });
}
const user = await ctx.prisma.user.findUnique({
where: { id: ctx.userId },
select: {
isAdmin: true,
adminRole: true,
adminPermissions: true,
suspendedAt: true,
},
});
if (!user) {
throw new server_1.TRPCError({ code: "FORBIDDEN", message: "Admin privileges required" });
}
if (user.suspendedAt) {
throw new server_1.TRPCError({ code: "FORBIDDEN", message: "Account is suspended" });
}
const role = (0, platform_admin_1.deriveAdminRole)(user);
if (!role) {
throw new server_1.TRPCError({ code: "FORBIDDEN", message: "Admin privileges required" });
}
const permissions = (0, shared_types_1.resolveAdminPermissions)(role, user.adminPermissions);
if (!permissions.has(permission)) {
throw new server_1.TRPCError({
code: "FORBIDDEN",
message: `Insufficient permissions: ${permission} required`,
});
}
return next({
ctx: {
...ctx,
isAdmin: !!user.isAdmin,
adminRole: role,
adminPermissions: permissions,
},
});
});
exports.adminPermissionProcedure = adminPermissionProcedure;
const applyRateLimit = (prefix, max, windowMs, keyFn) => (0, exports.middleware)(async ({ ctx, next, input }) => {
let identifier = ctx.userId ?? ctx.workspaceId ?? null;
if (!identifier && keyFn) {
identifier = keyFn(ctx, input) || null;
}
if (!identifier) {
identifier = "anonymous";
}
const { allowed, resetAt } = await (0, rate_limit_runtime_1.checkRateLimit)(identifier, prefix, max, windowMs);
if (!allowed) {
throw new server_1.TRPCError({
code: "TOO_MANY_REQUESTS",
message: `Rate limit exceeded for "${prefix}". Retry after ${new Date(resetAt).toISOString()}.`,
});
}
return next({ ctx });
});
const rateLimitedProcedure = (prefix, max, windowMs, keyFn) => exports.publicProcedure.use(applyRateLimit(prefix, max, windowMs, keyFn));
exports.rateLimitedProcedure = rateLimitedProcedure;
const rateLimitedWorkspaceProcedure = (prefix, max, windowMs) => exports.workspaceProcedure.use(applyRateLimit(prefix, max, windowMs));
exports.rateLimitedWorkspaceProcedure = rateLimitedWorkspaceProcedure;
//# sourceMappingURL=trpc.init.js.map