This repository has been archived on 2024-04-19. You can view files and clone it, but cannot push or open issues or pull requests.
brief-04-back/controllers/AuthController.js
2024-04-17 16:55:04 +02:00

343 lines
10 KiB
JavaScript

const {
RegisterService,
LoginService,
getAllUsersService,
getUserFromIdService,
editUserService,
deleteUserService
} = require("../services/UserService");
const {JwtVerify} = require("../services/JwtService");
const { Logger } = require('tslog');
const logger = new Logger({ name: "Auth Controller" });
/**
* Registers a user.
*
* @async
* @param {Object} req - The request object.
* @param {Object} res - The response object.
* @return {Object} The response object containing the result of the registration.
* If successful, it will contain the registered user's data.
* If there is an error, it will contain an error name and message.
*/
async function registerUser(req, res) {
const body = req.body;
if (!body) {
logger.warn(`Invalid input data (${req.ip})`);
return res
.type('application/json')
.status(400)
.json({ error: 'Invalid input data' });
}
if (!body.password || !body.username || !body.firstName || !body.lastName || !body.displayName) {
logger.warn(`Field(s) missing (${req.ip})`);
return res
.type('application/json')
.status(400)
.json({ error: 'Field(s) missing' });
}
// sanitize data
let gdpr = false
if (body.gdpr === true) {gdpr = true}
const sanitizeData= {
username: `${body.username}`,
displayName: `${body.displayName}`,
gdpr: gdpr,
password: `${body.password}`,
firstName: `${body.firstName}`,
lastName: `${body.lastName}`,
};
/**
* Represents the result of the registration service.
*
* @typedef {Object} RegisterServiceResult
* @property {Promise} promise - The promise that resolves when the service registration is complete.
*/
const RegisterServiceResult = await RegisterService(sanitizeData)
if (RegisterServiceResult.error === "gdprNotApproved") {
logger.warn(`GDPR not approved (${req.ip})`);
return res
.status(400)
.json({
error: RegisterServiceResult.error,
message: "GDPR not accepted."
});
}
if (RegisterServiceResult.error === "exist") {
logger.warn(`The user already exists (${req.ip})`);
return res
.type('application/json')
.status(400)
.json({
error: RegisterServiceResult.error,
message: "The user already exists."
});
}
// SUCCESS
logger.info(`User registered successfully (${req.ip})`);
return res
.type('application/json')
.status(201)
.json(RegisterServiceResult);
}
/**
* Logs in a user with the provided username and password.
*
* @param {Object} req - The request object containing the body data.
* @param {Object} res - The response object to send the result.
* @returns {Promise<void>} - A promise that resolves once the login process is complete.
*/
async function loginUser(req, res) {
const body = req.body;
if (!body) {
return res
.type('application/json')
.status(400)
.json({ error: 'Invalid input data' });
}
if (!body.password || !body.username) {
logger.warn(`Field(s) missing (${req.ip})`);
return res
.type('application/json')
.status(400)
.json({ error: 'Field(s) missing' });
}
const loginData = {
username: `${body.username}`,
password: `${body.password}`
};
console.log(body)
const LoginServiceResult = await LoginService(loginData);
console.log(LoginServiceResult)
if (LoginServiceResult.error === "userNotFound") {
console.log('POOL')
return res
.type('application/json')
.status(404)
.json({
error: LoginServiceResult.error,
message: "User not found."
});
}
if (LoginServiceResult.error === "invalidPassword") {
return res
.type('application/json')
.status(401)
.json({
error: LoginServiceResult.error,
message: "Invalid password."
});
}
return res
.type('application/json')
.status(200)
.json(LoginServiceResult);
}
//TODO - To test
async function getAllUsers(req, res) {
const authHeader = req.headers.authorization;
const bearerToken = authHeader.split(' ')[1];
const payload = await JwtVerify(bearerToken);
const sourceUser = await getUserFromIdService(payload.sub)
if (!sourceUser) {
return res
.type('application/json')
.status(404)
.json({ error: 'You dont exist anymore' });
}
if (!sourceUser.isAdmin) {
return res
.type('application/json')
.status(403)
.json({ error: 'Unauthorized' });
}
const AllUserResponse = await getAllUsersService()
if (!AllUserResponse.users) {
return res
.type('application/json')
.status(500)
.json({ error: 'Internal server error' });
}
return res
.type('application/json')
.status(200)
.json(AllUserResponse);
}
//TODO - To test
/**
* Get user from the database based on the provided user ID and return it as a response.
*
* @async
* @param {object} req - The request object containing the user ID as a parameter.
* @param {object} res - The response object to be used for sending the user data or error.
* @return {Promise<void>} - A Promise that resolves when the user data is sent to the client or an error occurred.
*/
async function getUser(req, res) {
const userId = req.params.userId;
const dbUser = await getUserFromIdService(userId);
if (!dbUser) {
logger.warn(`User not found (${req.ip})`);
return res
.type('application/json')
.status(404)
.json({ error: 'User not found' });
}
return res
.type('application/json')
.status(200)
.json(dbUser);
}
//TODO - To test
async function editUser(req, res) {
const body = req.body;
if (!body) {
return res
.type('application/json')
.status(400)
.json({ error: 'Field(s) missing' });
}
const authHeader = req.headers.authorization;
const bearerToken = authHeader.split(' ')[1];
const payload = await JwtVerify(bearerToken);
const sourceUser = await getUserFromIdService(payload.sub)
/**
* Represents the user ID that is the target for a specific operation.
*
* @type {string|number}
*/
const targetUserId = body.targetId | payload.sub
if (!sourceUser) {
logger.warn(`Unauthorized access attempt (${req.ip})`);
return res
.type('application/json')
.status(404)
.json({ error: 'You dont exist anymore' });
}
if (sourceUser.isAdmin || sourceUser.id === payload.sub) {
if (sourceUser.isAdmin) {
logger.info(`EDIT :> Source user is an admin (${sourceUser.displayName})`)
} else {
logger.info(`EDIT :> Source user modify itself (${sourceUser.displayName})`)
}
// biome-ignore lint/style/useConst: <explanation>
let modifiedData= {}
if (body.firstName) modifiedData.firstName = `${body.firstName}`;
if (body.lastName) modifiedData.lastName = `${body.lastName}`;
if (body.displayName) modifiedData.displayName = `${body.displayName}`;
if (body.password) modifiedData.password = `${body.password}`;
//Call service
const EditUserServiceResult = await editUserService(`${targetUserId}`, modifiedData);
if (EditUserServiceResult.error === 'userNotFound') {
logger.warn(`User not found (${req.ip})`);
return res
.type('application/json')
.status(404)
.json({ error: 'User not found' });
}
if (EditUserServiceResult.error !== 'none') {
logger.error(`Error occurred during user edit (${req.ip})`);
return res
.type('application/json')
.status(500)
.json({ error: 'Internal server error' });
}
return res
.type('application/json')
.status(200)
.json(EditUserServiceResult);
}
//Not itself or
logger.warn(`Unauthorized access attempt, not self or admin (${req.ip})`);
return res
.type('application/json')
.status(403)
.json({ error: 'Unauthorized' });
}
//TODO - To test
async function deleteUser(req, res) {
const body = req.body;
const authHeader = req.headers.authorization;
const bearerToken = authHeader.split(' ')[1];
const payload = await JwtVerify(bearerToken);
const sourceUser = await getUserFromIdService(payload.sub)
const targetUserId = body.targetId | payload.sub
if (!sourceUser) {
logger.warn(`Unauthorized access attempt (${req.ip})`);
return res
.type('application/json')
.status(404)
.json({ error: 'You dont exist anymore' });
}
if (sourceUser.isAdmin || sourceUser.id === payload.sub) {
const deleteUserServiceResult = await deleteUserService(`${targetUserId}`);
if (!deleteUserServiceResult) {
logger.error(`Error occurred during user delete (${req.ip})`);
return res
.type('application/json')
.status(500)
.json({ error: 'Internal server error' });
}
return res
.type('application/json')
.status(200)
.json({ message: 'User deleted successfully' });
}
}
/**
* Retrieves the user's information.
*
* @param {object} req - The incoming request object.
* @param {object} res - The outgoing response object.
*/
async function getSelf(req, res) {
const authHeader = req.headers.authorization;
const bearerToken = authHeader.split(' ')[1];
const payload = await JwtVerify(bearerToken);
console.log(payload)
const dbUser = await getUserFromIdService(payload.sub)
if (!dbUser) {
return res
.type('application/json')
.status(404)
.json({ error: 'User not found' });
}
return res
.type('application/json')
.status(200)
.json({
username: dbUser.username,
displayName: dbUser.displayName,
firstName: dbUser.firstName,
lastName: dbUser.lastName
});
}
module.exports = {
registerUser,
loginUser,
getAllUsers,
getUser,
editUser,
deleteUser,
getSelf
}