merge #1

Merged
nbot merged 7 commits from merge into main 2024-01-24 04:39:51 +00:00
21 changed files with 5312 additions and 70 deletions
Showing only changes of commit 173277cc8b - Show all commits

2
.gitignore vendored
View File

@ -1,7 +1,7 @@
node_modules
.env
cert
*.sqlite

View File

@ -9,21 +9,21 @@ app.use(express.json());
app.set("json spaces", 2);
// Set up the templating engine to build HTML for the front end.
app.set("views", path.join(__dirname, "../views"));
app.set("views", path.join(__dirname, "./views"));
app.set("view engine", "ejs");
// Have express server static content( images, CSS, browser JS) from the public
app.use(express.static(path.join(__dirname, "../public")));
app.use(express.static(path.join(__dirname, "./public")));
//middleware logic ( called by next() )
const auth = require("../middleware/authChecker");
const auth = require("./middleware/authChecker");
//route logic
app.use("/api/v0", require("../routes/api_routes"));
app.use("/api/v0", require("./routes/api_routes"));
//render logic
app.use("/", require("../routes/render"));
app.use("/", require("./routes/render"));
// Catch 404 and forward to error handler. If none of the above routes are
// used, this is what will be called.
@ -69,8 +69,6 @@ app.use(function (err, req, res, next) {
keyErrors,
});
});
app.listen(port, () => {
console.log(`app listening on port ${port}`);
});
module.exports = { app };
module.exports = app ;

96
consumerWebsite/bin/www Normal file
View File

@ -0,0 +1,96 @@
#!/usr/bin/env node
/**
* Module dependencies.
*/
const app = require('../app');
const debug = require('debug')('proxy-api:server');
const http = require('http');
const path = require('path');
require('dotenv').config({ path: path.resolve(__dirname, '../../.env')})
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.NODE_PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
var io = require('socket.io')(server);
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);
}

View File

