81 lines
2.0 KiB
JavaScript
81 lines
2.0 KiB
JavaScript
|
|
/**
|
||
|
|
* Middleware to check subscription status for protected routes
|
||
|
|
*/
|
||
|
|
export function requireActiveSubscription(req, res, next) {
|
||
|
|
// Check if user has subscription info attached
|
||
|
|
if (!req.subscription) {
|
||
|
|
return res.status(403).json({
|
||
|
|
error: 'Active subscription required',
|
||
|
|
code: 'NO_SUBSCRIPTION'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if subscription is active (not cancelled or past due)
|
||
|
|
if (req.subscription.status !== 'active' && req.subscription.status !== 'trialing') {
|
||
|
|
return res.status(403).json({
|
||
|
|
error: 'Subscription not active',
|
||
|
|
code: 'SUBSCRIPTION_INACTIVE',
|
||
|
|
status: req.subscription.status
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
// Check if trial has expired (if trialing)
|
||
|
|
if (req.subscription.status === 'trialing' && req.subscription.trial_end) {
|
||
|
|
const trialEnd = new Date(req.subscription.trial_end);
|
||
|
|
if (new Date() > trialEnd) {
|
||
|
|
return res.status(403).json({
|
||
|
|
error: 'Trial period expired',
|
||
|
|
code: 'TRIAL_EXPIRED'
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
next();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Middleware to attach subscription info to request
|
||
|
|
* Must be placed after verifyToken middleware
|
||
|
|
*/
|
||
|
|
export function attachSubscription(pool) {
|
||
|
|
return async (req, res, next) => {
|
||
|
|
if (!req.user) {
|
||
|
|
return next();
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const result = await pool.query(
|
||
|
|
'SELECT * FROM subscriptions WHERE user_id = $1',
|
||
|
|
[req.user.id]
|
||
|
|
);
|
||
|
|
|
||
|
|
if (result.rows.length > 0) {
|
||
|
|
req.subscription = result.rows[0];
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Error fetching subscription:', error);
|
||
|
|
}
|
||
|
|
|
||
|
|
next();
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Middleware to check if user is on free tier or has active subscription
|
||
|
|
*/
|
||
|
|
export function requireFreeOrSubscription(req, res, next) {
|
||
|
|
// Free tier is always allowed
|
||
|
|
if (req.user && req.user.tier === 'free') {
|
||
|
|
return next();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Otherwise, require active subscription
|
||
|
|
return requireActiveSubscription(req, res, next);
|
||
|
|
}
|
||
|
|
|
||
|
|
export default {
|
||
|
|
requireActiveSubscription,
|
||
|
|
attachSubscription,
|
||
|
|
requireFreeOrSubscription
|
||
|
|
};
|