Fix database model associations and update API route
This commit is contained in:
@ -2,7 +2,6 @@ const express = require("express");
|
|||||||
const { rateLimit } = require("express-rate-limit");
|
const { rateLimit } = require("express-rate-limit");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 3000;
|
|
||||||
const ejs = require("ejs");
|
const ejs = require("ejs");
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
|
@ -107,6 +107,6 @@ const sensorModel = sequelize.define(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
sensorModel.belongsTo(locationModel);
|
//sensorModel.belongsTo(locationModel);
|
||||||
|
|
||||||
module.exports = { sensorModel };
|
module.exports = { sensorModel };
|
||||||
|
@ -3,7 +3,7 @@ const { Sequelize, DataTypes } = require("sequelize");
|
|||||||
const { sequelize } = require("../mySQL");
|
const { sequelize } = require("../mySQL");
|
||||||
const { userModel } = require("./userModel");
|
const { userModel } = require("./userModel");
|
||||||
|
|
||||||
sequelize.sync();
|
//sequelize.sync();
|
||||||
const tokenModel = sequelize.define(
|
const tokenModel = sequelize.define(
|
||||||
"token",
|
"token",
|
||||||
{
|
{
|
||||||
@ -48,6 +48,14 @@ const tokenModel = sequelize.define(
|
|||||||
isIn: [["canRead", "canWrite",]],
|
isIn: [["canRead", "canWrite",]],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
isKey: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
length: 45,
|
||||||
|
validate:{
|
||||||
|
isIn: [["isKey" , "isNotKey"]],
|
||||||
|
}
|
||||||
|
},
|
||||||
expiration: {
|
expiration: {
|
||||||
type: DataTypes.DATE,
|
type: DataTypes.DATE,
|
||||||
allowNull: false,
|
allowNull: false,
|
||||||
|
@ -15,7 +15,7 @@ const sequelize = new Sequelize(
|
|||||||
attributeBehavior: 'escape',
|
attributeBehavior: 'escape',
|
||||||
dialectOptions: {
|
dialectOptions: {
|
||||||
ssl: {
|
ssl: {
|
||||||
ca: fs.readFileSync(path.resolve(__dirname, '../cert/DigiCertGlobalRootCA.crt.pem')),
|
ca: fs.readFileSync(path.resolve(__dirname, '../cert/DigiCertGlobalRootCA.crt_3.pem')),
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -30,7 +30,7 @@ async function getTokenByToken(token) {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addToken(userId, permission, expiry) {
|
async function addToken(userId, permission, isKey ,expiry) {
|
||||||
let uuid = await generateUUID();
|
let uuid = await generateUUID();
|
||||||
let hashtoken = await hash(uuid);
|
let hashtoken = await hash(uuid);
|
||||||
//console.log("user id", userId);
|
//console.log("user id", userId);
|
||||||
@ -41,6 +41,7 @@ async function addToken(userId, permission, expiry) {
|
|||||||
userid: userId,
|
userid: userId,
|
||||||
token: hashtoken,
|
token: hashtoken,
|
||||||
permission: permission,
|
permission: permission,
|
||||||
|
isKey: isKey,
|
||||||
expiration: expiry,
|
expiration: expiry,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -48,4 +49,16 @@ async function addToken(userId, permission, expiry) {
|
|||||||
return token.id + "-" + uuid;
|
return token.id + "-" + uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { addToken, getTokenByToken };
|
async function checkToken(id) {
|
||||||
|
let tokenRes = await tokenModel.findOne(
|
||||||
|
{
|
||||||
|
where: {
|
||||||
|
userid: id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
|
return tokenRes;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { addToken, getTokenByToken , checkToken};
|
||||||
|
@ -84,7 +84,7 @@ async function loginUser(user) {
|
|||||||
//let tokenToLive = moment().add(30, 'minutes').format();
|
//let tokenToLive = moment().add(30, 'minutes').format();
|
||||||
let currentDate = new Date();
|
let currentDate = new Date();
|
||||||
let tokenToLive = new Date(currentDate.getTime() + 30 * 60000);
|
let tokenToLive = new Date(currentDate.getTime() + 30 * 60000);
|
||||||
let token = await addToken(userRes.id , "canRead" , tokenToLive);
|
let token = await addToken(userRes.id , "canRead" , "isNotKey" , tokenToLive);
|
||||||
return { token: token, userid: userRes.id, username: userRes.username };
|
return { token: token, userid: userRes.id, username: userRes.username };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
var validator = require("validator");
|
var validator = require("validator");
|
||||||
|
|
||||||
|
/*
|
||||||
|
All the validation functions are used by database model.
|
||||||
|
*/
|
||||||
|
|
||||||
const dateRegex = /^[A-Za-z]{3}, \d{2} [A-Za-z]{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
const dateRegex = /^[A-Za-z]{3}, \d{2} [A-Za-z]{3} \d{4} \d{2}:\d{2}:\d{2} GMT$/;
|
||||||
|
|
||||||
function isValidDateString(value) {
|
function isValidDateString(value) {
|
||||||
|
@ -547,106 +547,3 @@ body.one-content-column-version .content thead {
|
|||||||
background-color: #45a049; /* Darker green on hover */
|
background-color: #45a049; /* Darker green on hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
.delete-key-button {
|
|
||||||
float: right; /* Align the button to the right */
|
|
||||||
margin-right: 78%;
|
|
||||||
margin-top: -40px; /* Adjust the margin-top value based on your layout */
|
|
||||||
/* Add any additional styling you want for the button */
|
|
||||||
}
|
|
||||||
|
|
||||||
#content-get-api .delete-key-button {
|
|
||||||
background-color: #af4c4c; /* Green background color */
|
|
||||||
color: white; /* White text color */
|
|
||||||
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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
#content-get-api .delete-key-button:hover {
|
|
||||||
background-color: #a04545; /* Darker green on hover */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.generate-key-screen {
|
|
||||||
position: fixed;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
padding: 30px;
|
|
||||||
width: 400px; /* Adjust the width as needed */
|
|
||||||
background-color: #ffffff;
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); /* Adjust the shadow as needed */
|
|
||||||
z-index: 1000;
|
|
||||||
border-radius: 12px; /* Slightly increased border-radius for a softer look */
|
|
||||||
overflow: hidden; /* Hide overflow content */
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-key-screen label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-key-screen input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-key-screen button {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
padding: 10px 15px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-key-screen button:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-key-screen button + button {
|
|
||||||
margin-left: 8px;
|
|
||||||
background-color: #f44336;
|
|
||||||
}
|
|
||||||
|
|
||||||
.generate-key-screen button + button:hover {
|
|
||||||
background-color: #d32f2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
.key-input {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.key-input input {
|
|
||||||
flex: 1;
|
|
||||||
padding: 8px;
|
|
||||||
margin-right: 8px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.key-input button {
|
|
||||||
background-color: #4caf50;
|
|
||||||
color: #fff;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border: none;
|
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.key-input button:hover {
|
|
||||||
background-color: #45a049;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -147,13 +147,13 @@ button.btn-secondary:hover{
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
.services-bar .card h4.card-header{
|
.services-bar .card h4.card-header{
|
||||||
background-color: #4e3914;
|
background-color: #ffffff;
|
||||||
color: #4eae3a;
|
color: #4eae3a;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
.services-bar .card .card-footer{
|
.services-bar .card .card-footer{
|
||||||
background-color: #4e3914;
|
background-color: #ffffff;
|
||||||
}
|
}
|
||||||
.about-main{
|
.about-main{
|
||||||
padding: 30px 0px;
|
padding: 30px 0px;
|
||||||
|
@ -5,8 +5,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
const aqi = "15";
|
const aqi = "15";
|
||||||
const temperature = "25°C";
|
const temperature = "25°C";
|
||||||
const humidity = "60%";
|
const humidity = "60%";
|
||||||
const pm25 = "10";
|
|
||||||
const pm10 = "20";
|
|
||||||
const so2 = "5";
|
const so2 = "5";
|
||||||
const o3 = "35";
|
const o3 = "35";
|
||||||
const co = "0.5";
|
const co = "0.5";
|
||||||
@ -15,7 +13,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
infoContainer.innerHTML = `
|
infoContainer.innerHTML = `
|
||||||
<div class="additional-info-box">
|
<div class="additional-info-box">
|
||||||
<h3>Additional Information - ${region}</h3>
|
<h3>Additional Information - ${region}</h3>
|
||||||
<button id="viewData">View Data</button>
|
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">Air Quality Index:</span>
|
<span class="info-label">Air Quality Index:</span>
|
||||||
<span class="info-value">${aqi}</span>
|
<span class="info-value">${aqi}</span>
|
||||||
@ -28,14 +25,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
<span class="info-label">Humidity:</span>
|
<span class="info-label">Humidity:</span>
|
||||||
<span class="info-value">${humidity}</span>
|
<span class="info-value">${humidity}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-item">
|
|
||||||
<span class="info-label">PM2.5:</span>
|
|
||||||
<span class="info-value">${pm25}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
|
||||||
<span class="info-label">PM10:</span>
|
|
||||||
<span class="info-value">${pm10}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-item">
|
<div class="info-item">
|
||||||
<span class="info-label">SO2:</span>
|
<span class="info-label">SO2:</span>
|
||||||
<span class="info-value">${so2}</span>
|
<span class="info-value">${so2}</span>
|
||||||
@ -54,21 +43,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
var viewDataButton = document.getElementById("viewData");
|
|
||||||
|
|
||||||
// Add a click event listener to the button
|
|
||||||
viewDataButton.addEventListener("click", function () {
|
|
||||||
// Redirect to the "viewdata.ejs" page
|
|
||||||
window.location.href = "/viewdata";
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove the 'active' class from all info-box elements
|
|
||||||
const infoBoxes = document.querySelectorAll('.info-box');
|
|
||||||
infoBoxes.forEach(box => box.classList.remove('active'));
|
|
||||||
|
|
||||||
// Add the 'active' class to the clicked info-box
|
|
||||||
const clickedBox = document.getElementById(region.toLowerCase());
|
|
||||||
clickedBox.classList.add('active');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
const { addToken } = require("../functions/api");
|
const { addToken, checkToken } = require("../functions/api");
|
||||||
const { checkEmail , getUserByEmail } = require("../functions/user");
|
const { checkEmail, getUserByEmail } = require("../functions/user");
|
||||||
const { sendTokenEmail } = require("../functions/nodeMail");
|
const { sendTokenEmail } = require("../functions/nodeMail");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
@ -14,7 +12,7 @@ const router = express.Router();
|
|||||||
4) store the api key in database
|
4) store the api key in database
|
||||||
*/
|
*/
|
||||||
//token/new
|
//token/new
|
||||||
//curl localhost:3000/api/v0/token/new -H "Content-Type: application/json" -X POST -d
|
//curl localhost:3000/api/v0/token/new -H "Content-Type: application/json" -X POST -d
|
||||||
//'{"userid": "5", "permission": "canRead" ,}'
|
//'{"userid": "5", "permission": "canRead" ,}'
|
||||||
router.post("/new", async (req, res, next) => {
|
router.post("/new", async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
@ -24,29 +22,33 @@ router.post("/new", async (req, res, next) => {
|
|||||||
let error = new Error("Email not found");
|
let error = new Error("Email not found");
|
||||||
error.status = 400;
|
error.status = 400;
|
||||||
return next(error);
|
return next(error);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//console.log("email found");
|
|
||||||
let userid = await getUserByEmail(req.body.email);
|
let userid = await getUserByEmail(req.body.email);
|
||||||
if (!userid) return false;
|
if (!userid) return false;
|
||||||
|
|
||||||
const token = await addToken(userid.id, "canRead" , "2204-01-24 07:34:36" );
|
const tokenRes = await checkToken(userid.id);
|
||||||
if (!token) return false;
|
if (tokenRes.isKey !== "null" && tokenRes.isKey !== "isKey") {
|
||||||
sendTokenEmail(req.body.email, token);
|
//allow user to create token
|
||||||
res.json({
|
const token = await addToken(
|
||||||
message: "Token generated successfully and sent to email",
|
userid.id,
|
||||||
})
|
"canRead",
|
||||||
|
"isKey",
|
||||||
|
"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});
|
//const token = await addToken(req.body.userid, "canRead" , "2204-01-24 07:34:36" );
|
||||||
|
//res.json({token: token});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ const router = express.Router();
|
|||||||
//getbyid
|
//getbyid
|
||||||
router.get("/me", async function (req, res, next) {
|
router.get("/me", async function (req, res, next) {
|
||||||
try {
|
try {
|
||||||
let user = await getUserByID(req.user);
|
let user = await getUserByID(req.user); //req.user assigned in middleware!
|
||||||
//console.log(user);
|
//console.log(user);
|
||||||
res.json({
|
res.json({
|
||||||
user: user,
|
user: user,
|
||||||
|
@ -41,14 +41,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="scroll-to-link active" data-target="content-get-started">
|
<li class="scroll-to-link active" data-target="content-get-started">
|
||||||
<a>GET STARTED</a>
|
<a>Get Started</a>
|
||||||
</li>
|
|
||||||
<li class="scroll-to-link" data-target="content-errors">
|
|
||||||
<a>Errors</a>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="scroll-to-link" data-target="content-get-api">
|
<li class="scroll-to-link" data-target="content-get-api">
|
||||||
<a>Generate API</a>
|
<a>Generate API</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="scroll-to-link" data-target="content-errors">
|
||||||
|
<a>Errors</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user