initialize git, basic setup for crm

This commit is contained in:
richardtekula
2025-11-18 13:53:28 +01:00
commit da01d586fc
47 changed files with 12776 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
import { verifyAccessToken } from '../../utils/jwt.js';
import { AuthenticationError } from '../../utils/errors.js';
import { getUserById } from '../../services/auth.service.js';
/**
* Middleware na overenie JWT tokenu
* Pridá user objekt do req.user ak je token validný
*/
export const authenticate = async (req, res, next) => {
try {
// Získaj token z Authorization header alebo cookies
let token = null;
// Skús Authorization header (Bearer token)
const authHeader = req.headers.authorization;
if (authHeader && authHeader.startsWith('Bearer ')) {
token = authHeader.substring(7);
}
// Ak nie je v header, skús cookies
if (!token && req.cookies && req.cookies.accessToken) {
token = req.cookies.accessToken;
}
if (!token) {
throw new AuthenticationError('Token nie je poskytnutý');
}
// Overenie tokenu
const decoded = verifyAccessToken(token);
// Načítaj aktuálne user data z DB
const user = await getUserById(decoded.id);
// Pridaj user do requestu
req.user = user;
req.userId = user.id;
next();
} catch (error) {
if (error instanceof AuthenticationError) {
return res.status(401).json({
success: false,
error: {
message: error.message,
statusCode: 401,
},
});
}
return res.status(401).json({
success: false,
error: {
message: 'Neplatný alebo expirovaný token',
statusCode: 401,
},
});
}
};
/**
* Optional authentication - nepovinnné overenie
* Ak je token poskytnutý, overí ho, ale nehodí error ak nie je
*/
export const optionalAuthenticate = async (req, res, next) => {
try {
let token = null;
const authHeader = req.headers.authorization;
if (authHeader && authHeader.startsWith('Bearer ')) {
token = authHeader.substring(7);
}
if (!token && req.cookies && req.cookies.accessToken) {
token = req.cookies.accessToken;
}
if (token) {
const decoded = verifyAccessToken(token);
const user = await getUserById(decoded.id);
req.user = user;
req.userId = user.id;
}
next();
} catch (error) {
// Ignoruj chyby, len pokračuj bez user objektu
next();
}
};

View File

@@ -0,0 +1,88 @@
import { ForbiddenError } from '../../utils/errors.js';
/**
* Middleware na overenie role používateľa
* Musí byť použité PO authenticate middleware
* @param {...string} allowedRoles - Povolené role (napr. 'admin', 'member')
*/
export const requireRole = (...allowedRoles) => {
return (req, res, next) => {
// Skontroluj či je user autentifikovaný
if (!req.user) {
return res.status(401).json({
success: false,
error: {
message: 'Musíte byť prihlásený',
statusCode: 401,
},
});
}
// Skontroluj či user má jednu z povolených rolí
if (!allowedRoles.includes(req.user.role)) {
return res.status(403).json({
success: false,
error: {
message: 'Nemáte oprávnenie na túto operáciu',
statusCode: 403,
},
});
}
next();
};
};
/**
* Middleware špecificky pre admin rolu
*/
export const requireAdmin = requireRole('admin');
/**
* Middleware pre kontrolu či user môže upravovať resource
* Buď je to admin, alebo je to vlastník resource
* @param {function} getResourceUserId - Funkcia ktorá vráti userId vlastníka resource
*/
export const requireOwnerOrAdmin = (getResourceUserId) => {
return async (req, res, next) => {
if (!req.user) {
return res.status(401).json({
success: false,
error: {
message: 'Musíte byť prihlásený',
statusCode: 401,
},
});
}
// Admin môže všetko
if (req.user.role === 'admin') {
return next();
}
// Inak skontroluj ownership
try {
const resourceUserId = await getResourceUserId(req);
if (req.user.id !== resourceUserId) {
return res.status(403).json({
success: false,
error: {
message: 'Nemáte oprávnenie na túto operáciu',
statusCode: 403,
},
});
}
next();
} catch (error) {
return res.status(500).json({
success: false,
error: {
message: 'Chyba pri overovaní oprávnenia',
statusCode: 500,
},
});
}
};
};