From 4aea6a8e4c67a178858d607581956eba5bf03a25 Mon Sep 17 00:00:00 2001 From: newtbot Date: Wed, 24 Jan 2024 04:23:54 +0800 Subject: [PATCH] Update dependencies and fix file paths --- IoT-sensor/Database/locationModel.js | 1 - IoT-sensor/Database/sensorModel.js | 6 +- IoT-sensor/functions/dbFunctions.js | 4 +- IoT-sensor/index.js | 4 +- api.MD | 2 +- consumerWebsite/public/js/app.js | 42 ++++- consumerWebsite/views/index.ejs | 86 +++++---- consumerWebsite/views/logintop.ejs | 2 + consumerWebsite/views/top.ejs | 253 +++++++++++++-------------- package-lock.json | 56 ++++++ package.json | 2 + webserver/bin/www | 109 ++++++++++++ webserver/functions/Database.js | 10 +- webserver/index.js | 1 - webserver/modules/express.js | 19 +- webserver/modules/mqtt.js | 4 +- 16 files changed, 405 insertions(+), 196 deletions(-) create mode 100644 webserver/bin/www diff --git a/IoT-sensor/Database/locationModel.js b/IoT-sensor/Database/locationModel.js index 9163156..7bd55d2 100644 --- a/IoT-sensor/Database/locationModel.js +++ b/IoT-sensor/Database/locationModel.js @@ -1,7 +1,6 @@ "use strict"; const { Sequelize, DataTypes } = require("sequelize"); const { sequelize } = require("./mySQL"); -const { isAlphaNumericwithSpaces } = require('../../Web-Server/functions/validateData') //sequelize.sync(); const locationModel = sequelize.define( diff --git a/IoT-sensor/Database/sensorModel.js b/IoT-sensor/Database/sensorModel.js index bed1d9b..1de32af 100644 --- a/IoT-sensor/Database/sensorModel.js +++ b/IoT-sensor/Database/sensorModel.js @@ -2,11 +2,7 @@ const { Sequelize, DataTypes } = require("sequelize"); const { sequelize } = require("./mySQL"); const { locationModel } = require("./locationModel"); -const { - isAlphaNumericwithSpaces, - isAlphaNumericWithSpacesAndDash, - isMacAddress, -} = require("../../Web-Server/functions/validateData"); + //sequelize.sync(); const sensorModel = sequelize.define( diff --git a/IoT-sensor/functions/dbFunctions.js b/IoT-sensor/functions/dbFunctions.js index f03c5a9..83993ec 100644 --- a/IoT-sensor/functions/dbFunctions.js +++ b/IoT-sensor/functions/dbFunctions.js @@ -1,5 +1,5 @@ -const { locationModel } = require("../Database/locationModel"); -const { sensorModel } = require("../Database/sensorModel"); +const { locationModel } = require("../database/locationModel"); +const { sensorModel } = require("../database/sensorModel"); async function getLocation() { const location = locationModel.findAll({ diff --git a/IoT-sensor/index.js b/IoT-sensor/index.js index 728cb30..a5cfb75 100644 --- a/IoT-sensor/index.js +++ b/IoT-sensor/index.js @@ -27,9 +27,9 @@ client.on("error", (err) => { }); //every 15 minutes -setInterval(publishData, 900000); +//setInterval(publishData, 900000); //every 1 minute -//setInterval(publishData, 60000); +setInterval(publishData, 60000); diff --git a/api.MD b/api.MD index b655bed..de38469 100644 --- a/api.MD +++ b/api.MD @@ -174,4 +174,4 @@ http://localhost/api/v0/sensor-data/data?week=1&sensorid=1&locationid=1&page=2&p curl localhost/api/v0/user/register -H "Content-Type: application/json" -X POST -d '{"username": "testuser123", "password": "thisisthesystemuserpasswordnoob", "email": "testuser123@ecosaver.com", "address": "Nanyang Polytechnic 180 Ang Mo Kio Avenue 8 Singapore 569830", "phone": "12345678"}' -curl localhost/api/v0/apikey/new -H "Content-Type: application/json" -X POST -d '{"userid": "5", "permission": "canRead"}' +curl localhost:3000/api/v0/apikey/new -H "Content-Type: application/json" -X POST -d '{"userid": "5", "permission": "canRead"}' diff --git a/consumerWebsite/public/js/app.js b/consumerWebsite/public/js/app.js index 3d69ec5..eed6158 100644 --- a/consumerWebsite/public/js/app.js +++ b/consumerWebsite/public/js/app.js @@ -144,6 +144,33 @@ app.api = (function (app) { return { post: post, get: get, put: put, delete: remove }; })(app); +//socket.io +app.socket = (function (app) { + //need to replace with domain name of server when published + var socket = io("localhost", { + transports: ["websocket"], + 'Access-Control-Allow-Origin': 'http://localhost:3000', + }); + socket.on("disconnect", () => { + console.log("disconnected"); + }); + + socket.io.on("reconnect", () => { + console.log("reconnected"); + }); + socket.io.on("connect_error", (err) => { + console.log(err); + }); + return socket; +})(app); + +//sensor data +app.sensordata = (function (app) { + + +})(app); + + app.auth = (function (app) { var user = {}; function setToken(token) { @@ -154,18 +181,20 @@ app.auth = (function (app) { return localStorage.getItem("APIToken"); } - function isLoggedIn(callback) { if (getToken()) { return app.api.get("user/me", function (error, data) { if (!error) app.auth.user = data; //for navbar to show username - $.scope.getUsername.update(data); + if (!location.pathname === "/login") + { + $.scope.getUsername.update(data); + + } //for edit profile to show user details //if not in edit profile page, it will not show - if (location.pathname === "/profile") - { + if (location.pathname === "/profile") { $.scope.getUserDetails.update(data); } return callback(error, data); @@ -232,12 +261,9 @@ app.auth = (function (app) { logInRedirect, homeRedirect, profileRedirect, - //showUser, - //redirectIfLoggedIn, }; })(app); - app.user = (function (app) { //delete profile function deleteProfile() { @@ -250,12 +276,10 @@ app.user = (function (app) { }); } }); - } return { deleteProfile, }; - })(app); //ajax form submit and pass to api diff --git a/consumerWebsite/views/index.ejs b/consumerWebsite/views/index.ejs index 1dfaaa4..c31da5b 100644 --- a/consumerWebsite/views/index.ejs +++ b/consumerWebsite/views/index.ejs @@ -1,5 +1,11 @@ <%- include('top') %> +
@@ -47,43 +53,55 @@
-

