This commit is contained in:
newtbot 2024-01-05 19:42:02 +08:00
parent b978f07867
commit a9912d4ddc
17 changed files with 628 additions and 353 deletions

View File

@ -1,77 +0,0 @@
"use strict";
const { Sequelize, DataTypes } = require("sequelize");
const { sequelize } = require("../mySQL");
const IoTModel = sequelize.define("iot-data",{
id: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true,
},
psiData: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
humidityData: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
o3Data: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
no2Data: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
so2Data: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
coData: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
temperatureData: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
windspeedData: {
type: DataTypes.STRING,
allowNull: false,
length: 8,
},
currentTime: {
type: DataTypes.STRING,
allowNull: false,
length: 20,
},
regionData: {
type: DataTypes.STRING,
allowNull: false,
length: 10,
},
createdAt: {
type: DataTypes.DATE,
allowNull: true,
},
updatedAt: {
type: DataTypes.DATE,
allowNull: true,
},
},
{
timestamps: true,
}
);
module.exports = { IoTModel };

View File

@ -5,7 +5,7 @@ const { locationModel } = require("./locationModel");
const { sensorModel } = require("./sensorModel"); const { sensorModel } = require("./sensorModel");
const { isJson } = require("../../Web-Server/functions/validateData"); const { isJson } = require("../../Web-Server/functions/validateData");
//sequelize.sync(); sequelize.sync();
const sensorDataModel = sequelize.define( const sensorDataModel = sequelize.define(
"sensorData", "sensorData",
{ {
@ -20,7 +20,7 @@ const sensorDataModel = sequelize.define(
notEmpty: true, notEmpty: true,
}, },
}, },
id_sensor: { sensorid: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
length: 100, length: 100,
@ -34,7 +34,7 @@ const sensorDataModel = sequelize.define(
notEmpty: true, notEmpty: true,
}, },
}, },
id_location: { locationid: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: false, allowNull: false,
length: 100, length: 100,
@ -48,7 +48,7 @@ const sensorDataModel = sequelize.define(
notEmpty: true, notEmpty: true,
}, },
}, },
sensordata: { measurement: {
type: DataTypes.JSON, type: DataTypes.JSON,
allowNull: false, allowNull: false,
validate: { validate: {

View File

@ -23,7 +23,7 @@ const sensorModel = sequelize.define(
isNumeric: true, isNumeric: true,
}, },
}, },
sensorname: { name: {
type: DataTypes.STRING, type: DataTypes.STRING,
allowNull: false, allowNull: false,
length: 10, length: 10,
@ -79,7 +79,7 @@ const sensorModel = sequelize.define(
}, },
}, },
}, },
location: { locationid: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
allowNull: true, allowNull: true,
length: 100, length: 100,

View File

@ -1,5 +1,4 @@
const { sequelize } = require("../../Database/mySql.js"); const { sequelize } = require("../../Database/mySql.js");
const { IoTModel } = require("../../Database/model/IoTModel.js");
const { locationModel } = require("../../Database/model/locationModel.js"); const { locationModel } = require("../../Database/model/locationModel.js");
const { sensorModel } = require("../../Database/model/sensorModel.js"); const { sensorModel } = require("../../Database/model/sensorModel.js");
const { sensorDataModel } = require("../../Database/model/sensorDataModel.js"); const { sensorDataModel } = require("../../Database/model/sensorDataModel.js");
@ -64,7 +63,7 @@ async function getSensor() {
async function addSensor(sensorname, added_by, mac_address , description, location) { async function addSensor(sensorname, added_by, mac_address , description, location) {
try { try {
const sensor = await sensorModel.create({ const sensor = await sensorModel.create({
sensorname: sensorname, name: sensorname,
added_by: added_by, added_by: added_by,
mac_address: mac_address, mac_address: mac_address,
description: description, description: description,
@ -80,7 +79,7 @@ async function updateSensor(id, sensorname, added_by, mac_address ,description,
//update by id //update by id
const sensor = await sensorModel.update( const sensor = await sensorModel.update(
{ {
sensorname: sensorname, name: sensorname,
added_by: added_by, added_by: added_by,
mac_address: mac_address, mac_address: mac_address,
description: description, description: description,
@ -143,9 +142,9 @@ async function addSensorData(id , id_sensor , id_location , sensordata){
} }
const sensorData = await sensorDataModel.create({ const sensorData = await sensorDataModel.create({
id: id, id: id,
id_sensor: id_sensor, sensorid: id_sensor,
id_location: id_location, locationid: id_location,
sensordata: sensordata, measurement: sensordata,
}); });
}catch(error){ }catch(error){
console.error(error); console.error(error);
@ -157,9 +156,9 @@ async function updateSensorData(id, id_sensor, id_location, sensordata) {
try { try {
const sensorData = await sensorDataModel.update( const sensorData = await sensorDataModel.update(
{ {
id_sensor: id_sensor, ensorid: id_sensor,
id_location: id_location, locationid: id_location,
sensordata: sensordata, measurement: sensordata,
}, },
{ {
where: { where: {

View File

@ -1,27 +1,5 @@
const { sequelize } = require("../../Database/mySql.js"); const { sequelize } = require("../../Database/mySql.js");
const { IoTModel } = require("../../Database/model/IoTModel.js"); const { api_log_Model } = require("../../Database/model/apiLogModel.js");
const { api_log_Model } = require("../../Database/model/apiLog.js");
function insertData(data) {
try {
//const latestData = await IoTModel.create({
IoTModel.create({
psiData: data.psi,
humidityData: data.humidity,
o3Data: data.o3,
no2Data: data.no2,
so2Data: data.so2,
coData: data.co,
temperatureData: data.temperature,
windspeedData: data.windspeed,
currentTime: data.time,
regionData: data.region,
});
}
catch (error) {
console.error(error);
}
}
async function insertLogData(log){ async function insertLogData(log){
try{ try{
@ -43,7 +21,7 @@ async function insertLogData(log){
} }
module.exports = { insertData , insertLogData }; module.exports = { insertLogData };

View File

@ -20,11 +20,11 @@ router.post("/new", async (req, res, next) => {
description: "system generated location", description: "system generated location",
}); });
await sensorModel.create({ await sensorModel.create({
sensorname: `AQI-${Math.floor(Math.random()*898)+101}`, name: `AQI-${Math.floor(Math.random()*898)+101}`,
added_by: "system", added_by: "system",
mac_address: `${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}`, mac_address: `${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}-${Math.floor(Math.random()*256).toString(16).padStart(2, '0')}`,
description: "system generated sensor", description: "system generated sensor",
location: location.id locationid: location.id
}); });
} }

View File

@ -5,40 +5,45 @@ const { sensorDataModel } = require("../../Database/model/sensorDataModel.js");
const express = require("express"); const express = require("express");
const router = express.Router(); const router = express.Router();
var moment = require("moment");
async function seedSensorData(seedOptions) { async function seedSensorData(seedOptions) {
//2024-01-01 18:48:04 seedOptions.endDate = new Date(seedOptions.endDate) || Date.now();
seedOptions.endDate = seedOptions.endDate || Date.now(); seedOptions.interval = seedOptions.interval || 15; //15 minutes
seedOptions.interval = seedOptions.interval || 150000; //15 minutes seedOptions.sensorid = seedOptions.sensorid || (await sensorModel.findAll()).map((i) => i.id);
seedOptions.sensorid = seedOptions.sensorid || (await sensorModel.findAll()).map((i) => i.id); seedOptions.seedData = seedOptions.seedData || {};
seedOptions.seedData = seedOptions.seedData || {};
let rows = []
for (let sensorId of seedOptions.sensorid) { let rows = [];
let sensor = await sensorModel.findByPk(sensorId)
let locationID = sensor.location_id;
let currentRow = firstDataRow(seedOptions.startDate , sensorId, locationID);
rows.push(currentRow);
while (currentRow.createdAt < seedOptions.endDate) {
currentRow = nextDataRow(currentRow, seedOptions.interval);
rows.push(currentRow);
}
}
//await sensorDataModel.bulkCreate(rows) for (let sensorId of seedOptions.sensorid) {
console.log(rows); let sensor = await sensorModel.findByPk(sensorId);
let locationId = sensor.locationid;
let currentRow = firstDataRow(seedOptions.startDate, sensorId, locationId);
rows.push(currentRow);
while (currentRow.createdAt <= seedOptions.endDate) {
currentRow = nextDataRow(currentRow, seedOptions.interval);
rows.push(currentRow);
}
}
await sensorDataModel.bulkCreate(rows)
//console.log(rows);
}
function convertDateToUTC(startDate) {
let date = new Date(startDate);
date = moment(date).utc().toDate();
//return as object
return date;
} }
//populate first row of sensordata model with random data from seedData //populate first row of sensordata model with random data from seedData
function firstDataRow(startDate , sensorId, locationID) { function firstDataRow(startDate, sensorId, locationId) {
console.log(startDate);
console.log(locationID);
return { return {
sensorid: sensorId, sensorid: sensorId,
locationid: locationID, locationid: locationId,
sensordata: { measurement: {
//console.log(Math.floor(Math.random() * 30) + 5) //console.log(Math.floor(Math.random() * 30) + 5)
psi: Math.floor(Math.random() * 30) + 5, psi: Math.floor(Math.random() * 30) + 5,
humidity: Math.floor(Math.random() * (90 - 80 + 1) + 80), humidity: Math.floor(Math.random() * (90 - 80 + 1) + 80),
@ -49,57 +54,37 @@ function firstDataRow(startDate , sensorId, locationID) {
temperature: Math.floor(Math.random() * (30 - 23 + 1) + 25), temperature: Math.floor(Math.random() * (30 - 23 + 1) + 25),
windspeed: Math.floor(Math.random() * (10 - 1 + 1) + 1), windspeed: Math.floor(Math.random() * (10 - 1 + 1) + 1),
}, },
createdAt: startDate, createdAt: convertDateToUTC(startDate),
}; };
} }
function numberWithinTenPercent(inputNumber) {
// Calculate the range for 10% of the input number
const range = 0.1 * inputNumber;
// Generate a random number within the range (-10% to +10%)
const randomOffset = Math.random() * range * 2 - range;
// Calculate the new number within the +/- 10% range
const newNumber = inputNumber + randomOffset;
return newNumber;
}
function nextDataRow(currentRow, interval) { function nextDataRow(currentRow, interval) {
return { return {
sensorid: currentRow.sensorid, sensorid: currentRow.sensorid,
locationid: currentRow.locationid, locationid: currentRow.locationid,
sensordata: { measurement: {
psi: numberWithinTenPercent(currentRow.sensordata.psi), psi: numberWithinPercent(currentRow.measurement.psi),
humidity: numberWithinTenPercent(currentRow.sensordata.humidity), humidity: Math.floor(Math.random() * (90 - 80 + 1) + 80),
o3: numberWithinTenPercent(currentRow.sensordata.o3), o3: Math.floor(Math.random() * (100 - 20 + 1) + 30),
no2: numberWithinTenPercent(currentRow.sensordata.no2), no2: numberWithinPercent(currentRow.measurement.no2),
so2: numberWithinTenPercent(currentRow.sensordata.so2), so2: numberWithinPercent(currentRow.measurement.so2),
co: numberWithinTenPercent(currentRow.sensordata.co), co: Math.floor(Math.random() * 25 - 0.5),
temperature: numberWithinTenPercent(currentRow.sensordata.temperatue), temperature: Math.floor(Math.random() * (30 - 23 + 1) + 25),
windspeed: numberWithinTenPercent(currentRow.sensordata.windspeed), windspeed: Math.floor(Math.random() * (10 - 1 + 1) + 1),
}, },
//convert 10-10-2020 to utc time createdAt: moment(currentRow.createdAt).add(interval, "m").toDate(),
/* };
const createdAtString = 'Sat Oct 10 2020 00:00:00 GMT+0800 (Singapore Standard Time)';
const createdAtDateObject = new Date(createdAtString);
// Add 150000 milliseconds
const updatedTimestamp = createdAtDateObject.getTime() + 150000;
// Create a new Date object with the updated timestamp
const updatedDateObject = new Date(updatedTimestamp);
console.log(updatedDateObject);
*/
createdAt: new Date (currentRow.createdAt).getTime() + interval,
};
} }
function numberWithinPercent(inputNumber) {
const range = inputNumber * 0.003;
const randomOffset = Math.random() * range;
const newNumber = inputNumber + randomOffset;
return Math.floor(newNumber);
}
//add seed //add seed
router.post("/new", async (req, res, next) => { router.post("/new", async (req, res, next) => {
@ -107,7 +92,7 @@ router.post("/new", async (req, res, next) => {
const seedOptions = req.body; const seedOptions = req.body;
console.log(seedOptions); console.log(seedOptions);
seedSensorData(seedOptions); seedSensorData(seedOptions);
res.status(200)
} catch (error) { } catch (error) {
console.error(error); console.error(error);
next(error); next(error);

View File

@ -26,7 +26,7 @@ router.use('/sensor', require('./sensor'))
//sensor data route //sensor data route
router.use('/sensor-data', require('./sensorData')); router.use('/sensor-data', require('./sensorData'));
router.use('/latest-data', require('./latest-data'));

View File

@ -1,23 +0,0 @@
const { sequelize } = require("../../Database/mySql.js");
const { IoTModel } = require("../../Database/model/IoTModel.js");
const { getLatestData } = require("../functions/apiDatabase.js");
const express = require('express');
const router = express.Router();
router.get('/', async (req, res) => {
try {
const data = await getLatestData();
if (data === null) {
res.status(404).send("No data found");
} else {
res.status(200).send(data);
}
} catch (error) {
console.error(error);
res.status(500).send('Internal Server Error');
}
});
// Export the router
module.exports = router;

12
api.MD
View File

@ -91,17 +91,17 @@ curl localhost/api/v0/sensor-data/update -H "Content-Type: application/json" -X
curl localhost/api/v0/sensor-data/delete -X DELETE -H "Content-Type: application/json" -d '{"id": "3" }' curl localhost/api/v0/sensor-data/delete -X DELETE -H "Content-Type: application/json" -d '{"id": "3" }'
//seed //seed
curl localhost/api/seed/v0/seed/new -H "Content-Type: application/json" -X POST -d '{"mockLocation": ["test", "test123"]}' curl localhost/api/seed/v0/seed/new -H "Content-Type: application/json" -X POST -d '{"mockLocation": ["Ang Mo Kio", "Bishan" , "Tampines" , "Jurong" , "Marine Parade" , "Woodlands "]}'
//router.use('/seedSensorData ', require('./seedSensorData.js')); //router.use('/seedSensorData ', require('./seedSensorData.js'));
//seed //seed
curl localhost/api/seed/v0/seedSensorData/new -H "Content-Type: application/json" -X POST -d '{ curl localhost/api/seed/v0/seedSensorData/new -H "Content-Type: application/json" -X POST -d '{
"startDate": "10-10-2020", "startDate": "2023-01-01T16:00:00.000Z",
"endDate": "10-12-2020", "endDate": "2023-02-01T16:00:00.000Z",
"interval": "150000", "interval": "15",
"sensorid": ["1", "4"], "sensorid": ["1", "2" , "3" , "4" , "5" , "6"],
"locationid": ["11", "12"], "locationid": ["1", "2" , "3" , "4" , "5" , "6"],
"seedData": { "seedData": {
"psi": "30", "psi": "30",
"humidity": "15%", "humidity": "15%",

461
package-lock.json generated
View File

@ -15,13 +15,16 @@
"ejs": "^3.1.9", "ejs": "^3.1.9",
"express": "^4.18.2", "express": "^4.18.2",
"express-session": "^1.17.3", "express-session": "^1.17.3",
"express-validator": "^7.0.1",
"helmet": "^7.1.0", "helmet": "^7.1.0",
"moment": "^2.30.1",
"mqtt": "^5.3.3", "mqtt": "^5.3.3",
"mysql2": "^3.6.5", "mysql2": "^3.6.5",
"nodemailer": "^6.9.7", "nodemailer": "^6.9.7",
"otp-generator": "^4.0.1", "otp-generator": "^4.0.1",
"otplib": "^12.0.1", "otplib": "^12.0.1",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
"sanitize-html": "^2.11.0",
"sequelize": "^6.35.2", "sequelize": "^6.35.2",
"validator": "^13.11.0" "validator": "^13.11.0"
} }
@ -495,6 +498,9 @@
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"dependencies": { "dependencies": {
"safe-buffer": "5.2.1" "safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
} }
}, },
"node_modules/content-disposition/node_modules/safe-buffer": { "node_modules/content-disposition/node_modules/safe-buffer": {
@ -561,12 +567,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"deepmerge": { "node_modules/deepmerge": {
"version": "4.3.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"engines": {
"node": ">=0.10.0"
}
}, },
"define-data-property": { "node_modules/define-data-property": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
"integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
@ -622,40 +631,58 @@
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz", "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==" "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
}, },
"dom-serializer": { "node_modules/dom-serializer": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": { "dependencies": {
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.2", "domhandler": "^5.0.2",
"entities": "^4.2.0" "entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
} }
}, },
"domelementtype": { "node_modules/domelementtype": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
}, },
"domhandler": { "node_modules/domhandler": {
"version": "5.0.3", "version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": { "dependencies": {
"domelementtype": "^2.3.0" "domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
} }
}, },
"domutils": { "node_modules/domutils": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"requires": { "dependencies": {
"dom-serializer": "^2.0.0", "dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.3" "domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
} }
}, },
"dotenv": { "node_modules/dotenv": {
"version": "16.3.1", "version": "16.3.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz",
"integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==",
@ -708,22 +735,34 @@
"node": ">= 0.8" "node": ">= 0.8"
} }
}, },
"entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
}, },
"escape-html": { "node_modules/escape-html": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
}, },
"escape-string-regexp": { "node_modules/escape-string-regexp": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
}, },
"etag": { "node_modules/etag": {
"version": "1.8.1", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
@ -784,50 +823,8 @@
"utils-merge": "1.0.1", "utils-merge": "1.0.1",
"vary": "~1.1.2" "vary": "~1.1.2"
}, },
"dependencies": { "engines": {
"body-parser": { "node": ">= 0.10.0"
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"requires": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
}
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"requires": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
}
} }
}, },
"node_modules/express-session": { "node_modules/express-session": {
@ -848,16 +845,140 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"express-validator": { "node_modules/express-session/node_modules/cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
"integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/express-session/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/express-session/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/express-session/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/express-validator": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz", "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-7.0.1.tgz",
"integrity": "sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA==", "integrity": "sha512-oB+z9QOzQIE8FnlINqyIFA8eIckahC6qc8KtqLdLJcU3/phVyuhXH3bA4qzcrhme+1RYaCSwrq+TlZ/kAKIARA==",
"requires": { "dependencies": {
"lodash": "^4.17.21", "lodash": "^4.17.21",
"validator": "^13.9.0" "validator": "^13.9.0"
},
"engines": {
"node": ">= 8.0.0"
} }
}, },
"filelist": { "node_modules/express/node_modules/body-parser": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
"integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/express/node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/express/node_modules/raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
"integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/express/node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/fast-unique-numbers": {
"version": "8.0.12",
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.12.tgz",
"integrity": "sha512-Z4AJueNDnuC/sLxeQqrHP4zgqcBIeQQLbQ0hEx1a7m6Wf7ERrdAyR7CkGfoEFWm9Qla7dpLt0eWPyiO18gqj0A==",
"dependencies": {
"@babel/runtime": "^7.23.5",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=16.1.0"
}
},
"node_modules/filelist": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
@ -1105,18 +1226,84 @@
"node": ">= 0.4" "node": ">= 0.4"
} }
}, },
"htmlparser2": { "node_modules/helmet": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz",
"integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==",
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/help-me": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/help-me/-/help-me-4.2.0.tgz",
"integrity": "sha512-TAOnTB8Tz5Dw8penUuzHVrKNKlCIbwwbHnXraNJxPwf8LRtE2HlM84RYuezMFcwOJmoYOCWVDyJ8TQGxn9PgxA==",
"dependencies": {
"glob": "^8.0.0",
"readable-stream": "^3.6.0"
}
},
"node_modules/help-me/node_modules/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^5.0.1",
"once": "^1.3.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/help-me/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=10"
}
},
"node_modules/help-me/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/htmlparser2": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"requires": { "funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.3.0", "domelementtype": "^2.3.0",
"domhandler": "^5.0.3", "domhandler": "^5.0.3",
"domutils": "^3.0.1", "domutils": "^3.0.1",
"entities": "^4.4.0" "entities": "^4.4.0"
} }
}, },
"http-errors": { "node_modules/http-errors": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
@ -1211,12 +1398,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"is-plain-object": { "node_modules/is-plain-object": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
}, },
"is-property": { "node_modules/is-property": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
"integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="
@ -1423,9 +1613,9 @@
} }
}, },
"node_modules/moment": { "node_modules/moment": {
"version": "2.29.4", "version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"engines": { "engines": {
"node": "*" "node": "*"
} }
@ -1544,12 +1734,32 @@
"node": ">=12.0.0" "node": ">=12.0.0"
} }
}, },
"nanoid": { "node_modules/named-placeholders/node_modules/lru-cache": {
"version": "7.18.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
"engines": {
"node": ">=12"
}
},
"node_modules/nanoid": {
"version": "3.3.7", "version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
}, },
"negotiator": { "node_modules/negotiator": {
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
@ -1717,12 +1927,12 @@
"node": ">=6" "node": ">=6"
} }
}, },
"parse-srcset": { "node_modules/parse-srcset": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz", "resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==" "integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
}, },
"parseurl": { "node_modules/parseurl": {
"version": "1.3.3", "version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
@ -1756,12 +1966,12 @@
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz",
"integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA=="
}, },
"picocolors": { "node_modules/picocolors": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
}, },
"pngjs": { "node_modules/pngjs": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
@ -1769,17 +1979,47 @@
"node": ">=10.13.0" "node": ">=10.13.0"
} }
}, },
"postcss": { "node_modules/postcss": {
"version": "8.4.32", "version": "8.4.33",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
"integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==", "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
"requires": { "funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"nanoid": "^3.3.7", "nanoid": "^3.3.7",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
"source-map-js": "^1.0.2" "source-map-js": "^1.0.2"
},
"engines": {
"node": "^10 || ^12 || >=14"
} }
}, },
"proxy-addr": { "node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"node_modules/proxy-addr": {
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
@ -1914,21 +2154,21 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}, },
"safer-buffer": { "node_modules/safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
}, },
"sanitize-html": { "node_modules/sanitize-html": {
"version": "2.11.0", "version": "2.11.0",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.11.0.tgz",
"integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==", "integrity": "sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA==",
"requires": { "dependencies": {
"deepmerge": "^4.2.2", "deepmerge": "^4.2.2",
"escape-string-regexp": "^4.0.0", "escape-string-regexp": "^4.0.0",
"htmlparser2": "^8.0.0", "htmlparser2": "^8.0.0",
@ -1937,7 +2177,7 @@
"postcss": "^8.3.11" "postcss": "^8.3.11"
} }
}, },
"semver": { "node_modules/semver": {
"version": "7.5.4", "version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
@ -2122,29 +2362,20 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
}, },
"source-map-js": { "node_modules/source-map-js": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"engines": {
"node": ">=0.10.0"
}
}, },
"sqlstring": { "node_modules/split2": {
"version": "2.3.3", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
"integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==" "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
}, "engines": {
"statuses": { "node": ">= 10.x"
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
},
"string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
} }
}, },
"node_modules/sqlstring": { "node_modules/sqlstring": {

View File

@ -25,6 +25,7 @@
"express-session": "^1.17.3", "express-session": "^1.17.3",
"express-validator": "^7.0.1", "express-validator": "^7.0.1",
"helmet": "^7.1.0", "helmet": "^7.1.0",
"moment": "^2.30.1",
"mqtt": "^5.3.3", "mqtt": "^5.3.3",
"mysql2": "^3.6.5", "mysql2": "^3.6.5",
"nodemailer": "^6.9.7", "nodemailer": "^6.9.7",

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,3 @@
CREATE DATABASE IF NOT EXISTS `eco_saver` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `eco_saver`;
-- MySQL dump 10.13 Distrib 8.0.34, for Win64 (x86_64) -- MySQL dump 10.13 Distrib 8.0.34, for Win64 (x86_64)
-- --
-- Host: mpsqldatabase.mysql.database.azure.com Database: eco_saver -- Host: mpsqldatabase.mysql.database.azure.com Database: eco_saver
@ -18,34 +16,32 @@ USE `eco_saver`;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- --
-- Table structure for table `api-logs` -- Table structure for table `locations`
-- --
DROP TABLE IF EXISTS `api-logs`; DROP TABLE IF EXISTS `locations`;
/*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */; /*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `api-logs` ( CREATE TABLE `locations` (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`ip` varchar(45) NOT NULL, `name` varchar(255) NOT NULL,
`time` varchar(30) NOT NULL, `added_by` varchar(255) NOT NULL,
`method` varchar(10) NOT NULL, `description` varchar(255) DEFAULT NULL,
`host` varchar(45) NOT NULL, `createdAt` datetime DEFAULT NULL,
`statusCode` varchar(10) NOT NULL, `updatedAt` datetime DEFAULT NULL,
`responsesize` varchar(10) NOT NULL, PRIMARY KEY (`id`),
`referrer` varchar(45) NOT NULL, UNIQUE KEY `name` (`name`)
`useragent` varchar(150) NOT NULL, ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
-- Dumping data for table `api-logs` -- Dumping data for table `locations`
-- --
LOCK TABLES `api-logs` WRITE; LOCK TABLES `locations` WRITE;
/*!40000 ALTER TABLE `api-logs` DISABLE KEYS */; /*!40000 ALTER TABLE `locations` DISABLE KEYS */;
INSERT INTO `api-logs` VALUES (1,'::1','Fri, 29 Dec 2023 09:21:29 GMT','GET','http://localhost/api/test','200','0','none','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'),(2,'::1','Fri, 29 Dec 2023 09:21:49 GMT','GET','http://localhost/api/test','200','0','none','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); INSERT INTO `locations` VALUES (1,'Ang Mo Kio','system','system generated location','2024-01-05 10:59:05','2024-01-05 10:59:05'),(2,'Bishan','system','system generated location','2024-01-05 10:59:06','2024-01-05 10:59:06'),(3,'Tampines','system','system generated location','2024-01-05 10:59:07','2024-01-05 10:59:07'),(4,'Jurong','system','system generated location','2024-01-05 10:59:07','2024-01-05 10:59:07'),(5,'Marine Parade','system','system generated location','2024-01-05 10:59:08','2024-01-05 10:59:08'),(6,'Woodlands ','system','system generated location','2024-01-05 10:59:08','2024-01-05 10:59:08');
/*!40000 ALTER TABLE `api-logs` ENABLE KEYS */; /*!40000 ALTER TABLE `locations` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -57,4 +53,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2023-12-29 17:25:40 -- Dump completed on 2024-01-05 19:38:57

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,62 @@
-- MySQL dump 10.13 Distrib 8.0.34, for Win64 (x86_64)
--
-- Host: mpsqldatabase.mysql.database.azure.com Database: eco_saver
-- ------------------------------------------------------
-- Server version 8.0.34
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `sensors`
--
DROP TABLE IF EXISTS `sensors`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `sensors` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`added_by` varchar(255) NOT NULL,
`mac_address` varchar(255) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`locationid` int DEFAULT NULL,
`createdAt` datetime DEFAULT NULL,
`updatedAt` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `name` (`name`),
UNIQUE KEY `mac_address` (`mac_address`),
KEY `locationid` (`locationid`),
CONSTRAINT `sensors_ibfk_1` FOREIGN KEY (`locationid`) REFERENCES `locations` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `sensors`
--
LOCK TABLES `sensors` WRITE;
/*!40000 ALTER TABLE `sensors` DISABLE KEYS */;
INSERT INTO `sensors` VALUES (1,'AQI-586','system','55-1a-c4-0e-7a-80','system generated sensor',1,'2024-01-05 10:59:06','2024-01-05 10:59:06'),(2,'AQI-852','system','b9-b9-68-83-be-bd','system generated sensor',2,'2024-01-05 10:59:07','2024-01-05 10:59:07'),(3,'AQI-242','system','a2-93-fd-3d-34-b9','system generated sensor',3,'2024-01-05 10:59:07','2024-01-05 10:59:07'),(4,'AQI-635','system','1a-3a-69-c8-00-77','system generated sensor',4,'2024-01-05 10:59:08','2024-01-05 10:59:08'),(5,'AQI-683','system','8e-d8-be-5c-46-3a','system generated sensor',5,'2024-01-05 10:59:08','2024-01-05 10:59:08'),(6,'AQI-519','system','f7-a7-3f-9b-1f-1c','system generated sensor',6,'2024-01-05 10:59:09','2024-01-05 10:59:09');
/*!40000 ALTER TABLE `sensors` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2024-01-05 19:39:03