WIP token

This commit is contained in:
newtbot
2024-01-16 04:43:39 +08:00
parent 290d0653d9
commit 7e4b2d8026
19 changed files with 534 additions and 77 deletions

View File

@ -0,0 +1,65 @@
"use strict";
const { Sequelize, DataTypes } = require("sequelize");
const { sequelize } = require("../mySQL");
const { userModel } = require("./userModel");
//sequelize.sync();
const apikeyModel = sequelize.define(
"apikey",
{
id: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true,
autoIncrement: true,
validate: {
isNumeric: true,
},
},
userid: {
type: DataTypes.INTEGER,
allowNull: false,
validate: {
isNumeric: true,
},
//fk
references: {
model: userModel,
key: "id",
},
},
apikey: {
type: DataTypes.STRING,
allowNull: false,
length: 255,
unique: true,
validate: {
notEmpty: true,
len: [1, 255],
},
},
permission: {
type: DataTypes.STRING,
allowNull: false,
length: 255,
validate: {
notEmpty: true,
len: [1, 255],
isIn: [["canRead", "canWrite"]],
},
},
createdAt: {
type: DataTypes.DATE,
allowNull: true,
},
updatedAt: {
type: DataTypes.DATE,
allowNull: true,
},
},
{
timestamps: true,
}
);
module.exports = { apikeyModel };

View File

