This commit is contained in:
jackiettran
2025-10-30 15:38:57 -04:00
parent d1cb857aa7
commit ee3a6fd8e1
13 changed files with 1400 additions and 12 deletions

View 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 };

View File

@@ -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