small fix to not allow refresh and access to be treated as the same for auth validation

This commit is contained in:
Pau 2025-05-14 19:21:04 +02:00
parent e87422e22d
commit 69b111d995
3 changed files with 24 additions and 28 deletions

View File

@ -5,6 +5,7 @@ import { error404, errorHandler } from '../utils/errors.js';
import { noResults } from '../validators/result-validators.js';
import mysql from '../adapters/mysql.js';
const obtainToken = (req, res) => {
return new Promise((resolve, reject) => {
const token = req.header('Authorization')?.replace('Bearer ', '');
@ -23,7 +24,7 @@ const setToken = (result, req, res, next, config) => {
next({ user: { ...result, accessToken, refreshToken} })
}
const authenticateToken = (req, res, next) => {
const authenticateToken = (req, res, next, config) => {
obtainToken(req, res)
.then((token) => getDataFromToken(token))
.then((decoded) => {
@ -31,21 +32,25 @@ const authenticateToken = (req, res, next) => {
next();
})
.catch((error) => {
return sendResponseUnauthorized(res, error);
const err = errorHandler(error, config.environment)
res.status(err.code).json(err)
});
};
const refreshAuthenticate = (req, res, next) => {
const token = req.body.refreshToken
getDataFromToken(token)
getDataFromToken(token, 'refresh')
.then((decoded) => {
req.auth = decoded;
next();
})
.catch((error) => {
if (error.code === 'TOKEN_TYPE_MISMATCH') {
return sendResponseForbidden(res, error); // 403 Forbidden
}
return sendResponseUnauthorized(res, error);
});
}
}
const authorizePermission = (endpoint) => {
return (req, res, next, config) => {
@ -53,7 +58,7 @@ const authorizePermission = (endpoint) => {
.then((token) => getDataFromToken(token)) //extract user data from the token
.then((decoded) => {
const roleName = decoded.role
_getRolePermissionsByName(roleName, config)
_getRolePermissionsByName(res, roleName, config)
.then((rolePermissions) => {
const action = req.method
//check if the user has the necessary permissions
@ -77,22 +82,17 @@ const authorizePermission = (endpoint) => {
};
};
const _getRolePermissionsByName = (roleName, config) => {
const _getRolePermissionsByName = (res, roleName, config) => {
const conn = mysql.start(config)
return getRolesHasPermissionsModel({ roleName, conn })
.then((response) => {
if (noResults(response)) {
const err = error404()
const error = errorHandler(err, config.environment)
return sendResponseNotFound(response, error)
}
return response.map(({ permission_action, permission_endpoint }) => ({
permission_action,
permission_endpoint
}))
})
.catch((err) => {
errorHandler(err, config.environment)
.catch((err) =>{
throw err
})
.finally(() => {
mysql.end(conn)

View File

@ -1723,7 +1723,7 @@ export default(config) => {
varChar('username'),
varChar('password'),
varChar('email').optional({ nullable: true, values: 'falsy' }),
varChar('fk_role')
varChar('fk_role').optional({nullable: false, values: 'falsy'})
],
(req, res, next) => payloadExpressValidator(req, res, next, config),
(req, res, next) => postRegisterController(req, res, next, config),

View File

@ -13,11 +13,19 @@ dotenv.config();
* @param {string} token - The JWT token to verify.
* @returns {Promise<Object>} - Resolves with the decoded token payload.
*/
const getDataFromToken = (token) => {
const getDataFromToken = (token, expectedType = 'access') => {
return new Promise((resolve, reject) => {
const JWT_SECRET = process.env.JWT_SECRET;
jwt.verify(token, JWT_SECRET, (err, decoded) => {
err ? reject(err) : resolve(decoded);
if (err) {
reject(err);
} else if (decoded.type !== expectedType) {
const err = error403()
const error = errorHandler(err)
reject(error);
} else {
resolve(decoded);
}
});
});
};
@ -70,26 +78,14 @@ const checkPermission = (action, endpoint, userPermissions, config) => {
}
return { hasPermission: false };
})
.catch((error) => {
const err = error403()
return errorHandler(err, config.environment,`Authorization failed: ${error.message}`);
});
};
const _getEndpointByRoute = (route, config) => {
const conn = mysql.start(config)
return getEndpointsModel({ route, conn })
.then((endpointInformation) => {
if (noResults(endpointInformation)) {
const err = error404()
errorHandler(err, config.environment)
}
return endpointInformation[0]
})
.catch((err) => {
errorHandler(err, config.environment)
})
.finally(() => {
mysql.end(conn)
})