@ -1,7 +1,9 @@
"use strict";
const { Sequelize, DataTypes } = require("sequelize");
const { sequelize } = require("../mySQL");
const { Sequelize, DataTypes, Op } = require("sequelize");
const { sequelize } = require("../mySql");
const { userModel } = require("./userModel");
const { generateUUID } = require("../../functions/generateUUID.js");
const { hash, compareHash } = require("../../functions/bcrypt.js");
//sequelize.sync();
const apikeyModel = sequelize.define(
@ -16,7 +18,7 @@ const apikeyModel = sequelize.define(
isNumeric: true,
},
},
userid: {
userId: {
type: DataTypes.INTEGER,
allowNull: false,
validate: {
@ -63,6 +65,8 @@ const apikeyModel = sequelize.define(
);
apikeyModel.belongsTo(userModel);
apikeyModel.sync()
module.exports = { apikeyModel };
/*

View File

@ -72,4 +72,59 @@ const locationModel = sequelize.define(
}
);
module.exports = { locationModel };
async function getLocation() {
const location = await locationModel.findAll();
return location;
}
async function addLocation(name, added_by, description) {
const location = await locationModel.create({
name: name,
added_by: added_by,
description: description,
});
}
async function updateLocation(id, name, added_by, description) {
const location = await locationModel.update(
{
name: name,
added_by: added_by,
description: description,
},
{
where: {
id: id,
},
}
);
}
async function deleteLocation(id) {
//delete by id
const location = await locationModel.destroy({
where: {
id: id,
},
});
}
async function getLocationById(id) {
const location = await locationModel.findAll({
where: {
id: id,
},
});
return location;
}
module.exports = {
locationModel,
getLocation,
addLocation,
updateLocation,
deleteLocation,
getLocationById,
};

View File

@ -1,6 +1,6 @@
"use strict";
const { Sequelize, DataTypes } = require("sequelize");
const { sequelize } = require("../mySQL");
const { sequelize } = require("../mySql");
const {
isAlphaNumericWithSpacesAndDash,
isAddress,
@ -111,4 +111,5 @@ const userModel = sequelize.define(
timestamps: true,
}
);
module.exports = { userModel };

View File

@ -1,16 +1,18 @@
const dotenv = require("dotenv");
const path = require('path')
require('dotenv').config({ path: path.resolve(__dirname, '../../.env') })
require('dotenv').config({ path: path.resolve(__dirname, '../../.env') });
const Sequelize = require("sequelize");
const fs = require('fs');
const sequelize = new Sequelize(
"eco_saver",
process.env.DB_name,
process.env.DB_USER,
process.env.DB_PASS,
{
host: "mpsqldatabase.mysql.database.azure.com",
dialect: 'mysql',
dialect: process.env.DB_dialect,
storage: process.env.DB_storage,
logging: process.env.DB_logging,
// attributeBehavior?: 'escape' | 'throw' | 'unsafe-legacy';
attributeBehavior: 'escape',
dialectOptions: {
@ -20,12 +22,10 @@ const sequelize = new Sequelize(
},
},
);
sequelize.authenticate().then(() => {
console.log('Connection has been established successfully.');
console.log(`Connection to ${process.env.DB_dialect} has been established successfully.`);
}).catch((error) => {
console.error('Unable to connect to the database: ', error);
});

View File

@ -0,0 +1,23 @@
const { hash, compareHash } = require("./bcrypt.js");
const { apikeyModel } = require("../database/model/apiKeyModel");
const { generateUUID } = require("./generateUUID.js");
//can be used for api key or token. Both are the same logic
async function addAPIKey(userId, permission) {
let hashtoken = await generateUUID();
let apikey = await hash(hashtoken);
let token = await apikeyModel.create({
userId: userId,
apikey: apikey,
permission: permission,
});
//user token with - tokenid is table id
return token.id + "-" + hashtoken;
}
module.exports = {
addAPIKey
};

View File

@ -23,23 +23,18 @@ bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
*/
//hash for pass or token lol doesnt matter
async function hashPassword(password) {
async function hash(password) {
return await bcrypt.hash(password, saltRounds);
}
async function hashAPIKey(apikey) {
return await bcrypt.hash(apikey, saltRounds);
}
//can be used to compare password or token
async function comparePassword(password, hash) {
async function compareHash(password, hash) {
return await bcrypt.compare(password, hash);
}
module.exports = {
hashPassword,
hashAPIKey,
comparePassword
};
hash,
compareHash
};

View File

@ -1,13 +1,45 @@
const { sequelize } = require("../database/mySql.js");
const { apikeyModel } = require("../database/model/apikeyModel.js");
const { userModel } = require("../database/model/userModel.js");
const { Op, Sequelize } = require("sequelize");
const { generateUUID } = require("../functions/generateUUID.js");
const {
hashPassword,
comparePassword,
hashAPIKey,
} = require("../functions/bcrypt.js");
const { Op } = require('sequelize')
const { hash, compareHash } = require("./bcrypt.js");
const { addAPIKey } = require("./api");
const { userModel } = require("../database/model/userModel");
//getuser
//api/v0/user/me
async function getUserID(userid) {
//console.log(userid);
//console.log(userid.id);
let userRes = await userModel.findByPk(userid.id, {
attributes: {
exclude: ["password"],
},
});
if (!userRes) return false;
return userRes;
}
async function addUser(user) {
//hash password
let hashed = await hash(user.password);
const addRes = await userModel.create({
firstname: user.firstname,
lastname: user.lastname,
username: user.username,
password: hashed,
email: user.email,
address: user.address,
phone: user.phone,
});
if (addRes) {
return true;
} else {
return false;
}
}
//getuser
//api/v0/user/me
@ -32,13 +64,13 @@ async function getUserID(userid) {
*/
async function addUser(user) {
//hash password
let hash = await hashPassword(user.password);
let hashed = await hash(user.password);
const addRes = await userModel.create({
firstname: user.firstname,
lastname: user.lastname,
username: user.username,
password: hash,
password: hashed,
email: user.email,
address: user.address,
phone: user.phone,
@ -70,7 +102,7 @@ async function loginUser(user) {
if (!userRes) return false;
// Compare passwords
let match = await comparePassword(user.password, userRes.password);
let match = await compareHash(user.password, userRes.password);
if (!match) return false;
//console.log('loginUser', userRes.id, userRes.username);
@ -89,20 +121,6 @@ async function loginUser(user) {
6) store in database
*/
//can be used for api key or token. Both are the same logic
async function addAPIKey(userId, permission) {
let hashtoken = await generateUUID();
let apikey = await hashAPIKey(hashtoken);
let token = await apikeyModel.create({
userid: userId,
apikey: apikey,
permission: permission,
});
//user token with - tokenid is table id
return token.id + "-" + hashtoken;
}
//api/v0/user/update
async function updateProfile(user, body) {
@ -125,7 +143,7 @@ async function updateProfile(user, body) {
if (!updateUser) return false;
return true;
} else {
let hash = await hashPassword(body.password);
let hashed = await hash(body.password);
let updateUser = await userModel.update(
{
firstname: body.first_name,
@ -134,7 +152,7 @@ async function updateProfile(user, body) {
email: body.email,
address: body.address,
phone: body.phone,
password: hash,
password: hashed,
},
{
where: {
@ -152,5 +170,4 @@ module.exports = {
addUser,
loginUser,
updateProfile,
addAPIKey,
};

View File

@ -1,6 +1,6 @@
const { apikeyModel } = require("../database/model/apiKeyModel");
const { userModel } = require("../database/model/userModel");
const { comparePassword } = require("../functions/bcrypt");
const { compareHash } = require("../functions/bcrypt");
async function auth(req, res, next){
try{
@ -15,7 +15,7 @@ async function auth(req, res, next){
if (!token) return false;
//compare
let isMatch = await comparePassword(suppliedToken, token.apikey);
let isMatch = await compareHash(suppliedToken, token.apikey);
if (!isMatch) return false;
//else do logic

5005
consumerWebsite/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
{
"name": "consumerwebsite",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start-dev": "nodemon bin/www"
},
"author": "",
"license": "ISC",
"devDependencies": {
"nodemon": "^3.0.3",
"sqlite3": "^5.1.7"
},
"dependencies": {
"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",
"dotenv": "^16.3.1",
"ejs": "^3.1.9",
"esm": "^3.2.25",
"express": "^4.18.2",
"express-rate-limit": "^7.1.5",
"express-session": "^1.17.3",
"express-validator": "^7.0.1",
"helmet": "^7.1.0",
"moment": "^2.30.1",
"mqtt": "^5.3.3",
"mysql2": "^3.7.1",
"node-fetch": "^3.3.2",
"nodemailer": "^6.9.8",
"otp-generator": "^4.0.1",
"otplib": "^12.0.1",
"qrcode": "^1.5.3",
"sanitize-html": "^2.11.0",
"sequelize": "^6.35.2",
"sequelize-cli": "^6.6.2",
"socket.io": "^4.7.4",
"socket.io-client": "^4.7.4",
"validator": "^13.11.0"
}
}

View File

@ -147,14 +147,15 @@ app.api = (function (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',
});
var socket = io();
socket.on("disconnect", () => {
console.log("disconnected");
});
socket.on('connect', ()=>{
console.info('WS connected');
})
socket.io.on("reconnect", () => {
console.log("reconnected");
});

View File

@ -1,4 +1,4 @@
const { getAPIKey , addAPIKey } = require("../functions/apiDatabase.js");
const { addAPIKey } = require("../functions/api");
const express = require("express");

View File

@ -1,4 +1,4 @@
const { addUser, loginUser } = require("../functions/apiDatabase.js");
const { addUser, loginUser } = require("../functions/user");
const express = require("express");
const router = express.Router();

View File

@ -1,4 +1,4 @@
const { getUserID, updateProfile } = require("../functions/apiDatabase.js");
const { getUserID, updateProfile } = require("../functions/user");
const express = require("express");
const router = express.Router();