@ -5,7 +5,7 @@ const { locationModel } = require("./locationModel");
const { sensorModel } = require("./sensorModel");
const { isJson } = require('../../functions/validateData');
sequelize.sync();
//sequelize.sync();
const sensorDataModel = sequelize.define(
"sensorData",
{

View File

@ -0,0 +1,94 @@
"use strict";
const { Sequelize, DataTypes } = require("sequelize");
const { sequelize } = require("../mySQL");
const {
isAlphaNumericWithSpacesAndDash,
isAddress,
} = require("../../functions/validateData");
//sequelize.sync();
const userModel = sequelize.define(
"user",
{
id: {
type: DataTypes.INTEGER,
allowNull: true,
primaryKey: true,
autoIncrement: true,
validate: {
isNumeric: true,
},
},
username: {
type: DataTypes.STRING,
allowNull: false,
length: 60,
validate: {
notEmpty: true,
len: [1, 60],
isAlphaNumericWithSpacesAndDash(value) {
if (!isAlphaNumericWithSpacesAndDash(value)) {
throw new Error("Invalid characters in username");
}
},
},
},
password: {
type: DataTypes.STRING,
allowNull: false,
length: 255,
validate: {
notEmpty: true,
len: [1, 255],
},
},
email: {
type: DataTypes.STRING,
allowNull: false,
length: 60,
unique: true,
validate: {
notEmpty: true,
len: [1, 60],
isEmail: true,
},
},
address: {
type: DataTypes.STRING,
allowNull: true,
length: 255,
validate: {
notEmpty: true,
len: [1, 255],
isAddress(value) {
if (!isAddress(value)) {
throw new Error("Invalid address");
}
},
},
},
phone: {
type: DataTypes.STRING,
allowNull: true,
length: 20,
validate: {
notEmpty: true,
len: [1, 20],
isNumeric: true,
},
},
//utc time
createdAt: {
type: DataTypes.DATE,
allowNull: true,
},
updatedAt: {
type: DataTypes.DATE,
allowNull: true,
},
},
{
timestamps: true,
}
);
module.exports = { userModel };

View File

@ -1,6 +1,7 @@
const { sequelize } = require("../Database/mySql.js");
const { api_log_Model } = require("../Database/model/apiLogModel.js");
const { sensorDataModel } = require("../Database/model/sensorDataModel.js");
const { apikeyModel } = require("../Database/model/apiKeyModel.js");
async function insertLogData(log){
try{
@ -32,10 +33,19 @@ async function insertDatatoDB(data) {
catch (error) {
console.error(error);
}
}
async function checkAPikey(unverified){
const apikey = apikeyModel.findOne({
where: {
apikey: unverified
}
});
return apikey;
}
module.exports = { insertLogData , insertDatatoDB};
module.exports = { insertLogData , insertDatatoDB , checkAPikey};

View File

@ -0,0 +1,38 @@
const bcrypt = require('bcrypt');
const saltRounds = 10;
//https://github.com/kelektiv/node.bcrypt.js#readme
/*
// Load hash from your password DB.
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
// result == true
});
bcrypt.compare(someOtherPlaintextPassword, hash, function(err, result) {
// result == false
});
*/
/*
//hash with salt
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
// Store hash in your password DB.
});
*/
async function hashAPIKey(apikey) {
return await bcrypt.hash(apikey, saltRounds);
}
async function compareAPIKey(apikey, hash) {
return await bcrypt.compare(apikey, hash);
}
module.exports = {
hashAPIKey,
compareAPIKey
};

View File

@ -1,18 +1,62 @@
function apiKeyMiddleware(req, res, next) {
const apiKey = req.headers['x-api-key'];
if (!apiKey) {
return res.status(401).json({ error: 'API key is missing' });
const { compareAPIKey } = require('../functions/bcrypt.js');
const { checkAPikey } = require('../functions/database.js');
async function apikeyCheck(req, res, next) {
//const authHeader = req.headers.authorization
try{
let apikey = req.headers.authorization
if(!apikey){
throw new Error('NotAuthed')
}
else{
//compare apikey to db
}
next()
}catch(error){
next(error);
}
//logic to check db?
if (apiKey !== 'YOUR_API_KEY') {
return res.status(403).json({ error: 'Invalid API key' });
}
// API key is valid, continue to the next middleware or route handler
next();
}
module.exports = { apiKeyMiddleware }
module.exports = { apikeyCheck };
/*
1) take user supplied api key
2) hash and salt
3) compare to stored hash and salt in db
4) if match, check permissions
5) if permissions allow, continue
6) else throw error
*/
/*
I plan to seed some data in user and api
Than use the system info and my API middleware will somehow check the supplied API key and check
If it's correct API key and has canWrite perms
I allow it to access put and post
async function auth(req, res, next){
try{
let token = // get token
req.token = token
if(req.method === 'GET' && token.canRead){
return next()
}
if(req.method === 'POST' && token.canWrite){
return next()
}
throw new Error('NotAuthed')
}catch(error){
next(error);
}
}
*/

View File

@ -2,6 +2,7 @@ const express = require("express");
const helmet = require("helmet");
const { rateLimit } = require("express-rate-limit");
const { APIlogger } = require('../middleware/apiLogger.js');
const { apikeyCheck } = require('../middleware/apiKey.js');
const app = express();
app.use(helmet());
@ -30,14 +31,10 @@ app.set("json spaces", 2);
/*
middleware logic ( called by next() )
*/
//app.use('/api/v0', require('../middleware/ApiKey.js'));
app.use('/api/v0', APIlogger, require('../routes/api_route.js'));
app.use("/api/seed/v0", [ apikeyCheck , APIlogger] ,require("../routes/seed_route.js"));
app.use('/api/v0', [apikeyCheck, APIlogger] ,require("../routes/api_route.js")); //webserver\routes\api_route.js
//route logic
app.use("/api/v0", require("../routes/api_route.js"));
//seed logic
app.use("/api/seed/v0", require("../routes/seed_route.js"));
// Catch 404 and forward to error handler. If none of the above routes are
// used, this is what will be called.

View File

@ -20,7 +20,7 @@ router.get("/", async (req, res, next) => {
next(error);
}
});
/*
//add location
router.post("/new", async (req, res, next) => {
@ -58,7 +58,7 @@ router.delete("/delete", async (req, res, next) => {
}
});
*/
//get location by id
router.get("/:id", async (req, res, next) => {

View File

@ -18,7 +18,7 @@ router.get("/", async (req, res, next) => {
next(error);
}
});
/*
router.post("/new", async (req, res, next) => {
try {
@ -52,7 +52,6 @@ router.delete("/delete", async (req, res, next) => {
next(error);
}
});
*/
router.get("/:id", async (req, res, next) => {
try {
const sensor = await getSensorById(req.params.id);

View File

@ -21,7 +21,7 @@ router.get("/", async (req, res, next) => {
next(error);
}
});
/*
router.post("/new", async (req, res, next) => {
try {
const { id, id_sensor, id_location, sensordata } = req.body;
@ -54,7 +54,6 @@ router.delete("/delete", async (req, res, next) => {
next(error);
}
});
*/
router.get("/data", async (req, res, next) => {
try {
console.log(req.query);