Services

- -
-
-
-

Humidity

-
-

70% - 75%

+

Services

+ +
+
+
+

Air Quality Index

+
+

15 - 18 PSI

+
+
- +
+
+

Humidity

+
+

70% - 75%

+
+
-
-
-
-
-

Air Quality Index

-
-

15 - 18 PSI

+
+
+
+

Temperature

+
+

30° - 37°

+
+
- +
+
+

Another Category

+
+

values

+
+
-
-
-
-
-

Temperature

-
-

30° - 37°

-
- -
-
-
+
+
+
@@ -121,4 +139,4 @@

-<%- include('bot') %> + <%- include('bot') %> \ No newline at end of file diff --git a/consumerWebsite/views/logintop.ejs b/consumerWebsite/views/logintop.ejs index e5dc928..80f9355 100644 --- a/consumerWebsite/views/logintop.ejs +++ b/consumerWebsite/views/logintop.ejs @@ -26,6 +26,8 @@ + + diff --git a/consumerWebsite/views/top.ejs b/consumerWebsite/views/top.ejs index b3af246..276d928 100644 --- a/consumerWebsite/views/top.ejs +++ b/consumerWebsite/views/top.ejs @@ -1,144 +1,133 @@ - - - - - - - - - + + + + + + + + + + - - + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + - - + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8b75c59..391c6c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "bcrypt": "^5.1.1", "body-parser": "^1.20.2", "cookie-parser": "^1.4.6", + "cors": "^2.8.5", "csurf": "^1.11.0", "date-fns": "^3.2.0", "date-fns-tz": "^2.0.0", @@ -35,6 +36,7 @@ "sequelize": "^6.35.2", "sequelize-cli": "^6.6.2", "socket.io": "^4.7.4", + "socket.io-client": "^4.7.4", "validator": "^13.11.0" }, "devDependencies": { @@ -1227,6 +1229,38 @@ "node": ">=10.2.0" } }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/engine.io-parser": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz", @@ -3606,6 +3640,20 @@ } } }, + "node_modules/socket.io-client": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.4.tgz", + "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/socket.io-parser": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", @@ -4091,6 +4139,14 @@ } } }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", diff --git a/package.json b/package.json index 28f6318..45eb5ce 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "bcrypt": "^5.1.1", "body-parser": "^1.20.2", "cookie-parser": "^1.4.6", + "cors": "^2.8.5", "csurf": "^1.11.0", "date-fns": "^3.2.0", "date-fns-tz": "^2.0.0", @@ -43,6 +44,7 @@ "sequelize": "^6.35.2", "sequelize-cli": "^6.6.2", "socket.io": "^4.7.4", + "socket.io-client": "^4.7.4", "validator": "^13.11.0" }, "devDependencies": { diff --git a/webserver/bin/www b/webserver/bin/www new file mode 100644 index 0000000..92b78f8 --- /dev/null +++ b/webserver/bin/www @@ -0,0 +1,109 @@ +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var app = require('../../webserver/modules/express.js'); +const index = require("../index.js") +var debug = require('debug')('proxy-api:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +const port = normalizePort(process.env.PORT || '80'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +const io = require('socket.io')(server + , { + cors: { + //replace with domain name when deployed + origin: 'http://localhost:3000', // client! + methods: ["GET"], + allowedHeaders: ["my-custom-header"], + credentials: true + + } +}); + +app.io = io; + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + console.log('Listening on ' + bind); + + for(let listener of app.onListen){ + listener() + } +} diff --git a/webserver/functions/Database.js b/webserver/functions/Database.js index d18f7dd..e401ada 100644 --- a/webserver/functions/Database.js +++ b/webserver/functions/Database.js @@ -23,11 +23,15 @@ async function insertLogData(log) { async function insertDatatoDB(data) { try { + const app = require("../modules/express.js"); + sensorDataModel.create({ sensorid: data.sensorid, locationid: data.locationid, measurement: data.measurement, }); + //ws broadcast event except to the sender. + app.io.emit("sensorData:new", data); } catch (error) { console.error(error); } @@ -37,15 +41,15 @@ async function checkAPikey(SuppliedKey, rowid) { try { const retrivedKey = await apikeyModel.findOne({ raw: true, - attributes: ["apikey" , "permission"], + attributes: ["apikey", "permission"], where: { - userid: rowid, + id: rowid, }, }); //console.log(retrivedKey.apikey); if (compareAPIKey(SuppliedKey, retrivedKey.apikey)) { //return true; - return retrivedKey.permission; + return retrivedKey.permission; } } catch (error) { console.error(error); diff --git a/webserver/index.js b/webserver/index.js index cf6da5d..c3c7fa8 100644 --- a/webserver/index.js +++ b/webserver/index.js @@ -1,4 +1,3 @@ -const { app } = require("./modules/express.js"); const client = require("./modules/mqtt"); const { isJson, isNumber } = require("./functions/validateData.js"); const { insertDatatoDB } = require("./functions/database.js"); diff --git a/webserver/modules/express.js b/webserver/modules/express.js index fcbbbba..80a497b 100644 --- a/webserver/modules/express.js +++ b/webserver/modules/express.js @@ -1,13 +1,24 @@ const express = require("express"); -const helmet = require("helmet"); +//const helmet = require("helmet"); +var cors = require('cors'); const { rateLimit } = require("express-rate-limit"); const { APIlogger } = require('../middleware/apiLogger.js'); const { apikeyCheck } = require('../middleware/apiKey.js'); const app = express(); -app.use(helmet()); +//app.use(cors()); +//allow cors from localhost:3000 +//app.use(helmet({ crossOriginResourcePolicy: { policy: "cross-origin" } })); const port = 80; +// Hold list of functions to run when the server is ready +app.onListen = [function(){console.log('hello')}]; + +module.exports = app; + +//handle cors + + //express-rate-limit stolen from docs const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes @@ -73,8 +84,8 @@ app.use(function(err, req, res, next) { keyErrors, }); }); +/* app.listen(port, () => { console.log(`app listening on port ${port}`); }); - -module.exports = { app }; +*/ diff --git a/webserver/modules/mqtt.js b/webserver/modules/mqtt.js index 5266d7c..f5f9e4a 100644 --- a/webserver/modules/mqtt.js +++ b/webserver/modules/mqtt.js @@ -10,8 +10,8 @@ const options = { username: process.env.MQTT_USER, password: process.env.MQTT_PASS, protocol: 'mqtts', // Use MQTT over TLS - key: fs.readFileSync(path.resolve(__dirname, '../../cert/privkey.pem')), - cert: fs.readFileSync(path.resolve(__dirname, '../../cert/cert.pem')), + key: fs.readFileSync(path.resolve(__dirname, '../cert/privkey.pem')), + cert: fs.readFileSync(path.resolve(__dirname, '../cert/cert.pem')), };