reconstruire UC inceput
@@ -1,4 +1,31 @@
|
||||
General overview
|
||||
-
|
||||
|
||||
For the use of the admin console, start with 'npm run start' the UI frontend.
|
||||
To see/modify the initial login credentials check the /config/config.json file.
|
||||
|
||||
WITHOUT SETTING THE CONFIG FILE FOR THE SERVER (API KEY) THE SERVER WILL NOT START!
|
||||
WITHOUT SETTING THE CONFIG FILE, THE SERVER WILL NOT WORK AS INTENDED!
|
||||
(click on the 'Reset UC' when first configuring the server to bring the
|
||||
UC at the initial state)
|
||||
|
||||
Because the client and CEO apps are dependent on the Central Unit (UC), we strongly
|
||||
suggest you to make backup at a regular interval in case of hardware failing you will
|
||||
only have to deploy the server with the configurations already existing.
|
||||
|
||||
Important aspects:
|
||||
-
|
||||
|
||||
- The starting/stopping of the UC is handled by this 'Admin Console'. The server will not
|
||||
work if the server which servers as the 'Admin Console' is not running.
|
||||
- The main server will run at the port 5000, so make sure to configure your routers to
|
||||
enable routing to the server;
|
||||
- The client and CEO backup system of their applications will need access at ports 5001 and 5002,
|
||||
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
|
||||
to a low-risk password, so make sure after any release to specify the account information;
|
||||
|
||||
Closing thoughts
|
||||
-
|
||||
|
||||
We really hope that you will enjoy our application and for any issues, feel free to contact us at
|
||||
'username@ourdomain.com' for troubleshooting and other problems.
|
||||
@@ -7,6 +7,26 @@ const cookieParser = require('cookie-parser');
|
||||
|
||||
const checkSession = require('./middlewares/checkSession');
|
||||
|
||||
process.on('SIGINT', shutdown);
|
||||
process.on('SIGTERM', shutdown);
|
||||
|
||||
function shutdown() {
|
||||
console.log('Received kill signal, shutting down gracefully.');
|
||||
const serverProcess = app.get('serverProcess');
|
||||
if (serverProcess && typeof serverProcess.kill === 'function') {
|
||||
console.log('Shutting down server process...');
|
||||
serverProcess.kill(); // Send SIGTERM to server process
|
||||
|
||||
serverProcess.on('exit', () => {
|
||||
console.log('Server process terminated.');
|
||||
process.exit(0); // Exit main process cleanly
|
||||
});
|
||||
} else {
|
||||
console.log('No server process or cannot be killed, exiting.');
|
||||
process.exit(0); // Exit main process cleanly
|
||||
}
|
||||
}
|
||||
|
||||
const app = express()
|
||||
|
||||
app.set('serverProcess', null);
|
||||
@@ -18,7 +38,7 @@ app.use(bodyParser.json());
|
||||
app.use(express.static(path.join(__dirname, 'public', 'html')));
|
||||
app.use('/css', express.static(path.join(__dirname, 'public', 'css')));
|
||||
app.use('/js', express.static(path.join(__dirname, 'public', 'js')));
|
||||
app.use('/images', express.static(path.join(__dirname, 'public', 'assets')));
|
||||
app.use('/images', express.static(path.join(__dirname, 'public', 'images')));
|
||||
|
||||
app.use(checkSession);
|
||||
|
||||
@@ -31,3 +51,5 @@ const PORT = process.env.PORT || 80;
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server is running on port ${PORT}`);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ body, html {
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
|
||||
@@ -13,78 +13,9 @@ body, html {
|
||||
background-repeat: no-repeat;
|
||||
|
||||
}
|
||||
|
||||
.overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.85);
|
||||
z-index: 2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ceo-validation-form {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 300px;
|
||||
padding: 20px;
|
||||
background: #1B1A55;
|
||||
border-radius: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.ceo-validation-form h2 {
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
text-align: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.form-actions button {
|
||||
padding: 10px 20px;
|
||||
margin: 0 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.2rem;
|
||||
width: 80%;
|
||||
padding: 1rem;
|
||||
margin: 0.7rem;
|
||||
background-color: #1B1A55;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#back_button {
|
||||
background-color: #f44336;
|
||||
width: 35%;
|
||||
height: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#submit_button {
|
||||
background-color: #4CAF50;
|
||||
width: 35%;
|
||||
height: auto;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.container {
|
||||
opacity: 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-evenly;
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
.fade-in {
|
||||
animation: fadeInAnimation 0.5s ease-in forwards;
|
||||
}
|
||||
|
||||
.fade-out {
|
||||
animation: fadeOutAnimation 0.5s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeInAnimation {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOutAnimation {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,28 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="/images/hard-disk.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" type="text/css" href="/css/login.css">
|
||||
<link rel="stylesheet" type="text/css" href="/css/transition.css">
|
||||
<script src="/js/login.js"></script>
|
||||
<script>
|
||||
function fadeIn() {
|
||||
document.querySelector('.container').classList.remove('fade-out');
|
||||
document.querySelector('.container').classList.add('fade-in');
|
||||
}
|
||||
|
||||
function fadeOut(destination) {
|
||||
const container = document.querySelector('.container');
|
||||
container.classList.remove('fade-in');
|
||||
container.classList.add('fade-out');
|
||||
|
||||
container.addEventListener('animationend', () => {
|
||||
window.location.href = destination;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<title>Login</title>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<h1>DO WE KNOW</h1>
|
||||
|
||||
@@ -5,12 +5,28 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" href="/images/hard-disk.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="/css/main_menu.css">
|
||||
<link rel="stylesheet" href="/css/transition.css">
|
||||
|
||||
<script src="/js/main_menu.js"></script>
|
||||
<script>
|
||||
function fadeIn() {
|
||||
document.querySelector('.container').classList.remove('fade-out');
|
||||
document.querySelector('.container').classList.add('fade-in');
|
||||
}
|
||||
|
||||
function fadeOut() {
|
||||
document.querySelector('.container').classList.remove('fade-in');
|
||||
document.querySelector('.container').classList.add('fade-out');
|
||||
// Redirect after fadeOut animation completes (adjust timeout as needed)
|
||||
setTimeout(() => {
|
||||
window.location.href = 'your_redirect_url.html';
|
||||
}, 500);
|
||||
}
|
||||
</script>
|
||||
|
||||
<title>Main Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<body onload="fadeIn()">
|
||||
<div class="container">
|
||||
<div class="main_block">
|
||||
<div class="header">
|
||||
@@ -28,7 +44,10 @@
|
||||
</div>
|
||||
<div class="content_buttons">
|
||||
<button id="ceo_info" name="menu_button">Get CEO Info</button>
|
||||
<button id="set_conf" name="menu_button">Set Server Conf File</button>
|
||||
<button id="users_info" name="menu_button">Get All Users</button>
|
||||
</div>
|
||||
<div class="content_buttons">
|
||||
<button id="reset_uc" name="menu_button">Reset UC</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
|
||||
|
Before Width: | Height: | Size: 298 KiB After Width: | Height: | Size: 298 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
@@ -26,7 +26,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
document.cookie = `email=${result.user.email};`;
|
||||
document.cookie = `name=${result.user.name};`;
|
||||
|
||||
window.location.href = '/';
|
||||
fadeOut('/');
|
||||
} else {
|
||||
alert('Incorrect credentials. Please try again.');
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const startUcButton = document.getElementById('start_uc');
|
||||
const stopUcButton = document.getElementById('stop_uc');
|
||||
const ceoInfoButton = document.getElementById('ceo_info');
|
||||
const setConfButton = document.getElementById('set_conf');
|
||||
const usersInfoButton = document.getElementById('users_info');
|
||||
const resetUcButton = document.getElementById('reset_uc');
|
||||
const logoutButton = document.getElementById('logout');
|
||||
|
||||
startUcButton.addEventListener('click', () => {
|
||||
@@ -63,11 +64,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('Ceo Info Button pressed');
|
||||
})
|
||||
|
||||
setConfButton.addEventListener('click', () => {
|
||||
usersInfoButton.addEventListener('click', () => {
|
||||
console.log('Users Info Button pressed');
|
||||
})
|
||||
|
||||
resetUcButton.addEventListener('click', () => {
|
||||
console.log('Set Conf Button pressed');
|
||||
})
|
||||
|
||||
logoutButton.addEventListener('click', function() {
|
||||
logoutButton.addEventListener('click', () => {
|
||||
console.log('Logout button was clicked');
|
||||
|
||||
const deleteCookie = (name) => {
|
||||
@@ -77,6 +82,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
deleteCookie('email');
|
||||
deleteCookie('name');
|
||||
|
||||
window.location.href = '/login';
|
||||
fadeOut('/login');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
const express = require('express');
|
||||
const path = require('path');
|
||||
const fs = require('fs').promises;
|
||||
const { fork } = require('child_process');
|
||||
const httpStatus = require('../helpers/status_codes');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
const backendPath = path.join(__dirname, '..', '..', 'backend');
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
@@ -15,44 +13,38 @@ router.get('/', (req, res) => {
|
||||
router.post('/server', async (req, res) => {
|
||||
const action = req.body.action;
|
||||
let serverProcess = req.app.get('serverProcess');
|
||||
const configFilePath = path.join(backendPath, 'config', 'config.json');
|
||||
|
||||
try {
|
||||
await fs.access(configFilePath);
|
||||
} catch (error) {
|
||||
if(action === 'start'){
|
||||
return res.status(httpStatus.BAD_REQUEST).send({ message: 'Config file is missing, cannot start server.' });
|
||||
}
|
||||
}
|
||||
|
||||
if (action === 'start') {
|
||||
if (serverProcess) {
|
||||
return res.status(httpStatus.BAD_REQUEST).send({message: 'Server is already running.'});
|
||||
}
|
||||
const serverPath = path.join(backendPath, 'src', 'app.js');
|
||||
serverProcess = fork(serverPath);
|
||||
serverProcess = fork(serverPath, [], { stdio: 'inherit' }); // Add stdio: 'inherit' to see child process logs in the parent process console
|
||||
|
||||
serverProcess.on('message', (msg) => {
|
||||
console.log('Message from server:', msg);
|
||||
});
|
||||
|
||||
serverProcess.on('close', (code) => {
|
||||
console.log(`Server process exited with code ${code}`);
|
||||
serverProcess.on('close', (code, signal) => {
|
||||
console.log(`Server process exited with code ${code} and signal ${signal}`);
|
||||
req.app.set('serverProcess', null);
|
||||
});
|
||||
|
||||
req.app.set('serverProcess', serverProcess); // Update the serverProcess in app
|
||||
req.app.set('serverProcess', serverProcess); // Update the serverProcess in the app
|
||||
res.status(httpStatus.OK).json({message: 'Server starting...'});
|
||||
} else if (action === 'stop') {
|
||||
if (!serverProcess) {
|
||||
return res.status(httpStatus.BAD_REQUEST).json({message: 'Server is not running.'});
|
||||
}
|
||||
serverProcess.kill();
|
||||
req.app.set('serverProcess', null);
|
||||
serverProcess.kill('SIGTERM');
|
||||
res.status(httpStatus.OK).json({message: 'Server stopping...'});
|
||||
} else {
|
||||
res.status(httpStatus.BAD_REQUEST).json({message: 'Invalid action.'});
|
||||
}
|
||||
});
|
||||
|
||||
router.post('ceo_credentials', (req, res) => {
|
||||
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||