reconstruire UC inceput

This commit is contained in:
andrei-mihnea-cerbu
2024-04-03 04:07:20 +03:00
parent af8c295d75
commit 5e4a488bfd
36 changed files with 264 additions and 943 deletions
+45
View File
@@ -0,0 +1,45 @@
General Overview
-
The UC serves as the main logistic station for all the client/CEO applications which are used
inside the corporation. This UC stores
- credentials for the users and ceo;
- registered departments, as well security levels and the encrypting/decrypting keys for the files;
- backup schemes for each user, as well as the IP, as well as the IPs where each computer is located;
The main endpoints of the application are:
- <b>Users</b>:
- Can register/login in the system;
- Update the information (username, email, password);
- Change the working department (the client app will prompt the CEO password request to proceed);
- Retrieve the full list of departments for the sign-up / 'change department' procedure;
- Retrieve the full list of users and their IPs for sharing a file
- <b>CEO</b>:
- Can log in the system;
- Can change the email (the password can only be retrieved by the admin);
- Delete users from the system;
- Create / Delete departments, as well as managing the security levels of each department;
- Retrieve the full list of users and their IPs for sharing a file
- <b>Admin</b>:
- Reset the server to default state;
- Retrieve the CEO login information, as well as a list of all users in the system;
- <b>Backup Schemes</b>:
- At a request, will get the ID of a user, their IP and the backup directory structure to place it in the scheme,
as well as the data size of the backup
Other Features
-
The UC will also create a separate process which at a set interval of time will retrieve from the admin config, as
well as from the CEO config, the ID so that it will be used to authenticate the users at their endpoints.
+5 -8
View File
@@ -8,23 +8,21 @@ const port = process.env.PORT || 5000;
app.use(cors());
app.use(json());
app.locals.apiKey = 'uc_api'
const checkJson = require('./middlewares/checkJson');
const apiKeyValidation = require('./middlewares/apiKeyValidation');
const setAdminValues = require('./middlewares/setAdminValues');
app.use(apiKeyValidation)
app.use(checkJson)
app.use(setAdminValues);
const usersRouter = require('./routes/users');
const departmentsRouter = require('./routes/departments');
const adminRouter = require('./routes/admin');
const ceoRouter = require('./routes/ceo');
const backupSchemesRouter = require('./routes/backup_schemes');
app.use('/users', usersRouter);
app.use('/departments', departmentsRouter);
app.use('/admin', adminRouter);
app.use('/ceo', ceoRouter);
app.use('/backup_schemes', backupSchemesRouter);
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
@@ -32,8 +30,7 @@ app.listen(port, () => {
// Graceful shutdown function
function gracefulShutdown() {
console.log('\nGracefully shutting down from SIGINT (Ctrl-C)');
console.log('\nShutting down!');
process.exit(0);
}
-1
View File
@@ -1 +0,0 @@
{}
-4
View File
@@ -1,4 +0,0 @@
{
"adminKey": "9ded8e96a7a03fb7ce23a19b4f6a3d08ac42926aa96664af941e4d02e0b93f0d",
"ceoID": "a7635c7a-d6a0-43dc-8e24-552ab33239b8"
}
-12
View File
@@ -1,12 +0,0 @@
[
{
"id": "16183532-3090-4e24-8def-aa29f316c1c5",
"name": "Programatori",
"key": "66238d3abd92e43486a1f8526ff83646a2481b4fb669667daf81ecc71e8211e3"
},
{
"id": "897b883b-7638-452e-bed9-81e8da2ec0c3",
"name": "Contabili",
"key": "55956d2a1cad9e3952f3756ded721724f71baada95c9addbf46f72defa06d354"
}
]
-5
View File
@@ -1,5 +0,0 @@
{
"1": "f1444987-c0c2-4ce8-89e3-b21f302bff7f",
"2": "16183532-3090-4e24-8def-aa29f316c1c5",
"3": "897b883b-7638-452e-bed9-81e8da2ec0c3"
}
-16
View File
@@ -1,16 +0,0 @@
[
{
"id": "a7635c7a-d6a0-43dc-8e24-552ab33239b8",
"name": "CEO",
"email": "ceo@yourfirm.com",
"password": "405ee6885be5385223830874bd6dcfca",
"department": ""
},
{
"id": "ffc90aca-bb31-4641-9a43-30b343924e8a",
"name": "Andrei",
"email": "a@c.com",
"password": "5447045dc3cfaafdb49b365e31dad41eb88616b0b1449930e55fd3a70bd8cee4",
"department": "16183532-3090-4e24-8def-aa29f316c1c5"
}
]
@@ -1,8 +0,0 @@
class DepartmentAlreadyExistsError extends Error {
constructor(message = 'This department is already in system') {
super(message);
this.name = 'DepartmentAlreadyExistsError';
}
}
module.exports = DepartmentAlreadyExistsError
@@ -1,8 +0,0 @@
class DepartmentNotExistingError extends Error {
constructor(message = 'Department not found') {
super(message);
this.name = 'DepartmentNotExistingError';
}
}
module.exports = DepartmentNotExistingError;
@@ -1,8 +0,0 @@
class EmailAlreadyInSystemError extends Error {
constructor(message = "Email is already in system!") {
super(message);
this.name = 'EmailAlreadyInSystem';
}
}
module.exports = EmailAlreadyInSystemError
@@ -1,8 +0,0 @@
class ImproperDirStructureError extends Error {
constructor(message = 'the provided structure is not a valid JSON') {
super(message);
this.name = 'ImproperDirStructureError';
}
}
module.exports = ImproperDirStructureError
@@ -1,8 +0,0 @@
class InvalidDepartmentJsonError extends Error {
constructor(message = 'Invalid JSON format for security levels') {
super(message);
this.name = 'InvalidDepartmentJsonError';
}
}
module.exports=InvalidDepartmentJsonError;
@@ -1,8 +0,0 @@
class InvalidKeyErrorException extends Error {
constructor(message = 'Invalid key for this operation') {
super(message);
this.name = 'InvalidKeyErrorException';
}
}
module.exports=InvalidKeyErrorException;
@@ -1,8 +0,0 @@
class UserAlreadyExistsException extends Error {
constructor(message = 'User already exists in system') {
super(message);
this.name = 'UserAlreadyExistsException';
}
}
module.exports = UserAlreadyExistsException
@@ -1,8 +0,0 @@
class UserNotExistingError extends Error {
constructor(message = 'User not found in the system!') {
super(message);
this.name = 'UserNotExistingError';
}
}
module.exports = UserNotExistingError
@@ -1,26 +0,0 @@
const path = require("path");
const fs = require("fs");
function SetAdminValuesMiddleware(req, res, next){
try{
const configFilePath = path.join(__dirname, '..', 'db', 'config.json');
const config = JSON.parse(fs.readFileSync(configFilePath));
res.locals.adminKey = config.adminKey === undefined ? " " : config.adminKey;
res.locals.ceoID = config.ceoID === undefined ? " " : config.ceoID;
next();
fs.writeFileSync(configFilePath, JSON.stringify(
{
adminKey: res.locals.adminKey,
ceoID: res.locals.ceoID
}, null, 2));
return res;
} catch(error){
console.log(error.message);
return res;
}
}
module.exports = SetAdminValuesMiddleware;
+7 -140
View File
@@ -1,153 +1,20 @@
const express = require('express');
const fs = require('fs');
const crypto = require('crypto');
const {v4: uuidv4} = require("uuid");
const path = require("path");
const { sendResponse } = require('../helpers/responseHelper');
const {httpStatus, httpStatusMessages} = require('../helpers/httpResponses')
const {schemas} = require("../models/schemaMapper");
const InvalidKeyErrorException = require("../exceptions/invalidKeyErrorException");
const UserNotExistingError = require("../exceptions/userNotExistingError");
const router = express.Router();
router.get('/reset_key', (req, res) => {
const adminKey= crypto.randomBytes(32).toString('hex');
res.locals.adminKey = adminKey;
sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK], adminKey);
});
router.get('/reset', (req, res) => {
try {
const requestAdminKey = req.headers['admin-key'];
if (requestAdminKey !== res.locals.adminKey) {
throw new InvalidKeyErrorException();
}
fs.writeFileSync(path.join(__dirname, '..', 'db', 'users.json'), '[]');
fs.writeFileSync(path.join(__dirname, '..', 'db', 'departments.json'), '[]');
fs.writeFileSync(path.join(__dirname, '..', 'db', 'security_levels.json'), '{}');
fs.writeFileSync(path.join(__dirname, '..', 'db', 'backup_schemas.json'), '{}');
fs.writeFileSync(path.join(__dirname, '..', 'db', 'config.json'), JSON.stringify({
adminKey: ' ',
ceoID: ' '
}, null, 2));
const adminPassword = crypto.randomBytes(16).toString('hex'); // Generating random password
const ceoID = uuidv4();
res.locals.ceoID = ceoID;
const adminAccount = {
id: ceoID,
name: 'CEO',
email: 'ceo@yourfirm.com',
password: adminPassword
};
const usersData = [adminAccount];
fs.writeFileSync(path.join(__dirname, '..', 'db', 'users.json'),
JSON.stringify(usersData, null, 2));
sendResponse(res, httpStatus.CREATED, httpStatusMessages[httpStatus.CREATED]);
} catch (error) {
console.log(error.message);
if(error instanceof InvalidKeyErrorException){
return sendResponse(res, httpStatus.UNAUTHORIZED, error.message);
}
sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
});
const validateRegisterCeoBody = (req, res, next) => {
const { error, value } = schemas.ceoRegisterModelSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
function validateBody(req, res, next) {
next();
}
router.put('/change_admin_credentials', validateRegisterCeoBody, (req, res) => {
try {
const requestAdminKey = req.headers['admin-key'];
if (requestAdminKey !== res.locals.adminKey) {
throw new InvalidKeyErrorException();
}
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = JSON.parse(fs.readFileSync(usersFilePath, 'utf8'));
const adminIndex = usersData.findIndex(user => user.id === res.locals.ceoID);
if (adminIndex === -1) {
throw new UserNotExistingError();
}
const { name, email } = req.body; // Using req.body instead of req.jsonModel
const newPassword = crypto.randomBytes(16).toString('hex'); // Generate new random password
// Update the user data
usersData[adminIndex] = {
id: res.locals.ceoID,
name: name,
email: email,
password: newPassword
};
// Write the updated user data back to the file
fs.writeFileSync(usersFilePath, JSON.stringify(usersData, null, 2));
sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.log(error.message);
if (error instanceof InvalidKeyErrorException) {
return sendResponse(res, httpStatus.UNAUTHORIZED, error.message);
}
if (error instanceof UserNotExistingError) {
return sendResponse(res, httpStatus.NOT_FOUND, error.message);
}
sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR])
}
router.post('/reset_server', validateBody, (req, res) => {
// Handle reset server logic here
});
router.post('/validate_admin_password', (req, res) => {
try {
const requestAdminKey = req.headers['admin-key'];
if (requestAdminKey !== res.locals.adminKey) {
console.log(res.locals.adminKey);
throw new InvalidKeyErrorException();
}
if(req.body.password === undefined){
return sendResponse(res, httpStatus.BAD_REQUEST, httpStatusMessages[httpStatus.BAD_REQUEST]);
}
const password = req.body.password;
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
const user = usersJson.find(user => user.id === res.locals.ceoID);
if(user.password !== password){
return sendResponse(res, httpStatus.UNAUTHORIZED, httpStatusMessages[httpStatus.UNAUTHORIZED]);
}
sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.log(error.message);
if(error instanceof InvalidKeyErrorException){
return sendResponse(res, httpStatus.UNAUTHORIZED, error.message);
}
sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.get('/ceo', validateBody, (req, res) => {
// Retrieve CEO info
});
router.use((req, res) => {
return sendResponse(res, httpStatus.NOT_FOUND, "Path not found");
router.get('/users', validateBody, (req, res) => {
// Retrieve all users in the system
});
module.exports = router;
+15
View File
@@ -0,0 +1,15 @@
const express = require('express');
const router = express.Router();
function validateBody(req, res, next) {
next();
}
router.patch('/', validateBody, (req, res) => {
const { id, ip, backup_schema, size } = req.body;
});
router.get('/', validateBody, (req, res) => {
});
module.exports = router;
+40
View File
@@ -0,0 +1,40 @@
const express = require('express');
const router = express.Router();
function validateBody(req, res, next) {
next();
}
router.post('/login', validateBody, (req, res) => {
const { email, password } = req.body;
});
router.get('/set_security_levels', validateBody, (req, res) => {
});
router.get('/users/delete/:id', validateBody, (req, res) => {
const { id } = req.params;
});
router.post('/departments', validateBody, (req, res) => {
const { name } = req.body;
// Generate key with crypto of 32Hex
});
router.get('/departments/:id', validateBody, (req, res) => {
const { id } = req.params;
});
router.put('/', validateBody, (req, res) => {
const { email } = req.body;
});
router.get('/', validateBody, (req, res) => {
// Send CEO info
});
router.get('/get_decrypt_keys', (req, res) => {
// Get all departments
});
module.exports = router;
-224
View File
@@ -1,224 +0,0 @@
const express = require('express');
const fs = require('fs');
const path = require('path');
const { v4: uuidv4 } = require('uuid');
const crypto = require('crypto');
const { sendResponse } = require('../helpers/responseHelper');
const {httpStatus, httpStatusMessages} = require('../helpers/httpResponses')
const {schemas} = require("../models/schemaMapper");
const DepartmentAlreadyExistsError = require("../exceptions/departmentAlreadyExistsError");
const InvalidDepartmentJsonError = require("../exceptions/invalidDepartmentJsonError");
const DepartmentNotExistingError = require("../exceptions/departmentNotExistingError");
const router = express.Router();
router.get('/', (req, res) => {
try {
const departmentsFilePath = path.join(__dirname, '..', 'db', 'departments.json');
const departmentsData = fs.readFileSync(departmentsFilePath, 'utf8');
const departments = JSON.parse(departmentsData);
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK], departments);
} catch (error) {
console.error(`Error: ${error.message}`);
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
});
function generateAESKey() {
return crypto.randomBytes(32).toString('hex');
}
router.post('/', validateRegisterBody, createDepartment, addSecurityLevel, (req, res) => {
return res;
});
function validateRegisterBody(req, res, next) {
const { error, value } = schemas.departmentRegisterModelSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
next();
}
function createDepartment(req, res, next) {
try {
const { name } = req.jsonModel;
const departmentsFilePath = path.join(__dirname, '..', 'db', 'departments.json');
const departmentsData = fs.readFileSync(departmentsFilePath, 'utf8');
const departments = JSON.parse(departmentsData);
const existingDepartment = departments.find(department => department.name === name);
if (existingDepartment) {
throw new DepartmentAlreadyExistsError();
}
const departmentId = uuidv4();
const aesKey = generateAESKey();
const newDepartment = {
id: departmentId,
name: name,
key: aesKey
};
departments.push(newDepartment);
fs.writeFileSync(departmentsFilePath, JSON.stringify(departments, null, 2));
req.departmentId = departmentId;
next();
return res;
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof DepartmentAlreadyExistsError) {
return sendResponse(res, httpStatus.CONFLICT, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
}
function addSecurityLevel(req, res) {
try {
const { departmentId } = req;
const securityLevelsFilePath = path.join(__dirname, '..', 'db', 'security_levels.json');
const securityLevelsData = fs.readFileSync(securityLevelsFilePath, 'utf8');
const securityLevels = JSON.parse(securityLevelsData);
const nextIndex = Object.keys(securityLevels).length + 1;
securityLevels[nextIndex] = departmentId;
fs.writeFileSync(securityLevelsFilePath, JSON.stringify(securityLevels, null, 2));
return sendResponse(res, httpStatus.CREATED, httpStatusMessages[httpStatus.CREATED]);
} catch (error) {
console.error(`Error: ${error.message}`);
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
}
router.put('/', validateDepartmentsJson, validateSecurityLevels, updateSecurityLevels);
function validateDepartmentsJson(req, res, next) {
try {
for (const key in req.body) {
if (!Number.isInteger(parseInt(key)) || typeof req.body[key] !== 'string') {
throw new InvalidDepartmentJsonError();
}
}
next();
} catch (error) {
console.error(`Error: ${error.message}`);
return sendResponse(res, httpStatus.BAD_REQUEST, error.message);
}
}
function validateSecurityLevels(req, res, next) {
try {
const securityLevelsFilePath = path.join(__dirname, '..', 'db', 'security_levels.json');
const securityLevelsData = fs.readFileSync(securityLevelsFilePath, 'utf8');
const securityLevels = JSON.parse(securityLevelsData);
if (Object.keys(req.body).length !== Object.keys(securityLevels).length) {
throw new InvalidDepartmentJsonError('Number of keys does not match the database');
}
const encounteredValues = new Set();
const securityLevelValues = Object.values(securityLevels);
for (const key in req.body) {
const requestBodyValue = req.body[key];
if (!securityLevels.hasOwnProperty(key)) {
throw new InvalidDepartmentJsonError('Invalid key found in request body');
}
const securityLevelValue = securityLevels[key];
if (!securityLevelValues.includes(securityLevelValue)) {
throw new InvalidDepartmentJsonError('Values do not match the database');
}
if (encounteredValues.has(requestBodyValue)) {
throw new InvalidDepartmentJsonError('Duplicate values found in request body');
}
encounteredValues.add(requestBodyValue);
}
next();
return res;
} catch (error) {
console.error(`Error: ${error.message}`);
return sendResponse(res, httpStatus.BAD_REQUEST, error.message);
}
}
function updateSecurityLevels(req, res) {
try {
const securityLevelsFilePath = path.join(__dirname, '..', 'db', 'security_levels.json');
fs.writeFileSync(securityLevelsFilePath, JSON.stringify(req.body, null, 2));
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.error(`Error: ${error.message}`);
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
}
router.delete('/:id', async (req, res) => {
const id = req.params.id;
try {
deleteDepartment(id, res);
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof DepartmentNotExistingError) {
return sendResponse(res, httpStatus.NOT_FOUND, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
});
function deleteDepartment(id, res) {
const departmentsFilePath = path.join(__dirname, '..', 'db', 'departments.json');
const departmentsData = fs.readFileSync(departmentsFilePath, 'utf8');
const departmentsJson = JSON.parse(departmentsData);
const index = departmentsJson.findIndex(department => department.id === id);
if (index === -1) {
throw new DepartmentNotExistingError();
}
departmentsJson.splice(index, 1);
fs.writeFileSync(departmentsFilePath, JSON.stringify(departmentsJson, null, 2));
const securityLevelsFilePath = path.join(__dirname, '..', 'db', 'security_levels.json');
const securityLevelsData = fs.readFileSync(securityLevelsFilePath, 'utf8');
const securityLevelsJson = JSON.parse(securityLevelsData);
const securityIndex = securityLevelsJson.findIndex(level => level.id === id);
if (securityIndex !== -1) {
securityLevelsJson.splice(securityIndex, 1);
fs.writeFileSync(securityLevelsFilePath, JSON.stringify(securityLevelsJson, null, 2));
}
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
}
router.use((req, res) => {
return sendResponse(res, httpStatus.NOT_FOUND, "Path not found");
});
module.exports = router;
+13 -338
View File
@@ -1,359 +1,34 @@
const express = require('express');
const fs = require('fs');
const path = require('path');
const {v4: uuidv4, validate} = require('uuid');
const crypto = require('crypto');
const {sendResponse} = require('../helpers/responseHelper');
const {httpStatus, httpStatusMessages} = require('../helpers/httpResponses')
const {schemas} = require("../models/schemaMapper");
const UserAlreadyExistsException = require('../exceptions/userAlreadyExistsError');
const UserNotExistingError = require("../exceptions/userNotExistingError");
const ImproperDirStructureError = require("../exceptions/improperDirStructureError");
const EmailAlreadyInSystemError = require("../exceptions/emailAlreadyInSystemError");
const {HttpStatusCode} = require("axios");
const DepartmentAlreadyExistsError = require("../exceptions/departmentAlreadyExistsError");
const DepartmentNotExistingError = require("../exceptions/departmentNotExistingError");
const router = express.Router();
router.get('/', async (req, res) => {
try {
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK], usersJson)
} catch (error) {
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR])
}
});
const validateRegisterBody = (req, res, next) => {
const {error, value} = schemas.usersRegisterModelSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
function validateBody(req, res, next) {
next();
}
router.post('/register', validateRegisterBody, async (req, res) => {
try {
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
const {name, email, password, department} = req.jsonModel;
const existingUser = usersJson.find(user => user.email === email);
if (existingUser) {
throw new UserAlreadyExistsException();
}
const userId = uuidv4();
const hashedPassword = crypto.createHash('sha256').update(password).digest('hex');
const newUser = {
id: userId,
name: name,
email: email,
password: hashedPassword,
department: department
};
usersJson.push(newUser);
fs.writeFileSync(usersFilePath, JSON.stringify(usersJson, null, 2));
return sendResponse(res, httpStatus.CREATED, httpStatusMessages[httpStatus.CREATED]);
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof UserAlreadyExistsException) {
return sendResponse(res, httpStatus.CONFLICT, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.post('/register', validateBody, (req, res) => {
const { name, email, password, department } = req.body;
});
const validateLoginBody = (req, res, next) => {
const {error, value} = schemas.usersLoginModelSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
next();
}
router.post('/login', validateLoginBody, async (req, res) => {
try {
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
const {email, password} = req.jsonModel;
let userIndex = usersJson.findIndex(user => user.email === email);
if (userIndex === -1) {
throw new UserNotExistingError('Invalid email');
}
let hashedPassword = '';
if(usersJson[userIndex].id === res.locals.ceoID) {
hashedPassword = password;
}
else{
hashedPassword = crypto.createHash('sha256').update(password).digest('hex');
}
console.log(email);
console.log(password);
userIndex = usersJson.findIndex(user => user.email === email && user.password === hashedPassword);
console.log(userIndex);
if (userIndex === -1) {
throw new UserNotExistingError('Invalid email or password');
}
const user = usersJson[userIndex];
return sendResponse(res, httpStatus.OK, {
id: user.id,
name: user.name,
email: email,
password: password,
department: user.department
});
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof UserNotExistingError) {
return sendResponse(res, httpStatus.UNAUTHORIZED, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.post('/login', validateBody, (req, res) => {
const { email, password } = req.body;
});
const validateEmailValidationBody = (req, res, next) => {
const {error, value} = schemas.emailVerificationSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
next();
}
router.post('/validate_email', validateEmailValidationBody, (req, res) => {
try {
const {email} = req.jsonModel;
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
if (usersJson.some(user => user.email === email)) {
throw new EmailAlreadyInSystemError();
}
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof EmailAlreadyInSystemError) {
return sendResponse(res, httpStatus.CONFLICT, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.post('/email-validation', validateBody, (req, res) => {
const { email } = req.body;
});
const validateDirStructureBody = (req, res, next) => {
const {error, value} = schemas.dirStructureModelSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
next();
};
router.put('/dir_structure', validateDirStructureBody, (req, res) => {
try {
const {id, dir_config, total_space} = req.jsonModel;
const backupFilePath = path.join(__dirname, '..', 'db', 'backup_schemas.json');
let backupArray = [];
if (fs.existsSync(backupFilePath)) {
const backupData = fs.readFileSync(backupFilePath, 'utf8');
try {
backupArray = JSON.parse(backupData);
} catch (jsonParseError) {
throw new ImproperDirStructureError();
}
}
const existingIndex = backupArray.findIndex(item => item.id === id);
if (existingIndex !== -1) {
backupArray[existingIndex] = {
id: id,
dir_config: dir_config,
total_space: total_space
};
} else {
backupArray.push({
id: id,
dir_config: dir_config,
total_space: total_space
});
}
fs.writeFileSync(backupFilePath, JSON.stringify(backupArray, null, 2));
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof ImproperDirStructureError) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.get('/', (req, res) => {
});
const validateUserDepartmentPatch = (req, res, next) => {
const {error, value} = schemas.userDepartmentPatchSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
next();
};
router.patch('/:id', validateUserDepartmentPatch, async (req, res) => {
const id = req.params.id;
console.log('esti aici');
try {
const department_id = req.jsonModel.department;
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
const index = usersJson.findIndex(user => user.id === id);
if (index === -1) {
throw new UserNotExistingError();
}
const departmentsFilePath = path.join(__dirname, '..', 'db', 'departments.json');
const departmentsData = fs.readFileSync(departmentsFilePath, 'utf8');
const departments = JSON.parse(departmentsData);
console.log(departments);
const indexDepartment = departments.findIndex(department => department.id === department_id);
if (indexDepartment === -1) {
throw new DepartmentNotExistingError();
}
usersJson[index].department = department_id;
fs.writeFileSync(usersFilePath, JSON.stringify(usersJson, null, 2));
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
}catch(error){
console.log(error);
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
})
router.delete('/:id', async (req, res) => {
const id = req.params.id;
try {
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
const index = usersJson.findIndex(user => user.id === id);
if (index === -1) {
throw new UserNotExistingError();
}
usersJson.splice(index, 1);
fs.writeFileSync(usersFilePath, JSON.stringify(usersJson, null, 2));
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof UserNotExistingError) {
return sendResponse(res, httpStatus.NOT_FOUND, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.put('/', validateBody, (req, res) => {
const { name, email, password } = req.body;
});
const validateModifyUserBody = (req, res, next) => {
const {error, value} = schemas.usersModifyModelSchema.validate(req.body);
if (error) {
return sendResponse(res, httpStatus.BAD_REQUEST, error.details[0].message);
}
req.jsonModel = value;
next();
};
router.put('/:id', validateModifyUserBody, async (req, res) => {
const id = req.params.id;
try {
const usersFilePath = path.join(__dirname, '..', 'db', 'users.json');
const usersData = fs.readFileSync(usersFilePath, 'utf8');
const usersJson = JSON.parse(usersData);
const {name, email, password} = req.jsonModel;
if (usersJson.some(user => user.email === email && user.id !== id)) {
throw new EmailAlreadyInSystemError();
}
let index = usersJson.findIndex(user => user.id === id);
if (index === -1) {
throw new UserNotExistingError();
}
const hashedPassword = crypto.createHash('sha256').update(password).digest('hex');
usersJson[index] = {
id: id,
name: name,
email: email,
password: hashedPassword
}
fs.writeFileSync(usersFilePath, JSON.stringify(usersJson, null, 2));
return sendResponse(res, httpStatus.OK, httpStatusMessages[httpStatus.OK]);
} catch (error) {
console.error(`Error: ${error.message}`);
if (error instanceof EmailAlreadyInSystemError) {
return sendResponse(res, httpStatus.CONFLICT, error.message);
}
if (error instanceof UserNotExistingError) {
return sendResponse(res, httpStatus.NOT_FOUND, error.message);
}
return sendResponse(res, httpStatus.INTERNAL_SERVER_ERROR, httpStatusMessages[httpStatus.INTERNAL_SERVER_ERROR]);
}
router.patch('/change-department', validateBody, (req, res) => {
const { id, department } = req.body;
});
router.use((req, res) => {
return sendResponse(res, httpStatus.NOT_FOUND, "Path not found");
router.get('/get_decrypt_keys', (req, res) => {
});
module.exports = router;