ADMIN UI DONE
This commit is contained in:
Generated
+7
@@ -14,6 +14,7 @@
|
|||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cron": "^3.1.6",
|
"cron": "^3.1.6",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"express": "^4.19.1",
|
"express": "^4.19.1",
|
||||||
"joi": "^17.12.2",
|
"joi": "^17.12.2",
|
||||||
@@ -492,6 +493,12 @@
|
|||||||
"luxon": "~3.4.0"
|
"luxon": "~3.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/crypto": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
|
||||||
|
"deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
|
||||||
|
},
|
||||||
"node_modules/crypto-js": {
|
"node_modules/crypto-js": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"cron": "^3.1.6",
|
"cron": "^3.1.6",
|
||||||
|
"crypto": "^1.0.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"express": "^4.19.1",
|
"express": "^4.19.1",
|
||||||
"joi": "^17.12.2",
|
"joi": "^17.12.2",
|
||||||
|
|||||||
+17
-1
@@ -5,9 +5,25 @@ const cors = require('cors');
|
|||||||
const app = express();
|
const app = express();
|
||||||
const port = process.env.PORT || 5000;
|
const port = process.env.PORT || 5000;
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors({
|
||||||
|
allowedHeaders: ['Authorization', 'Content-Type'] // Add 'Authorization' to the list of allowed headers
|
||||||
|
}));
|
||||||
app.use(json());
|
app.use(json());
|
||||||
|
|
||||||
|
const {
|
||||||
|
usersDB,
|
||||||
|
departmentsDB,
|
||||||
|
backupSchemesDB,
|
||||||
|
ceoDB,
|
||||||
|
adminDB
|
||||||
|
} = require('./db/jsonDatabaseManager');
|
||||||
|
|
||||||
|
app.set('usersDB', usersDB);
|
||||||
|
app.set('departmentsDB', departmentsDB);
|
||||||
|
app.set('backupSchemesDB', backupSchemesDB);
|
||||||
|
app.set('ceoDB', ceoDB);
|
||||||
|
app.set('adminDB', adminDB);
|
||||||
|
|
||||||
const checkJson = require('./middlewares/checkJson');
|
const checkJson = require('./middlewares/checkJson');
|
||||||
const apiKeyValidation = require('./middlewares/apiKeyValidation');
|
const apiKeyValidation = require('./middlewares/apiKeyValidation');
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "CEO",
|
||||||
|
"email": "ceo@yourfirm.com",
|
||||||
|
"password": "335ae110091d3bc5fbc90d5e3786890e"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class JSONDatabase {
|
||||||
|
constructor(filePath) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.readFile = this.readFile.bind(this); // Bind readFile method to the instance
|
||||||
|
this.writeFile = this.writeFile.bind(this); // Bind writeFile method to the instance
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
readFile() {
|
||||||
|
if (!fs.existsSync(this.filePath)) {
|
||||||
|
console.log('File does not exist, returning null:', this.filePath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const data = fs.readFileSync(this.filePath, 'utf8');
|
||||||
|
return JSON.parse(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error reading file:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeFile(data) {
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2), { flag: 'w' });
|
||||||
|
console.log('File written successfully.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error writing file:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const usersDB = new JSONDatabase(path.join(__dirname, 'users.json'));
|
||||||
|
const departmentsDB = new JSONDatabase(path.join(__dirname, 'departments.json'));
|
||||||
|
const backupSchemesDB = new JSONDatabase(path.join(__dirname, 'backup_schemes.json'));
|
||||||
|
const ceoDB = new JSONDatabase(path.join(__dirname, 'ceo.json'));
|
||||||
|
const adminDB = new JSONDatabase(path.join(__dirname + '..', '..', '..', '..', 'frontend', 'config', 'credentials.json'));
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
usersDB,
|
||||||
|
departmentsDB,
|
||||||
|
backupSchemesDB,
|
||||||
|
ceoDB,
|
||||||
|
adminDB,
|
||||||
|
JSONDatabase
|
||||||
|
};
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
[]
|
||||||
@@ -1,20 +1,47 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
|
const {httpStatus} = require("../helpers/httpResponses");
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
function validateBody(req, res, next) {
|
function validateBody(req, res, next) {
|
||||||
|
const apiKey = req.headers['authorization'];
|
||||||
|
const adminDB = req.app.get('adminDB');
|
||||||
|
const {id} = adminDB.readFile();
|
||||||
|
|
||||||
|
if(apiKey !== id){
|
||||||
|
return res.status(httpStatus.UNAUTHORIZED).json(
|
||||||
|
{message: "You are not authorized as an admin."})
|
||||||
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
router.post('/reset_server', validateBody, (req, res) => {
|
router.get('/reset_server', validateBody, (req, res) => {
|
||||||
// Handle reset server logic here
|
const usersDB = req.app.get('usersDB');
|
||||||
|
const departmentsDB = req.app.get('departmentsDB');
|
||||||
|
const backupSchemesDB = req.app.get('backupSchemesDB');
|
||||||
|
const ceoDB = req.app.get('ceoDB');
|
||||||
|
|
||||||
|
usersDB.writeFile([]);
|
||||||
|
departmentsDB.writeFile([]);
|
||||||
|
backupSchemesDB.writeFile({});
|
||||||
|
ceoDB.writeFile({
|
||||||
|
name: "CEO",
|
||||||
|
email: "ceo@yourfirm.com",
|
||||||
|
password: crypto.randomBytes(16).toString('hex')
|
||||||
|
});
|
||||||
|
|
||||||
|
res.status(httpStatus.OK).json({ message: "Resetting the server..." });
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/ceo', validateBody, (req, res) => {
|
router.get('/ceo', validateBody, (req, res) => {
|
||||||
// Retrieve CEO info
|
const ceoDB = req.app.get('ceoDB');
|
||||||
|
res.status(httpStatus.OK).json({ message: "Retrieving CEO info...", data: ceoDB.readFile() }) // Corrected to readFile
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/users', validateBody, (req, res) => {
|
router.get('/users', validateBody, (req, res) => {
|
||||||
// Retrieve all users in the system
|
const usersDB = req.app.get('usersDB');
|
||||||
|
res.status(httpStatus.OK).json({ message: "Retrieving users info...", data: usersDB.readFile() }) // Corrected to readFile
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ enable routing to the server;
|
|||||||
so also make sure to open those ports as well;
|
so also make sure to open those ports as well;
|
||||||
- If the CEO wants to change the email address linked to the account, his password will be changed
|
- If the CEO wants to change the email address linked to the account, his password will be changed
|
||||||
to a low-risk password, so make sure after any release to specify the account information;
|
to a low-risk password, so make sure after any release to specify the account information;
|
||||||
|
- Make sure that all the ports configurations are respected to have all the applications work properly
|
||||||
|
|
||||||
Closing thoughts
|
Closing thoughts
|
||||||
-
|
-
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"id": "deee8837-3549-44d5-af56-fb7532505574",
|
||||||
"name": "Andrei",
|
"name": "Andrei",
|
||||||
"email": "admin@yourfirm.com",
|
"email": "admin@yourfirm.com",
|
||||||
"password": "password"
|
"password": "password"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const result = await response.json();
|
const result = await response.json();
|
||||||
|
|
||||||
if (response.ok && result.success) {
|
if (response.ok && result.success) {
|
||||||
// Set cookie with email and name
|
document.cookie = `id=${result.user.id};`;
|
||||||
document.cookie = `email=${result.user.email};`;
|
document.cookie = `email=${result.user.email};`;
|
||||||
document.cookie = `name=${result.user.name};`;
|
document.cookie = `name=${result.user.name};`;
|
||||||
|
|
||||||
|
|||||||
@@ -62,14 +62,122 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
ceoInfoButton.addEventListener('click', () => {
|
ceoInfoButton.addEventListener('click', () => {
|
||||||
console.log('Ceo Info Button pressed');
|
console.log('Ceo Info Button pressed');
|
||||||
|
|
||||||
|
const domain = window.location.hostname;
|
||||||
|
const endpoint = 'http://' + domain + ':5000/admin/ceo';
|
||||||
|
const id = getCookie('id');
|
||||||
|
|
||||||
|
fetch(endpoint, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': id
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(async response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
const responseData = await response.json();
|
||||||
|
throw new Error(responseData.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await response.json()
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
alert(data.message);
|
||||||
|
|
||||||
|
// Assuming 'data' is the property you want to download
|
||||||
|
const toDownload = data.data;
|
||||||
|
const jsonStr = JSON.stringify(toDownload, null, 2);
|
||||||
|
const blob = new Blob([jsonStr], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'ceo.json';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// Cleanup: remove the link and revoke the URL
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
alert(error)
|
||||||
|
console.error('Error: '+ error)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
usersInfoButton.addEventListener('click', () => {
|
usersInfoButton.addEventListener('click', () => {
|
||||||
console.log('Users Info Button pressed');
|
console.log('Users Info Button pressed');
|
||||||
|
|
||||||
|
const domain = window.location.hostname;
|
||||||
|
const endpoint = 'http://' + domain + ':5000/admin/users';
|
||||||
|
const id = getCookie('id');
|
||||||
|
|
||||||
|
fetch(endpoint, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': id
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(async response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
const responseData = await response.json();
|
||||||
|
throw new Error(responseData.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await response.json()
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
alert(data.message);
|
||||||
|
|
||||||
|
const toDownload = data.data;
|
||||||
|
const jsonStr = JSON.stringify(toDownload, null, 2);
|
||||||
|
const blob = new Blob([jsonStr], { type: 'application/json' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
// Create a temporary link to trigger the download
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'users.json';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
// Cleanup: remove the link and revoke the URL
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
alert(error)
|
||||||
|
console.error('Error: '+ error)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
resetUcButton.addEventListener('click', () => {
|
resetUcButton.addEventListener('click', () => {
|
||||||
console.log('Set Conf Button pressed');
|
console.log('Reset UC Button pressed');
|
||||||
|
|
||||||
|
const domain = window.location.hostname;
|
||||||
|
const endpoint = 'http://' + domain + ':5000/admin/reset_server';
|
||||||
|
const id = getCookie('id');
|
||||||
|
|
||||||
|
fetch(endpoint, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: {
|
||||||
|
'Authorization': id
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(async response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
const responseData = await response.json();
|
||||||
|
throw new Error(responseData.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await response.json()
|
||||||
|
})
|
||||||
|
.then(data => alert(data.message))
|
||||||
|
.catch(error => {
|
||||||
|
alert(error)
|
||||||
|
console.error('Error: '+ error)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
logoutButton.addEventListener('click', () => {
|
logoutButton.addEventListener('click', () => {
|
||||||
@@ -81,6 +189,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
deleteCookie('email');
|
deleteCookie('email');
|
||||||
deleteCookie('name');
|
deleteCookie('name');
|
||||||
|
deleteCookie('id');
|
||||||
|
|
||||||
fadeOut('/login');
|
fadeOut('/login');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function validateLogin(req, res, next) {
|
|||||||
const {error, value} = schemas.loginModelSchema.validate(req.body);
|
const {error, value} = schemas.loginModelSchema.validate(req.body);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
res.status(statusCodes.BAD_REQUEST).json({success: false, error: error.details});
|
res.status(statusCodes.BAD_REQUEST).json({error: error.details});
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
@@ -29,12 +29,13 @@ router.post('/', validateLogin, (req, res) => {
|
|||||||
success: true,
|
success: true,
|
||||||
message: 'Login successful',
|
message: 'Login successful',
|
||||||
user: {
|
user: {
|
||||||
|
id: config.id,
|
||||||
name: config.name,
|
name: config.name,
|
||||||
email: config.email
|
email: config.email
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
res.status(statusCodes.UNAUTHORIZED).json({ success: false, message: 'Invalid email or password' });
|
res.status(statusCodes.UNAUTHORIZED).json({message: 'Invalid email or password' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -43,8 +43,4 @@ router.post('/server', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('ceo_credentials', (req, res) => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
Reference in New Issue
Block a user