alpha
This commit is contained in:
59
backend/middleware/alphaAccess.js
Normal file
59
backend/middleware/alphaAccess.js
Normal file
@@ -0,0 +1,59 @@
|
||||
const { AlphaInvitation } = require("../models");
|
||||
const logger = require("../utils/logger");
|
||||
|
||||
/**
|
||||
* Middleware to require alpha access for protected routes
|
||||
* Checks for valid alpha cookie or registered user with invitation
|
||||
*/
|
||||
const requireAlphaAccess = async (req, res, next) => {
|
||||
try {
|
||||
let hasAccess = false;
|
||||
|
||||
// Check 1: Valid alpha access cookie
|
||||
if (req.cookies && req.cookies.alphaAccessCode) {
|
||||
const { code } = req.cookies.alphaAccessCode;
|
||||
if (code) {
|
||||
const invitation = await AlphaInvitation.findOne({
|
||||
where: { code, status: ["pending", "active"] },
|
||||
});
|
||||
if (invitation) {
|
||||
hasAccess = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check 2: Authenticated user who has used an invitation
|
||||
if (!hasAccess && req.user && req.user.id) {
|
||||
const invitation = await AlphaInvitation.findOne({
|
||||
where: { usedBy: req.user.id },
|
||||
});
|
||||
if (invitation) {
|
||||
hasAccess = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasAccess) {
|
||||
logger.warn(
|
||||
`Alpha access denied for request to ${req.path}`,
|
||||
{
|
||||
ip: req.ip,
|
||||
userId: req.user?.id,
|
||||
}
|
||||
);
|
||||
return res.status(403).json({
|
||||
error: "Alpha access required",
|
||||
code: "ALPHA_ACCESS_REQUIRED",
|
||||
});
|
||||
}
|
||||
|
||||
// Access granted
|
||||
next();
|
||||
} catch (error) {
|
||||
logger.error(`Error checking alpha access: ${error.message}`, { error });
|
||||
res.status(500).json({
|
||||
error: "Server error",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { requireAlphaAccess };
|
||||
@@ -143,6 +143,18 @@ const authRateLimiters = {
|
||||
legacyHeaders: false,
|
||||
}),
|
||||
|
||||
// Alpha code validation rate limiter
|
||||
alphaCodeValidation: rateLimit({
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 5, // 5 code validation attempts per 15 minutes
|
||||
message: {
|
||||
error: "Too many attempts. Please try again later.",
|
||||
retryAfter: 900,
|
||||
},
|
||||
standardHeaders: true,
|
||||
legacyHeaders: false,
|
||||
}),
|
||||
|
||||
// General API rate limiter
|
||||
general: rateLimit({
|
||||
windowMs: 60 * 1000, // 1 minute
|
||||
@@ -166,6 +178,7 @@ module.exports = {
|
||||
loginLimiter: authRateLimiters.login,
|
||||
registerLimiter: authRateLimiters.register,
|
||||
passwordResetLimiter: authRateLimiters.passwordReset,
|
||||
alphaCodeValidationLimiter: authRateLimiters.alphaCodeValidation,
|
||||
generalLimiter: authRateLimiters.general,
|
||||
|
||||
// Burst protection
|
||||
|
||||
Reference in New Issue
Block a user