update on sensor

This commit is contained in:
BIG2EYEZ 2024-01-23 21:24:12 +08:00
parent 3dbfe5733b
commit 940d40ed38
7 changed files with 1144 additions and 2700 deletions

View File

@ -9,8 +9,9 @@ const nodemailer = require("nodemailer");
const otpGenerator = require('otp-generator'); const otpGenerator = require('otp-generator');
const { body, validationResult } = require('express-validator'); const { body, validationResult } = require('express-validator');
const validator = require('validator'); const validator = require('validator');
const { format } = require('date-fns'); const axios = require('axios');
const { format } = require('date-fns');
const { Sequelize } = require('sequelize'); const { Sequelize } = require('sequelize');
const { transporter } = require("./modules/nodeMailer"); const { transporter } = require("./modules/nodeMailer");
const { sequelize, User } = require("./modules/mysql"); const { sequelize, User } = require("./modules/mysql");
@ -801,22 +802,139 @@ app.get('/api/getLogs', async (req, res) => {
app.get("/locations", isAuthenticated, async (req, res) => { app.get("/locations", isAuthenticated, async (req, res) => {
try { try {
// Render the inusers page with JSON data // Fetch data using Axios
res.render("locations"); const response = await axios.get(process.env.API_ALLLOCATION);
const locationsData = response.data;
// Render the "locations" page with the fetched JSON data
res.render("locations", { locationsData, csrfToken: csrfTokenSession});
} catch (error) { } catch (error) {
console.error("Error fetching all users:", error); console.error("Error fetching locations:", error);
res.status(500).send("Internal Server Error"); res.status(500).send("Internal Server Error");
} }
}); });
const locationValidation = [
body('name').trim().isLength({ min: 1 }).withMessage('Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('description').trim().escape(),
];
app.post('/location/new', locationValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { name, added_by, description } = req.body;
const preparedData = {name, added_by, description};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_NEWLOCATION, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new location submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
const locationValidationUpdate = [
body('id').trim().escape(),
body('name').trim().isLength({ min: 1 }).withMessage('Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('description').trim().escape(),
];
app.post('/location/update', locationValidationUpdate, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { id, name, added_by, description } = req.body;
const preparedData = {id, name, added_by, description};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_UPDATELOCATION, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new location submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.get("/sensors", isAuthenticated, async (req, res) => { app.get("/sensors", isAuthenticated, async (req, res) => {
try { try {
// Render the inusers page with JSON data // Render the inusers page with JSON data
res.render("sensors"); const response = await axios.get(process.env.API_ALLLOCATION);
const locationsData = response.data;
const response2 = await axios.get(process.env.API_ALLSENSOR);
const sensorData = response2.data;
res.render("sensors",{locationsData, sensorData, csrfToken: csrfTokenSession});
} catch (error) { } catch (error) {
console.error("Error fetching all users:", error); console.error("Error:", error);
res.status(500).send("Internal Server Error"); res.status(500).send("Internal Server Error");
} }
}); });
const sensorValidation = [
body('id').trim().escape(),
body('sensorname').trim().isLength({ min: 1 }).withMessage('Sensor Name must not be empty').escape(),
body('added_by').trim().isLength({ min: 1 }).withMessage('Added by must not be empty').escape(),
body('macAddress').custom(value => {
const macAddressRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
if (!macAddressRegex.test(value)) {
throw new Error('Invalid MAC address format');
}
return true;
}).withMessage('Invalid MAC address format').escape(),
body('description').trim().escape(),
body('location').trim().escape()
];
app.post('sensor/new',sensorValidation, async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const sessionTokencookie = req.cookies['sessionToken'];
const user = await User.findOne({ where: { sessionid: sessionTokencookie } });
if (!user) {
return res.status(403).json({ error: 'Invalid sessionToken' });
}
const submittedCSRFToken = req.body.csrf_token;
if (!csrfTokenSession || submittedCSRFToken !== csrfTokenSession) {
return res.status(403).json({ error: 'CSRF token mismatch' });
}
const { id, sensorname, added_by, macAddress, description, location} = req.body;
const preparedData = {id, sensorname, added_by, macAddress, description, location};
// Make a POST request with the sanitized data using Axios
const axiosResponse = await axios.post(process.env.API_NEWSENSOR, preparedData);
// Send the Axios response back to the client
res.status(axiosResponse.status).json(axiosResponse.data);
} catch (error) {
console.error('Error handling new sensor submission:', error);
res.status(500).json({ message: 'Internal Server Error' });
}
});
app.use(express.static("views")); app.use(express.static("views"));
app.listen(PORT, () => { app.listen(PORT, () => {

View File

@ -20,78 +20,48 @@ $(document).ready(function () {
let locationArray = []; let locationArray = [];
$(document).ready(function () { function populateTableAndArray(data) {
// Function to fetch and display locations const tableBody = document.getElementById("locationTableBody");
function fetchLocations() {
// Make a GET request to retrieve all locations
fetch('/api/v0/location', {
method: 'GET',
}) // Clear existing rows and array
.then(response => { tableBody.innerHTML = "";
if (response.ok) { locationArray.length = 0;
return response.json();
} else {
throw new Error(`HTTP error! Status: ${response.status}`);
}
})
.then(locations => {
// Clear existing table rows
$('#locationTableBody').empty();
locationArray = [];
// Populate the table with location information // Loop through the data and create table rows
locations.forEach(location => { data.forEach(location => {
locationArray.push({ const row = document.createElement("tr");
id: location.id, row.innerHTML = `
name: location.name, <td>${location.id}</td>
description: location.description <td>${location.location}</td>
}); <td>${location.description}</td>
`;
tableBody.appendChild(row);
$('#locationTableBody').append(` // Push location data to the array
<tr> locationArray.push(location);
<td>${location.id}</td> });
<td>${location.name}</td> }
<td>${location.description}</td> populateTableAndArray(locationsData);
</tr> console.log(locationArray);
`);
});
})
.catch(error => {
console.error('Error fetching locations:', error);
// Handle error as needed
});
}
// Call the fetchLocations function when the page loads
fetchLocations();
});
$('#locationForm').on('submit', function (e) { $('#locationForm').on('submit', function (e) {
e.preventDefault(); e.preventDefault();
const location= DOMPurify.sanitize($('#location').val().trim()); const location= $('#location').val();
// Validate if the sanitized value is empty
if (location === '') {
alert('Location name cannot be empty');
return;
}
const user = req.session.jobTitle const user = req.session.jobTitle
const description= DOMPurify.sanitize($('#description').val().trim()); const description= $('#description').val();
// Validate if the sanitized value is empty const csrf_token = $('#userForm input[name="csrf_token"]').val();
if (description === '') {
alert('description name cannot be empty'); fetch('/location/new', {
return;
}
fetch('/api/v0/location/new', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': '2-eb0c08b0-250a-4249-8a87-11141e2ff8fb'
}, },
body: JSON.stringify({ body: JSON.stringify({
name: location, name: location,
added_by: user, added_by: user,
description: description description: description,
csrf_token: csrf_token
}), }),
}) })
.then(response => { .then(response => {
@ -127,37 +97,23 @@ $('#locationForm').on('submit', function (e) {
$('#updateForm').on('submit', function (e) { $('#updateForm').on('submit', function (e) {
e.preventDefault(); e.preventDefault();
const selectedLocationId = DOMPurify.sanitize($('#locationDropdown').val().trim()); const selectedLocationId = $('#locationDropdown').val();
const location= $('#location').val();
// Validate if the selected location ID is empty
if (selectedLocationId === '') {
alert('Please select a location to update');
return;
}
const location= DOMPurify.sanitize($('#location').val().trim());
// Validate if the sanitized value is empty
if (location === '') {
alert('Location name cannot be empty');
return;
}
const user = req.session.jobTitle const user = req.session.jobTitle
const description= DOMPurify.sanitize($('#description').val().trim()); const description=$('#description').val();
// Validate if the sanitized value is empty const csrf_token = $('#userForm input[name="csrf_token"]').val();
if (description === '') {
alert('description name cannot be empty'); fetch('/location/update', {
return;
}
fetch('/api/v0/location/update', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
'Authorization': '1-1ec4ce9d-bcff-46c4-a023-c34171b9ca51'
}, },
body: JSON.stringify({ body: JSON.stringify({
id:selectedLocationId, id:selectedLocationId,
name: location, name: location,
added_by: user, added_by: user,
description: description description: description,
csrf_token: csrf_token
}), }),
}) })
.then(response => { .then(response => {

View File

@ -42,7 +42,7 @@
<div id="createLocationForm" class="location-creation-container custom-location-form" style="display: none;"> <div id="createLocationForm" class="location-creation-container custom-location-form" style="display: none;">
<h3>Add Location</h3> <h3>Add Location</h3>
<div class="content"> <div class="content">
<form action="/api/v0/location/new" id="locationForm" method="post"> <form action="/location/new" id="locationForm" method="post">
<div class="Location-details"> <div class="Location-details">
<div class="input-box"> <div class="input-box">
<span class="details">Location Name</span> <span class="details">Location Name</span>
@ -53,6 +53,7 @@
<input type="text" name="description" id="description" placeholder="Enter the description here" required> <input type="text" name="description" id="description" placeholder="Enter the description here" required>
</div> </div>
</div> </div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button"> <div class="button">
<input type="submit" value="submit"> <input type="submit" value="submit">
</div> </div>
@ -79,6 +80,7 @@
<input type="text" name="description" id="description" placeholder="Enter the description here" required> <input type="text" name="description" id="description" placeholder="Enter the description here" required>
</div> </div>
</div> </div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button"> <div class="button">
<input type="submit" value="submit"> <input type="submit" value="submit">
</div> </div>
@ -88,6 +90,9 @@
<footer> <footer>
Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com
</footer> </footer>
<script>
const locationsData = <%- JSON.stringify(locationsData) %>;
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.3/purify.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.3/purify.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="location.js"></script> <script src="location.js"></script>

View File

@ -10,126 +10,67 @@ $(document).ready(function () {
$('#additional-text4').show(); $('#additional-text4').show();
}); });
}); });
let locationsArray = []; function populateTableAndArray(data, locationsArray) {
const tableBody = document.getElementById("sensorTableBody");
// Clear existing rows and array
tableBody.innerHTML = "";
sensorArray.length = 0;
// Loop through the data and create table rows
data.forEach(sensor => {
const location = locationsArray.find(loc => loc.id === sensor.location);
// Function to fetch and store locations in the array const row = document.createElement("tr");
function fetchLocations() { row.innerHTML = `
// Make a GET request to retrieve all locations <td>${sensor.id}</td>
fetch('/api/v0/location', { <td>${sensor.sensorname}</td>
method: 'GET', <td>${sensor.added_by}</td>
}) <td>${sensor.description}</td>
.then(response => { <td>${location ? location.name : 'Unknown Location'}</td>
if (response.ok) { `;
return response.json(); tableBody.appendChild(row);
} else { // Push sensor data to the array
throw new Error(`HTTP error! Status: ${response.status}`); sensorArray.push(sensor);
} });
}) }
.then(locations => { // Assuming locationsArray is defined elsewhere in your code
// Reset the array populateTableAndArray(sensorData);
locationsArray = []; console.log(sensorArray);
// Populate the array with location information function populateLocationDropdown() {
locations.forEach(location => { const locationDropdown = document.getElementById('locationDropdown');
// Store in the array
locationsArray.push({
id: location.id,
location: location.name,
});
});
})
.catch(error => {
console.error('Error fetching locations:', error);
// Handle error as needed
});
}
// Call the fetchLocations function when the page loads
fetchLocations();
// Function to fetch sensor data and populate the table // Clear existing options
function fetchAndPopulateSensorTable() { locationDropdown.innerHTML = '';
// Fetch sensor data from the API
fetch('/api/v0/sensor', {
method: 'GET',
headers: {
'Authorization': '1-1ec4ce9d-bcff-46c4-a023-c34171b9ca51'
},
})
.then(response => response.json())
.then(sensorData => {
// Get the table body
const tableBody = document.getElementById('sensorTableBody');
// Clear existing rows // Add a default option
tableBody.innerHTML = ''; const defaultOption = document.createElement('option');
defaultOption.text = 'Select a Location';
defaultOption.value = '';
locationDropdown.add(defaultOption);
// Iterate through each sensor data // Add locations as options
sensorData.forEach(sensor => { locationsArray.forEach(location => {
// Find the corresponding location object const option = document.createElement('option');
const location = locationsArray.find(loc => loc.id === sensor.location); option.text = location.location;
option.value = location.id;
// Create a new row locationDropdown.add(option);
const row = tableBody.insertRow(); });
}
// Insert cells with sensor data populateLocationDropdown();
row.insertCell(0).textContent = sensor.id;
row.insertCell(1).textContent = sensor.sensorname;
row.insertCell(2).textContent = sensor.added_by;
row.insertCell(3).textContent = sensor.mac_address;
row.insertCell(4).textContent = sensor.description;
// Insert location cell with corresponding location name
const locationCell = row.insertCell(5);
locationCell.textContent = location ? location.location : 'Unknown';
});
})
.catch(error => {
console.error('Error fetching sensor data:', error);
});
}
// Call the function to fetch and populate the table
fetchAndPopulateSensorTable();
$('#sensorForm').on('submit', function (e) { $('#sensorForm').on('submit', function (e) {
e.preventDefault(); e.preventDefault();
// Sanitize sensor input const sensor = $('#sensor').val();
const sensor = DOMPurify.sanitize($('#sensor').val().trim()); const user = req.session.jobTitle;
// Validate if the sanitized value is empty const macAddress = $('#macAddress').val();
if (sensor === '') { const description = $('#description').val();
alert('Sensor name cannot be empty'); const location = $('#location').val();
return; const csrf_token = $('#userForm input[name="csrf_token"]').val();
}
// Sanitize user input (assuming req.session is available)
const user = DOMPurify.sanitize(req.session.jobTitle);
// Validate if the sanitized value is missing fetch('sensor/new', {
if (!user) {
alert('User information is missing');
return;
}
// Sanitize macAddress input
const macAddress = DOMPurify.sanitize($('#macAddress').val().trim());
// Validate macAddress format
const macAddressRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
if (!macAddressRegex.test(macAddress)) {
alert('Invalid MAC Address format');
return;
}
// Sanitize description input
const description = DOMPurify.sanitize($('#description').val().trim());
// Validate if the sanitized value is empty
if (description === '') {
alert('Description cannot be empty');
return;
}
const location = $('#location').val();
fetch('/api/v0/sensor/new', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json'
'Authorization': '2-eb0c08b0-250a-4249-8a87-11141e2ff8fb'
}, },
body: JSON.stringify({ body: JSON.stringify({
id: id, id: id,
@ -137,7 +78,8 @@ $('#sensorForm').on('submit', function (e) {
added_by: user, added_by: user,
mac_address: macAddress, mac_address: macAddress,
description: description, description: description,
location: location location: location,
csrf_token: csrf_token
}), }),
}) })
.then(response => { .then(response => {
@ -160,27 +102,3 @@ $('#sensorForm').on('submit', function (e) {
// Handle error as needed // Handle error as needed
}); });
}); });
function populateLocationDropdown() {
const locationDropdown = document.getElementById('locationDropdown');
// Clear existing options
locationDropdown.innerHTML = '';
// Add a default option
const defaultOption = document.createElement('option');
defaultOption.text = 'Select a Location';
defaultOption.value = '';
locationDropdown.add(defaultOption);
// Add locations as options
locationsArray.forEach(location => {
const option = document.createElement('option');
option.text = location.location;
option.value = location.id;
locationDropdown.add(option);
});
}
// Call the function to populate the dropdown when the page loads
populateLocationDropdown();

View File

@ -64,10 +64,10 @@
<div class="input-box"> <div class="input-box">
<span class="details">Location</span> <span class="details">Location</span>
<select name="location" id="locationDropdown" required> <select name="location" id="locationDropdown" required>
</select> </select>
</div> </div>
</div> </div>
<input type="hidden" name="csrf_token" value="<%= csrfToken %>">
<div class="button"> <div class="button">
<input type="submit" value="Submit"> <input type="submit" value="Submit">
</div> </div>
@ -88,6 +88,10 @@
Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com Any Issue faced, Please contact the administrator at 11111111 or ecosaverAdmin@gmail.com
</footer> </footer>
</body> </body>
<script>
const locationsArray = <%=-JSON.stringify(locationsData) %>;
const sensorArray = <%- JSON.stringify(sensorData) %>;
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.3/purify.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.3.3/purify.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="sensor.js"></script> <script src="sensor.js"></script>

3390
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
}, },
"homepage": "https://github.com/Newtbot/MP#readme", "homepage": "https://github.com/Newtbot/MP#readme",
"dependencies": { "dependencies": {
"axios": "^1.6.5",
"bcrypt": "^5.1.1", "bcrypt": "^5.1.1",
"body-parser": "^1.20.2", "body-parser": "^1.20.2",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",