225 lines
7.9 KiB
JavaScript
225 lines
7.9 KiB
JavaScript
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;
|