API CEO + USER v1.0

This commit is contained in:
andrei-mihnea-cerbu
2024-04-03 09:50:48 +03:00
parent 4f8719e9c8
commit 038b809dd8
7 changed files with 212 additions and 16 deletions
+1
View File
@@ -1,4 +1,5 @@
{ {
"id": "335ae110091d3bc5fbc90d5e3786890e",
"name": "CEO", "name": "CEO",
"email": "ceo@yourfirm.com", "email": "ceo@yourfirm.com",
"password": "335ae110091d3bc5fbc90d5e3786890e" "password": "335ae110091d3bc5fbc90d5e3786890e"
+10 -1
View File
@@ -1 +1,10 @@
[] {
"1": {
"name": "HR",
"key": "65388e02b16e1cc530502492384ebd29ee6cda57840235d714d59dd460ae148a"
},
"2": {
"name": "Contabili",
"key": "572854d54c42f03ddcbb2beeae574dc4fcd33b251670d4983be49c4242c2d88a"
}
}
+3 -1
View File
@@ -7,6 +7,7 @@ const ceoModifyModelSchema = require('./ceoModifyModel');
const emailVerificationSchema = require('./emailVerificationModel'); const emailVerificationSchema = require('./emailVerificationModel');
const userDepartmentPatchSchema = require('./userDepartmentPatchModel'); const userDepartmentPatchSchema = require('./userDepartmentPatchModel');
const ceoPasswordModelSchema = require('./ceoPasswordModel'); const ceoPasswordModelSchema = require('./ceoPasswordModel');
const securityLevelsModelSchema = require('./securityLevelsModel');
module.exports = { module.exports = {
schemas: { schemas: {
@@ -18,6 +19,7 @@ module.exports = {
ceoModifyModelSchema, ceoModifyModelSchema,
emailVerificationSchema, emailVerificationSchema,
userDepartmentPatchSchema, userDepartmentPatchSchema,
ceoPasswordModelSchema ceoPasswordModelSchema,
securityLevelsModelSchema
}, },
}; };
@@ -0,0 +1,19 @@
const Joi = require("joi");
// Define a schema for the string values (department names)
const nameSchema = Joi.string().required().messages({
'string.empty': 'Name can\'t be empty',
'any.required': 'Name is required'
});
// Define the main schema for the security levels model
const securityLevelsModel = Joi.object().pattern(
Joi.number().integer().positive().messages({
'number.base': 'Keys must be integers',
'number.integer': 'Keys must be integers',
'number.positive': 'Keys must be positive integers'
}),
nameSchema
);
module.exports = securityLevelsModel;
+6 -2
View File
@@ -1,7 +1,10 @@
const express = require('express'); const express = require('express');
const {httpStatus} = require("../helpers/httpResponses");
const router = express.Router();
const crypto = require('crypto'); const crypto = require('crypto');
const { v4: uuidv4 } = require('uuid');
const {httpStatus} = require("../helpers/httpResponses");
const router = express.Router();
function validateBody(req, res, next) { function validateBody(req, res, next) {
const apiKey = req.headers['authorization']; const apiKey = req.headers['authorization'];
@@ -26,6 +29,7 @@ router.get('/reset_server', validateBody, (req, res) => {
departmentsDB.writeFile([]); departmentsDB.writeFile([]);
backupSchemesDB.writeFile({}); backupSchemesDB.writeFile({});
ceoDB.writeFile({ ceoDB.writeFile({
id: uuidv4(),
name: "CEO", name: "CEO",
email: "ceo@yourfirm.com", email: "ceo@yourfirm.com",
password: crypto.randomBytes(16).toString('hex') password: crypto.randomBytes(16).toString('hex')
+157 -10
View File
@@ -1,40 +1,187 @@
const express = require('express'); const express = require('express');
const { v4: uuidv4 } = require('uuid');
const {schemas} = require("../models/schemaMapper");
const {httpStatus} = require("../helpers/httpResponses");
const crypto = require("crypto");
const {departmentsDB} = require("../db/jsonDatabaseManager");
const router = express.Router(); const router = express.Router();
function validateBody(req, res, next) { function validateBody(req, res, next) {
if(req.path !== '/login'){
const ceoDB = req.app.get('ceoDB');
const ceoPassword = req.headers['ceo_password'];
const {password} = ceoDB.readFile()
if(ceoPassword !== password){
return res.status(httpStatus.UNAUTHORIZED).json({message: 'Invalid CEO password.'});
}
}
let validationSchema = undefined;
switch(req.path){
case '/set_security_levels':
validationSchema = schemas.securityLevelsModelSchema;
break;
case '/login':
validationSchema = schemas.usersLoginModelSchema;
break;
case '/departments':
validationSchema = schemas.departmentRegisterModelSchema;
break;
case '/':
if(req.method === 'PUT'){
validationSchema = schemas.ceoModifyModelSchema;
}
break;
default:
validationSchema = undefined;
}
if(validationSchema !== undefined){
const {error} = validationSchema.validate(req.body);
if(error){
const errorMessage = error.details.map(detail => detail.message).join(', ');
return res.status(httpStatus.BAD_REQUEST).json({ message: errorMessage });
}
}
next(); next();
} }
router.post('/login', validateBody, (req, res) => { router.post('/login', validateBody, (req, res) => {
const ceoDB = req.app.get('ceoDB');
const { email, password } = req.body; const { email, password } = req.body;
if(ceoDB.findIndexByKeyValueInArray('email', email) !== ceoDB.findIndexByKeyValueInArray('password', password)){
return res.status(httpStatus.UNAUTHORIZED).json({message: 'Invalid credentials.'});
}
return res.status(httpStatus.Ok).json({message: 'Logged in.'});
}); });
router.get('/set_security_levels', validateBody, (req, res) => { router.post('/set_security_levels', validateBody, (req, res) => {
const departmentsDB = req.app.get('departmentsDB');
const departmentsJson = departmentsDB.readFile();
const levelsJson = req.body;
console.log(levelsJson);
const newJson = {};
Object.entries(levelsJson).forEach(([levelKey, departmentName]) => {
let departmentId = -1;
for (let deptKey in departmentsJson) {
if (departmentsJson.hasOwnProperty(deptKey)) {
if (departmentsJson[deptKey].name === departmentName) {
departmentId = deptKey;
break;
}
}
}
if (departmentId !== -1) {
newJson[levelKey] = {
name: departmentName,
key: departmentsJson[departmentId].key
};
}
}); });
router.get('/users/delete/:id', validateBody, (req, res) => {
departmentsDB.writeFile(newJson);
return res.status(httpStatus.OK).json({message: 'Departments levels updated.'});
});
router.delete('/users/:id', validateBody, (req, res) => {
const usersDB = req.app.get('usersDB');
const { id } = req.params; const { id } = req.params;
const userIndex = usersDB.findIndexByKeyValueInArray('id', id);
if(userIndex === -1){
return res.status(httpStatus.NOT_FOUND).json({message: 'User not found in system.'});
}
let usersJson = usersDB.readFile;
usersJson.splice(userIndex, 1);
usersDB.writeFile(usersJson);
return res.status(httpStatus.OK).json({ message: 'User deleted successfully.' });
}); });
router.post('/departments', validateBody, (req, res) => { router.post('/departments', validateBody, (req, res) => {
const departmentsDB = req.app.get('departmentsDB');
const { name } = req.body; const { name } = req.body;
// Generate key with crypto of 32Hex
let jsonDepartments = departmentsDB.readFile();
const nameExists = Object.values(jsonDepartments).some(department => department.name === name);
if(nameExists){
return res.status(httpStatus.CONFLICT).json({message: 'Department already in system.'})
}
const isObjectEmpty = !Object.keys(jsonDepartments).length;
const highestKey = isObjectEmpty ? 0 : Math.max(...Object.keys(jsonDepartments).map(Number));
const nextKey = highestKey + 1;
jsonDepartments[nextKey] = {
name: name,
key: crypto.randomBytes(32).toString('hex')
};
departmentsDB.writeFile(jsonDepartments);
return res.status(httpStatus.CREATED).json({message: 'Department successfully created'});
}); });
router.get('/departments/:id', validateBody, (req, res) => { router.delete('/departments/:name', validateBody, (req, res) => {
const { id } = req.params; const departmentsDB = req.app.get('departmentsDB');
let departmentsJson = departmentsDB.readFile();
let foundName = false;
const { name } = req.params;
console.log(name);
for (let key in departmentsJson) {
if (departmentsJson.hasOwnProperty(key)) {
const department = departmentsJson[key];
if (department.name === name) {
delete departmentsJson[key];
foundName = true;
break;
}
}
}
if(foundName !== true){
return res.status(httpStatus.NOT_FOUND).json({ message: 'Department not found.' });
}
departmentsDB.writeFile(departmentsJson);
return res.status(httpStatus.OK).json({ message: 'Department deleted successfully.' });
}); });
router.put('/', validateBody, (req, res) => { router.put('/', validateBody, (req, res) => {
const { email } = req.body; const ceoDB = req.app.get('ceoDB');
}); const { name, email } = req.body;
const {id} = ceoDB.readFile()
router.get('/', validateBody, (req, res) => { const newCeo = {
// Send CEO info id: id,
name: name,
email: email,
password: crypto.randomBytes(16).toString('hex')
}
ceoDB.writeFile(newCeo);
return res.status(httpStatus.OK).json({message: 'Information modified.'});
}); });
router.get('/get_decrypt_keys', (req, res) => { router.get('/get_decrypt_keys', (req, res) => {
// Get all departments return res.status(httpStatus.OK).json({
message: 'Departments fetched.',
data: departmentsDB.readFile()
});
}); });
module.exports = router; module.exports = router;
+16 -2
View File
@@ -90,12 +90,26 @@ router.post('/validate_email', validateBody, (req, res) => {
router.get('/', (req, res) => { router.get('/', (req, res) => {
const usersDB = req.app.get('usersDB'); const usersDB = req.app.get('usersDB');
const ceoDB = req.app.get('ceoDB');
const ceoJson = ceoDB.readFile();
let usersJson = usersDB.readFile();
usersJson.push(ceoJson);
return res.status(httpStatus.OK).json({ return res.status(httpStatus.OK).json({
message: "Fetched users", message: "Fetched users",
data: usersDB.readFile() data: usersJson
}) })
}); });
router.get('/departments', (req, res) => {
const departmentsDB = req.app.get('departmentsDB');
return res.status(httpStatus.OK).json({
message: 'Departments fetched.',
data: departmentsDB.readFile()
});
})
router.put('/', validateBody, (req, res) => { router.put('/', validateBody, (req, res) => {
const usersDB = req.app.get('usersDB'); const usersDB = req.app.get('usersDB');
let usersJson = usersDB.readFile(); let usersJson = usersDB.readFile();
@@ -161,7 +175,7 @@ router.get('/get_decrypt_keys', (req, res) => {
return res.status(httpStatus.OK).json({ return res.status(httpStatus.OK).json({
message: 'Departments fetched.', message: 'Departments fetched.',
data: departmentsDB.readFile() data: departmentsDB.readFile()
}) });
}); });
router.use((req, res) => { router.use((req, res) => {