diff --git a/consumerWebsite/functions/nodeMail.js b/consumerWebsite/functions/nodeMail.js new file mode 100644 index 0000000..f81a8c4 --- /dev/null +++ b/consumerWebsite/functions/nodeMail.js @@ -0,0 +1,82 @@ +const { transporter } = require("../modules/nodemailer"); +const path = require("path"); +require("dotenv").config({ path: path.resolve(__dirname, "../.env") }); + +/* +var message = { + from: "sender@server.com", + to: "receiver@sender.com", + subject: "Message title", + text: "Plaintext version of the message", + html: "

HTML version of the message

", +}; +//send mail with defined transport object +transporter.sendMail(data[, callback]) + +*/ + +async function sendContactEmail(email, name, message) { + console.log(email, name, message); + + try { + let contactMessage = await transporter.sendMail({ + to: process.env.euser, + subject: "Contact us Message", + html: ` +

Contact us Message

+

From: ${name}

+

User Email: ${email}

+

Message: ${message}

+

Thank you for contacting us. We will get back to you as soon as possible.

+

Regards,

+

EcoSaver Team

+

EcoSaver Website

+

Please do not reply to this email.

+ `, + }); + transporter.sendMail({ contactMessage }, function (error, info) { + if (error) { + console.log(error); + } else { + console.log("Email sent: " + info.response); + } + }); + } catch (error) { + console.error(error); + } +} + +async function sendTokenEmail(email, token) { + + try { + let tokenMessage = await transporter.sendMail({ + to: email, + from: process.env.euser, + subject: "API Token", + html: ` +

API Token

+

Token: ${token}

+

Please do not lose this token and do not share your token with anyone!

+

Thank you for using EcoSaver.

+

Regards,

+

EcoSaver Team

+

EcoSaver Website

+

Please do not reply to this email.

+ + `, + }); + transporter.sendMail({ tokenMessage }, function (error, info) { + if (error) { + console.log(error); + } else { + console.log("Email sent: " + info.response); + } + }); + } catch (error) { + console.error(error); + } +} + + + +module.exports = { sendContactEmail , sendTokenEmail }; diff --git a/consumerWebsite/functions/sensorData.js b/consumerWebsite/functions/sensorData.js index f59c28b..20a4176 100644 --- a/consumerWebsite/functions/sensorData.js +++ b/consumerWebsite/functions/sensorData.js @@ -18,7 +18,6 @@ async function getSensorData() { const sensorData = await sensorDataModel.findAll(); return sensorData; } -let dataArray = []; async function addSensorData(id_sensor, id_location, sensordata) { const sensorData = await sensorDataModel.create({ sensorid: id_sensor, @@ -26,11 +25,10 @@ async function addSensorData(id_sensor, id_location, sensordata) { measurement: sensordata.measurement, }); //console.log("sensorData", sensorData); - //console.log("sensorData", sensordata); - dataArray.push(sensordata); - console.log("dataArray", dataArray); + //console.log("sensorData", sensordata.measurement); + - io().emit('sensorData:new', dataArray) + io().emit('sensorData:new', sensordata) return sensorData; } @@ -68,7 +66,7 @@ async function getSensorDataById(id) { async function getLatestData() { const sensorData = await sensorDataModel.findAll({ - limit: 1, + limit: 6, order: [["createdAt", "DESC"]], }); return sensorData; diff --git a/consumerWebsite/functions/user.js b/consumerWebsite/functions/user.js index c94e183..d79d86d 100644 --- a/consumerWebsite/functions/user.js +++ b/consumerWebsite/functions/user.js @@ -20,6 +20,16 @@ async function getUserByID(userid) { return userRes; } +async function getUserByEmail(email) { + let userRes = await userModel.findOne({ + where: { + email: email, + }, + }); + if (!userRes) return false; + return userRes; +} + //api/v0/auth/register /* Registering new user 1) req.body is taken from html form or wtv @@ -131,9 +141,23 @@ async function updateProfile(user, body) { } } +async function checkEmail(email) { + let emailRes = await userModel.findOne({ + where: { + email: email, + }, + }); + if (!emailRes) return false; + return true; + +} + + module.exports = { getUserByID, + getUserByEmail, addUser, loginUser, updateProfile, + checkEmail }; \ No newline at end of file diff --git a/consumerWebsite/middleware/authChecker.js b/consumerWebsite/middleware/authChecker.js index cc9b3f9..300cf4d 100644 --- a/consumerWebsite/middleware/authChecker.js +++ b/consumerWebsite/middleware/authChecker.js @@ -19,12 +19,24 @@ async function auth(req, res, next) { const route = req.originalUrl.split("?")[0]; // Removing query parameters //if route is from user/ and permission is canRead allow it to do CRUD - if (route.includes("/user/") && token.permission === "canRead") { + if (route.includes("/user/") || route.includes("/token/") && token.permission === "canRead") { + console.log("user route"); return next(); } - if ((req.method === "GET" && token.permission === "canRead") || (["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite")) { + if ((req.method === "GET" && token.permission === "canRead")){ + console.log("wtf you shldnt be here"); return next(); } + if (["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite") { + console.log("wtf you shldnt be here"); + return next(); + } + /* + if ((req.method === "GET" && token.permission === "canRead") || + (["GET", "POST", "PUT", "DELETE"].includes(req.method) && token.permission === "canWrite")) { + return next(); + } + */ throw permissionError diff --git a/consumerWebsite/modules/nodemailer.js b/consumerWebsite/modules/nodemailer.js index 64e745f..a6d3cc2 100644 --- a/consumerWebsite/modules/nodemailer.js +++ b/consumerWebsite/modules/nodemailer.js @@ -2,6 +2,7 @@ const nodemailer = require("nodemailer"); const dotenv = require("dotenv"); const path = require('path') require('dotenv').config({ path: path.resolve(__dirname, '../.env') }) +//.env let transporter = nodemailer.createTransport({ service: 'gmail', diff --git a/consumerWebsite/public/css/api.css b/consumerWebsite/public/css/api.css index f5d527e..a13b630 100644 --- a/consumerWebsite/public/css/api.css +++ b/consumerWebsite/public/css/api.css @@ -528,22 +528,24 @@ body.one-content-column-version .content thead { .generate-key-button { - float: right; /* Align the button to the right */ - margin-right: 85%; - margin-top: -40px; /* Adjust the margin-top value based on your layout */ - /* Add any additional styling you want for the button */ -} - -#content-get-api .generate-key-button { + margin-top: -40px; + margin-left: 25px; background-color: #4caf50; /* Green background color */ - color: white; /* White text color */ + color: #ffffff; padding: 5px 11px; /* Padding for the button */ border: none; /* Remove button border */ border-radius: 5px; /* Add border-radius for rounded corners */ cursor: pointer; /* Add pointer cursor on hover */ font-size: 14px; /* Font size */ } +.api-form { + margin-top: 20px; + margin-left: 25px; +} -#content-get-api .generate-key-button:hover { +.generate-key-button:hover { background-color: #45a049; /* Darker green on hover */ -} \ No newline at end of file +} + + + diff --git a/consumerWebsite/public/js/app.js b/consumerWebsite/public/js/app.js index 0ffd8a2..90da0c3 100644 --- a/consumerWebsite/public/js/app.js +++ b/consumerWebsite/public/js/app.js @@ -285,7 +285,7 @@ function formAJAX(btn, del) { //console.log('Data being sent to', $form.attr('action'), formData) app.api[method]($form.attr("action"), formData, function (error, data) { - //console.log('Data back from the server', error, data) + console.log('Data back from the server', error, data) app.util.actionMessage(data.message, $form, error ? "danger" : "success"); //re-populate table if (!error) { $form.trigger("reset"); diff --git a/consumerWebsite/routes/auth.js b/consumerWebsite/routes/auth.js index dd16dc1..276a5a2 100644 --- a/consumerWebsite/routes/auth.js +++ b/consumerWebsite/routes/auth.js @@ -1,4 +1,5 @@ -const { addUser, loginUser } = require("../functions/user"); +const { addUser, loginUser, checkEmail } = require("../functions/user"); +const { sendContactEmail } = require("../functions/nodeMail"); const express = require("express"); const router = express.Router(); @@ -12,12 +13,11 @@ router.post("/register", async (req, res, next) => { error.message = "The user failed to be craated"; error.status = 400; return next(error); + } else { + return res.json({ + message: "User created successfully", + }); } - else{ - return res.json({ - message: "User created successfully", - }); - } } catch (error) { console.error(error); next(error); @@ -29,20 +29,18 @@ router.post("/login", async (req, res, next) => { try { let Res = await loginUser(req.body); if (Res == false) { - let error = new Error("User Login Failed"); + let error = new Error("User Login Failed"); error.status = 400; return next(error); + } else { + //pass res back to form to be set in local storage + return res.json({ + message: "User login successfully", + token: Res.token, + userid: Res.userid, + username: Res.username, + }); } - else{ - //pass res back to form to be set in local storage - return res.json({ - message: "User login successfully", - token: Res.token, - userid: Res.userid, - username: Res.username, - }); - - } } catch (error) { console.error(error); next(error); @@ -52,8 +50,26 @@ router.post("/login", async (req, res, next) => { //contact //auth/contact router.post("/contact", async (req, res, next) => { - + try { + //console.log(req.body); + let Res = await checkEmail(req.body.email); + if (!Res) { + let error = new Error("Email not found"); + error.status = 400; + return next(error); + } + else{ + //console.log(Res); + sendContactEmail(req.body.email, req.body.name, req.body.message); + return res.json({ + message: "Email sent successfully", + }); + + } + } catch (error) { + console.error(error); + next(error); + } }); module.exports = router; - diff --git a/consumerWebsite/routes/token.js b/consumerWebsite/routes/token.js index f6d4b46..18b8df0 100644 --- a/consumerWebsite/routes/token.js +++ b/consumerWebsite/routes/token.js @@ -1,4 +1,7 @@ const { addToken } = require("../functions/api"); +const { checkEmail , getUserByEmail } = require("../functions/user"); +const { sendTokenEmail } = require("../functions/nodeMail"); + const express = require("express"); @@ -15,8 +18,29 @@ const router = express.Router(); //'{"userid": "5", "permission": "canRead" ,}' router.post("/new", async (req, res, next) => { try { - const token = await addToken(req.body.userid, req.body.permission , "2204-01-24 07:34:36" ); - res.json({token: token}); + //console.log(req.body); + const Res = await checkEmail(req.body.email); + if (!Res) { + let error = new Error("Email not found"); + error.status = 400; + return next(error); + } + else + { + //console.log("email found"); + let userid = await getUserByEmail(req.body.email); + if (!userid) return false; + + const token = await addToken(userid.id, "canRead" , "2204-01-24 07:34:36" ); + if (!token) return false; + sendTokenEmail(req.body.email, token); + res.json({ + message: "Token generated successfully and sent to email", + }) + + } + //const token = await addToken(req.body.userid, "canRead" , "2204-01-24 07:34:36" ); + //res.json({token: token}); } catch (error) { console.error(error); next(error); diff --git a/consumerWebsite/views/api.ejs b/consumerWebsite/views/api.ejs index e3521e4..4e90eaf 100644 --- a/consumerWebsite/views/api.ejs +++ b/consumerWebsite/views/api.ejs @@ -6,6 +6,10 @@ !--> <%- include('top') %> + @@ -312,81 +316,6 @@ - -
-

Errors

-

- The Westeros API uses the following error codes: -

- - - - - - - - - - - - - - - - - - - - - - - - - -
Error CodeMeaning
X000 - Some parameters are missing. This error appears when you don't pass every mandatory - parameters. -
403 - Unknown or unvalid secret_key. This error appears if - you use an unknow API key or if your API key expired. -
500 - Unvalid secret_key No API key was supplied. Invalid - request. -
X003 - Unknown or unvalid user token. This error appears if - you use an unknow user token or if the user token expired. -
-
-
-
-

API Keys

- -

- You can generate API Keys here: -

- - - - - - - - - - - - - - - - - - - -
NamePublic KeyPrivate KeyKey TypeCreated
API KeyGR234-We34greR-234-fEGType2024-01-22
-
-

Get all sensor

@@ -483,7 +412,7 @@ Authorization JSON Your API key. - (Required) Example: curl https://api.teeseng.uk/api/v0/sensor/new + (Required) Example: curl https://api.teeseng.uk/api/v0/sensor/new -H "Authorization: {provide your API key here}" @@ -620,7 +549,8 @@ Description JSON Description of Sensor - (Optional) Description of Sensor Example: curl https://api.teeseng.uk/api/v0/sensor/update + (Optional) Description of Sensor Example: curl + https://api.teeseng.uk/api/v0/sensor/update -H "Authorization: provide your API key here" -d '{"description":"test"}' @@ -629,7 +559,8 @@ Location JSON Location of Sensor - (Optional) Location of Sensor Example: curl https://api.teeseng.uk/api/v0/sensor/update + (Optional) Location of Sensor Example: curl + https://api.teeseng.uk/api/v0/sensor/update -H "Authorization: provide your API key here" -d '{"location": "11"}' @@ -679,10 +610,77 @@ +

+

API Keys

+

+ You can generate API Keys here: +

+
+ + +
+ + +
+ +
+
+ +
+

Errors

+

+ The EcoSaver API uses the following error codes: +

+ + + + + + + + + + + + + + + + + + + + + + + + + +
Error CodeMeaning
X000 + Some parameters are missing. This error appears when you don't pass every + mandatory + parameters. +
403 + Unknown or unvalid secret_key. This error + appears if + you use an unknow API key or if your API key expired. +
500 + Unvalid secret_key No API key was supplied. + Invalid + request. +
X003 + Unknown or unvalid user token. This error + appears if + you use an unknow user token or if the user + token expired. +
+ - + + \ No newline at end of file diff --git a/consumerWebsite/views/contact.ejs b/consumerWebsite/views/contact.ejs index edc98f5..670c760 100644 --- a/consumerWebsite/views/contact.ejs +++ b/consumerWebsite/views/contact.ejs @@ -42,7 +42,8 @@

E: - leongdingxuan@gmail.com + ecosaverx@gmail.com +

@@ -55,17 +56,18 @@

+

Send us a Message

-
- + +
- +
- +
@@ -75,6 +77,8 @@
+
+
diff --git a/consumerWebsite/views/index.ejs b/consumerWebsite/views/index.ejs index c2e533a..c4419a3 100644 --- a/consumerWebsite/views/index.ejs +++ b/consumerWebsite/views/index.ejs @@ -1,18 +1,59 @@ <%- include('top') %> - @@ -69,7 +110,8 @@

Air Quality Index

-

{{ measurement.psi }} PSI

+

Average: {{average.psi}} PSI

+

Latest: {{latest.psi}} PSI