94 lines
2.1 KiB
JavaScript
94 lines
2.1 KiB
JavaScript
/**
|
|
* Copyright (c) 2026 Niolla
|
|
* All rights reserved.
|
|
*
|
|
* This source code is proprietary and confidential.
|
|
* Unauthorized copying, modification, distribution, or use
|
|
* of this file, via any medium, is strictly prohibited.
|
|
*/
|
|
|
|
// app/middleware/auth.middleware.js
|
|
|
|
const { verifyToken } = require("../utils/jwt.util");
|
|
const { getEffectivePermissions } = require("../services/permission.service");
|
|
|
|
const authenticate = async (req, res, next) => {
|
|
try {
|
|
let token = null;
|
|
|
|
// Get token from cookie
|
|
if (req.cookies?.access_token) {
|
|
token = req.cookies.access_token;
|
|
}
|
|
|
|
// Fallback to Bearer token
|
|
if (!token && req.headers.authorization?.startsWith("Bearer ")) {
|
|
token = req.headers.authorization.split(" ")[1];
|
|
}
|
|
|
|
if (!token) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: "Unauthorized",
|
|
});
|
|
}
|
|
|
|
// Verify token
|
|
const decoded = verifyToken(token);
|
|
|
|
if (process.env.NODE_ENV === "development") {
|
|
console.log("DECODED:", decoded);
|
|
}
|
|
|
|
const userId = decoded.sub || decoded.id;
|
|
|
|
if (!userId) {
|
|
throw new Error("User ID missing in token");
|
|
}
|
|
|
|
// Load permissions
|
|
const permissions = await getEffectivePermissions(userId);
|
|
|
|
req.user = {
|
|
...decoded,
|
|
id: userId,
|
|
permissions,
|
|
};
|
|
|
|
next();
|
|
} catch (err) {
|
|
console.error("AUTH ERROR:", err);
|
|
|
|
// Clear invalid/expired cookie
|
|
res.clearCookie("access_token", {
|
|
httpOnly: true,
|
|
secure: process.env.NODE_ENV === "production",
|
|
sameSite: process.env.NODE_ENV === "production" ? "None" : "Lax",
|
|
});
|
|
|
|
// Token expired
|
|
if (err.name === "TokenExpiredError") {
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: "Session expired. Please login again.",
|
|
});
|
|
}
|
|
|
|
// Invalid token
|
|
if (err.name === "JsonWebTokenError") {
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: "Invalid token",
|
|
});
|
|
}
|
|
|
|
// Default
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: "Authentication failed",
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = { authenticate };
|