343 lines
10 KiB
JavaScript
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
|
|
} |