fixed login payload and token structure for auth
This commit is contained in:
parent
a3ecace384
commit
4ebc73031e
|
|
@ -1,9 +1,10 @@
|
||||||
import { sendResponseAccessDenied } from '../utils/responses.js';
|
import { sendResponseAccessDenied } from '../utils/responses.js';
|
||||||
import { checkPermission, getDataFromToken, generateAccessToken} from '../services/authService.js';
|
import { checkPermission, getDataFromToken, generateAccessToken} from '../services/authService.js';
|
||||||
import { getRolesHasPermissionsModel } from '../models/authorization/roles_has_permissionsModel.js';
|
import { getRolesHasPermissionsModel } from '../models/authorization/roles_has_permissionsModel.js';
|
||||||
import mysql from '../adapters/mysql.js';
|
|
||||||
import { error404, errorHandler } from '../utils/errors.js';
|
import { error404, errorHandler } from '../utils/errors.js';
|
||||||
import { noResults } from '../validators/result-validators.js';
|
import { noResults } from '../validators/result-validators.js';
|
||||||
|
import mysql from '../adapters/mysql.js';
|
||||||
|
import { sendResponseNotFound } from '../utils/responses.js';
|
||||||
|
|
||||||
const obtainToken = (req, res) => {
|
const obtainToken = (req, res) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
@ -11,18 +12,15 @@ const obtainToken = (req, res) => {
|
||||||
if (token) {
|
if (token) {
|
||||||
resolve(token);
|
resolve(token);
|
||||||
} else {
|
} else {
|
||||||
sendResponseAccessDenied(res, { message: 'No authorization provided. Access token required' });
|
return sendResponseAccessDenied(res, { message: 'No authorization provided. Access token required' })
|
||||||
reject(new Error('No authorization provided'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setToken = (result, req, res, next, config) => {
|
const setToken = (result, req, res, next, config) => {
|
||||||
const { user, role } = result._data
|
const { uuid, role } = result._data
|
||||||
const token = generateAccessToken({
|
const payload = {role, user: uuid}
|
||||||
payload: { user, role },
|
const token = generateAccessToken(payload)
|
||||||
config
|
|
||||||
})
|
|
||||||
next({ user: { ...result, token } })
|
next({ user: { ...result, token } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -34,8 +32,7 @@ const authenticateToken = (req, res, next) => {
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error in authentication middleware:', error);
|
return sendResponseAccessDenied(res, error);
|
||||||
sendResponseAccessDenied(res, { message: 'Access denied. Invalid token.' });
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -44,31 +41,27 @@ const authorizePermission = (endpoint) => {
|
||||||
obtainToken(req, res)
|
obtainToken(req, res)
|
||||||
.then((token) => getDataFromToken(token)) //extract user data from the token
|
.then((token) => getDataFromToken(token)) //extract user data from the token
|
||||||
.then((decoded) => {
|
.then((decoded) => {
|
||||||
const roleName = decoded.payload.role
|
const roleName = decoded.role
|
||||||
_getRolePermissionsByName(roleName, config)
|
_getRolePermissionsByName(roleName, config)
|
||||||
.then((rolePermissions) => {
|
.then((rolePermissions) => {
|
||||||
const action = req.method
|
const action = req.method
|
||||||
//check if the user has the necessary permissions
|
//check if the user has the necessary permissions
|
||||||
return checkPermission(action, endpoint, rolePermissions)
|
return checkPermission(action, endpoint, rolePermissions, config)
|
||||||
.then(({ hasPermission }) => {
|
.then(({ hasPermission }) => {
|
||||||
if (!hasPermission) {
|
if (!hasPermission) {
|
||||||
sendResponseAccessDenied(res, {
|
return sendResponseAccessDenied(res, {
|
||||||
message: `You don't have permission to ${action} on ${endpoint}`
|
message: `Access denied. User does not have permission`
|
||||||
});
|
});
|
||||||
throw new Error(`Permission denied for ${action} on ${endpoint}`);
|
|
||||||
}
|
}
|
||||||
|
req.auth.user = decoded.user
|
||||||
//attach user and role to the request object
|
req.auth.role = roleName;
|
||||||
//req.auth.user = user;
|
|
||||||
//req.auth.role = role;
|
|
||||||
|
|
||||||
next();
|
next();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error('Error in authorization middleware:', error);
|
return sendResponseAccessDenied(res, error);
|
||||||
sendResponseAccessDenied(res, { message: 'Authorization error', error: error.message });
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -82,15 +75,13 @@ const _getRolePermissionsByName = (roleName, config) => {
|
||||||
const error = errorHandler(err, config.environment)
|
const error = errorHandler(err, config.environment)
|
||||||
return sendResponseNotFound(res, error)
|
return sendResponseNotFound(res, error)
|
||||||
}
|
}
|
||||||
console.log(response)
|
|
||||||
return response.map(({ permission_action, permission_endpoint }) => ({
|
return response.map(({ permission_action, permission_endpoint }) => ({
|
||||||
permission_action,
|
permission_action,
|
||||||
permission_endpoint
|
permission_endpoint
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
const error = errorHandler(err, config.environment)
|
errorHandler(err, config.environment)
|
||||||
res.status(error.code).json(error)
|
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
mysql.end(conn)
|
mysql.end(conn)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
|
import mysql from '../adapters/mysql.js';
|
||||||
|
import { errorHandler } from '../utils/errors.js';
|
||||||
|
import { getEndpointsModel } from '../models/authorization/endpointsModel.js';
|
||||||
|
import { noResults } from '../validators/result-validators.js';
|
||||||
|
import { error404, error403 } from '../utils/errors.js';
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
|
|
@ -25,7 +30,6 @@ const getDataFromToken = (token) => {
|
||||||
const generateAccessToken = (payload) => {
|
const generateAccessToken = (payload) => {
|
||||||
const JWT_SECRET = process.env.JWT_SECRET;
|
const JWT_SECRET = process.env.JWT_SECRET;
|
||||||
const JWT_TIME = parseInt(process.env.JWT_TIME, 10);
|
const JWT_TIME = parseInt(process.env.JWT_TIME, 10);
|
||||||
|
|
||||||
return jwt.sign(payload, JWT_SECRET, JWT_TIME ? { expiresIn: JWT_TIME } : {});
|
return jwt.sign(payload, JWT_SECRET, JWT_TIME ? { expiresIn: JWT_TIME } : {});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -37,21 +41,45 @@ const generateAccessToken = (payload) => {
|
||||||
* @param {Array} userPermissions - The list of permissions assigned to the user.
|
* @param {Array} userPermissions - The list of permissions assigned to the user.
|
||||||
* @returns {Promise<Object>} - Resolves with an object containing permission details.
|
* @returns {Promise<Object>} - Resolves with an object containing permission details.
|
||||||
*/
|
*/
|
||||||
const checkPermission = (action, endpoint, userPermissions) => {
|
const checkPermission = (action, endpoint, userPermissions, config) => {
|
||||||
return new Promise((resolve, reject) => {
|
return _getEndpointByRoute(endpoint, config)
|
||||||
const hasPermission = userPermissions.some(
|
.then((endpointInfo) => {
|
||||||
(permission) =>
|
const hasPermission = userPermissions.some(
|
||||||
permission.permission_action === action && permission.permission_endpoint === endpoint
|
(permission) =>
|
||||||
);
|
permission.permission_action === action &&
|
||||||
|
permission.permission_endpoint === endpointInfo.id // Comparar con el ID del endpoint
|
||||||
|
);
|
||||||
|
|
||||||
if (hasPermission) {
|
if (hasPermission) {
|
||||||
resolve({ hasPermission: true });
|
return { hasPermission: true };
|
||||||
} else {
|
}
|
||||||
reject(new Error(`Permission denied for ${action} on ${endpoint}`));
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getDataFromToken,
|
getDataFromToken,
|
||||||
generateAccessToken,
|
generateAccessToken,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue