Files
wallabicher/web/backend/middlewares/subscriptionLimits.js
Omar Sánchez Pizarro 6ec8855c00 add landing and subscription plans
Signed-off-by: Omar Sánchez Pizarro <omar.sanchez@pistacero.net>
2026-01-20 23:49:19 +01:00

134 lines
4.2 KiB
JavaScript

import { getUser, getUserSubscription, getWorkerCount } from '../services/mongodb.js';
import { getPlan, getMaxWorkers, hasPlatformAccess } from '../config/subscriptionPlans.js';
// Middleware para verificar límites de suscripción
export async function checkSubscriptionLimits(req, res, next) {
try {
const username = req.user?.username;
if (!username) {
return res.status(401).json({ error: 'Authentication required' });
}
// Obtener usuario y suscripción
const user = await getUser(username);
if (!user) {
return res.status(404).json({ error: 'Usuario no encontrado' });
}
// Si es admin, no aplicar límites
if (user.role === 'admin') {
return next();
}
const subscription = await getUserSubscription(username);
const planId = subscription?.planId || 'free';
const plan = getPlan(planId);
// Añadir información del plan al request para uso posterior
req.userPlan = {
planId,
plan,
subscription,
};
next();
} catch (error) {
console.error('Error verificando límites de suscripción:', error);
res.status(500).json({ error: 'Error verificando límites de suscripción' });
}
}
// Middleware para verificar límite de workers
export async function checkWorkerLimit(req, res, next) {
try {
const username = req.user?.username;
const userPlan = req.userPlan;
if (!userPlan) {
// Si no hay userPlan, ejecutar checkSubscriptionLimits primero
await checkSubscriptionLimits(req, res, () => {});
if (res.headersSent) return;
}
const planId = req.userPlan.planId;
const maxWorkers = getMaxWorkers(planId);
// Si es ilimitado (-1), permitir
if (maxWorkers === -1) {
return next();
}
// Obtener número actual de workers
const currentWorkerCount = await getWorkerCount(username);
// Si estamos actualizando workers, verificar el nuevo número
if (req.method === 'PUT' && req.body?.items) {
const newWorkerCount = (req.body.items || []).filter(
(item, index) => !(req.body.disabled || []).includes(index)
).length;
if (newWorkerCount > maxWorkers) {
return res.status(403).json({
error: 'Límite de búsquedas excedido',
message: `Tu plan actual (${req.userPlan.plan.name}) permite hasta ${maxWorkers} búsquedas simultáneas. Estás intentando crear ${newWorkerCount}.`,
currentPlan: planId,
maxWorkers,
currentCount: currentWorkerCount,
requestedCount: newWorkerCount,
});
}
} else if (currentWorkerCount >= maxWorkers) {
// Si ya alcanzó el límite y está intentando crear más
return res.status(403).json({
error: 'Límite de búsquedas alcanzado',
message: `Tu plan actual (${req.userPlan.plan.name}) permite hasta ${maxWorkers} búsquedas simultáneas.`,
currentPlan: planId,
maxWorkers,
currentCount: currentWorkerCount,
});
}
next();
} catch (error) {
console.error('Error verificando límite de workers:', error);
res.status(500).json({ error: 'Error verificando límite de workers' });
}
}
// Middleware para verificar acceso a plataforma
export async function checkPlatformAccess(req, res, next) {
try {
const platform = req.body?.platform || req.query?.platform;
if (!platform) {
return next(); // Si no hay plataforma especificada, continuar
}
const userPlan = req.userPlan;
if (!userPlan) {
await checkSubscriptionLimits(req, res, () => {});
if (res.headersSent) return;
}
const planId = req.userPlan.planId;
if (!hasPlatformAccess(planId, platform)) {
return res.status(403).json({
error: 'Plataforma no disponible en tu plan',
message: `La plataforma "${platform}" no está disponible en tu plan actual (${req.userPlan.plan.name}).`,
currentPlan: planId,
requestedPlatform: platform,
availablePlatforms: req.userPlan.plan.limits.platforms,
});
}
next();
} catch (error) {
console.error('Error verificando acceso a plataforma:', error);
res.status(500).json({ error: 'Error verificando acceso a plataforma' });
}
}