166 lines
3.9 KiB
JavaScript
166 lines
3.9 KiB
JavaScript
/**
|
|
* Utilitaires d'authentification et d'autorisation
|
|
*/
|
|
const admin = require("firebase-admin");
|
|
const logger = require("firebase-functions/logger");
|
|
|
|
/**
|
|
* Vérifie le token Firebase et retourne l'utilisateur
|
|
*/
|
|
async function authenticateUser(req) {
|
|
if (!req.headers.authorization || !req.headers.authorization.startsWith("Bearer ")) {
|
|
throw new Error("Unauthorized: No token provided");
|
|
}
|
|
|
|
const idToken = req.headers.authorization.split("Bearer ")[1];
|
|
try {
|
|
const decodedToken = await admin.auth().verifyIdToken(idToken);
|
|
return decodedToken;
|
|
} catch (e) {
|
|
logger.error("Error verifying Firebase ID token:", e);
|
|
throw new Error("Unauthorized: Invalid token");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Récupère les données utilisateur depuis Firestore
|
|
*/
|
|
async function getUserData(uid) {
|
|
const userDoc = await admin.firestore().collection("users").doc(uid).get();
|
|
if (!userDoc.exists) {
|
|
return null;
|
|
}
|
|
return {uid, ...userDoc.data()};
|
|
}
|
|
|
|
/**
|
|
* Récupère les permissions d'un rôle
|
|
*/
|
|
async function getRolePermissions(roleRef) {
|
|
if (!roleRef) return [];
|
|
|
|
let roleId;
|
|
if (typeof roleRef === "string") {
|
|
roleId = roleRef;
|
|
} else if (roleRef.id) {
|
|
roleId = roleRef.id;
|
|
} else {
|
|
return [];
|
|
}
|
|
|
|
const roleDoc = await admin.firestore().collection("roles").doc(roleId).get();
|
|
if (!roleDoc.exists) return [];
|
|
|
|
return roleDoc.data().permissions || [];
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur a une permission spécifique
|
|
*/
|
|
async function hasPermission(uid, requiredPermission) {
|
|
const userData = await getUserData(uid);
|
|
if (!userData) return false;
|
|
|
|
const permissions = await getRolePermissions(userData.role);
|
|
return permissions.includes(requiredPermission);
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur est admin
|
|
*/
|
|
async function isAdmin(uid) {
|
|
const userData = await getUserData(uid);
|
|
if (!userData) return false;
|
|
|
|
let roleId;
|
|
const roleField = userData.role;
|
|
if (typeof roleField === "string") {
|
|
roleId = roleField;
|
|
} else if (roleField && roleField.id) {
|
|
roleId = roleField.id;
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
return roleId === "ADMIN";
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur est assigné à un événement
|
|
*/
|
|
async function isAssignedToEvent(uid, eventId) {
|
|
const eventDoc = await admin.firestore().collection("events").doc(eventId).get();
|
|
if (!eventDoc.exists) return false;
|
|
|
|
const eventData = eventDoc.data();
|
|
const workforce = eventData.workforce || [];
|
|
|
|
// workforce contient des références DocumentReference
|
|
return workforce.some((ref) => {
|
|
if (typeof ref === "string") return ref === uid;
|
|
if (ref && ref.id) return ref.id === uid;
|
|
return false;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Middleware d'authentification pour les Cloud Functions HTTP
|
|
*/
|
|
async function authMiddleware(req, res, next) {
|
|
try {
|
|
const decodedToken = await authenticateUser(req);
|
|
req.user = decodedToken;
|
|
req.uid = decodedToken.uid;
|
|
next();
|
|
} catch (error) {
|
|
res.status(401).json({error: error.message});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Middleware de vérification de permission
|
|
*/
|
|
function requirePermission(permission) {
|
|
return async (req, res, next) => {
|
|
try {
|
|
const hasAccess = await hasPermission(req.uid, permission);
|
|
if (!hasAccess) {
|
|
res.status(403).json({error: `Forbidden: Requires permission '${permission}'`});
|
|
return;
|
|
}
|
|
next();
|
|
} catch (error) {
|
|
res.status(403).json({error: error.message});
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Middleware admin uniquement
|
|
*/
|
|
async function requireAdmin(req, res, next) {
|
|
try {
|
|
const adminAccess = await isAdmin(req.uid);
|
|
if (!adminAccess) {
|
|
res.status(403).json({error: "Forbidden: Admin access required"});
|
|
return;
|
|
}
|
|
next();
|
|
} catch (error) {
|
|
res.status(403).json({error: error.message});
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
authenticateUser,
|
|
getUserData,
|
|
getRolePermissions,
|
|
hasPermission,
|
|
isAdmin,
|
|
isAssignedToEvent,
|
|
authMiddleware,
|
|
requirePermission,
|
|
requireAdmin,
|
|
};
|
|
|