user managment
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
module.exports = {
|
||||
db: {
|
||||
connectionString: "mongodb://db:27017",
|
||||
dbName: "jucundus",
|
||||
},
|
||||
session: {
|
||||
sessionCollection: "Session",
|
||||
sessionConfig: {
|
||||
name: "jucundus.sid",
|
||||
cookie: {
|
||||
maxAge: 1000 * 60 * 60 * 24 * 30, // 30 days
|
||||
httpOnly: true, // only accessible by the server
|
||||
secure: true,
|
||||
},
|
||||
resave: false, // don't save session if unmodified
|
||||
saveUninitialized: true,
|
||||
}
|
||||
},
|
||||
jwtOptions: {
|
||||
issuer: "jucundus.com",
|
||||
audience: "yoursite",
|
||||
}
|
||||
};
|
||||
@@ -38,7 +38,6 @@ exports.getPictures = asyncHandler(async (req, res, next) => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
exports.getLotsBySale = asyncHandler(async (req, res, next) => {
|
||||
let id = req.params.id
|
||||
|
||||
@@ -165,3 +164,67 @@ exports.AuctionedItem = asyncHandler(async (req, res, next) => {
|
||||
}
|
||||
});
|
||||
|
||||
// DB
|
||||
exports.get = asyncHandler(async (req, res, next) => {
|
||||
|
||||
try{
|
||||
const id = req.params.id;
|
||||
let result = await lotDb.get(id);
|
||||
res.status(200).send(result);
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.post = asyncHandler(async (req, res, next) => {
|
||||
|
||||
try{
|
||||
// check if double
|
||||
let Lot = await lotDb.getByIDPlatform(req.body.idPlatform, req.body.platform);
|
||||
if(Sale){
|
||||
return res.status(500).send("Lot already exists");
|
||||
}
|
||||
|
||||
let createLot = await lotDb.post(req.body);
|
||||
|
||||
res.status(204).send();
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.put = asyncHandler(async (req, res, next) => {
|
||||
|
||||
try{
|
||||
const id = req.params.id;
|
||||
let updatedDocument = { ...req.body };
|
||||
delete updatedDocument._id;
|
||||
console.log(updatedDocument);
|
||||
let result = await lotDb.put(id, updatedDocument);
|
||||
console.log(result);
|
||||
res.status(200).send(result);
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.delete = asyncHandler(async (req, res, next) => {
|
||||
try{
|
||||
const id = req.params.id;
|
||||
|
||||
// Remove the lot
|
||||
await lotDb.remove(id);
|
||||
|
||||
res.status(200).send({"message": "Lots deleted"});
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
+164
-6
@@ -8,7 +8,7 @@ const lotDb = new LotDb();
|
||||
const agenda = require('../services/agenda');
|
||||
const {Agent} = require('../services/agent');
|
||||
const agent = new Agent();
|
||||
|
||||
const ExcelJS = require('exceljs');
|
||||
|
||||
exports.getSaleInfos = asyncHandler(async (req, res, next) => {
|
||||
let url = req.params.url
|
||||
@@ -218,31 +218,102 @@ exports.postProcessing = asyncHandler(async (req, res, next) => {
|
||||
}
|
||||
|
||||
Lots = await lotDb.getBySaleId(Sale._id.toString(),Sale.platform);
|
||||
|
||||
TimestampInSecond = (timestamp) => {
|
||||
const stringTimestamp = String(timestamp);
|
||||
if (stringTimestamp.length === 13) {
|
||||
return timestamp / 1000;
|
||||
} else if (stringTimestamp.length === 10) {
|
||||
return timestamp;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Create an array to hold the updated lots
|
||||
let updatedLots = [];
|
||||
let bidsDuration = 0;
|
||||
|
||||
// process each lot
|
||||
for (let lot of Lots) {
|
||||
let highestBid, duration, percentageAboveUnderLow, percentageAboveUnderHigh = 0;
|
||||
|
||||
// if bid
|
||||
let nbrBids = 0;
|
||||
if (Array.isArray(lot.Bids)) {
|
||||
|
||||
nbrBids = lot.Bids.length;
|
||||
|
||||
highestBid = lot.Bids.reduce((prev, current) => (prev.amount > current.amount) ? prev : current).amount;
|
||||
let startTime = TimestampInSecond(lot.Bids[0].timestamp);
|
||||
let endTime = TimestampInSecond(lot.Bids[lot.Bids.length-1].timestamp);
|
||||
duration = endTime - startTime;
|
||||
|
||||
// total time of bids
|
||||
bidsDuration += duration;
|
||||
|
||||
duration = duration.toFixed(0);
|
||||
}
|
||||
|
||||
// if auctioned
|
||||
percentageAboveUnderLow = 0;
|
||||
percentageAboveUnderHigh = 0;
|
||||
if (lot.auctioned) {
|
||||
|
||||
if(lot.EstimateLow){
|
||||
percentageAboveUnderLow = ((lot.auctioned.amount - lot.EstimateLow) / lot.EstimateLow) * 100;
|
||||
}
|
||||
|
||||
if(lot.EstimateHigh){
|
||||
percentageAboveUnderHigh = ((lot.auctioned.amount - lot.EstimateHigh) / lot.EstimateHigh) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
let lotPostProcessing = {
|
||||
nbrBids: nbrBids,
|
||||
highestBid: highestBid,
|
||||
duration: duration,
|
||||
percentageAboveUnderLow: percentageAboveUnderLow.toFixed(0),
|
||||
percentageAboveUnderHigh: percentageAboveUnderHigh.toFixed(0)
|
||||
}
|
||||
lot.postProcessing = lotPostProcessing;
|
||||
await lotDb.put(lot._id, lot);
|
||||
|
||||
// Add the updated lot to the array
|
||||
updatedLots.push(lot);
|
||||
}
|
||||
|
||||
// refresh with postprocess datas
|
||||
Lots = updatedLots;
|
||||
|
||||
|
||||
let startTime = 0;
|
||||
if (Array.isArray(Lots[0].Bids)) {
|
||||
startTime = Lots[0].Bids[0].timestamp;
|
||||
startTime = TimestampInSecond(Lots[0].Bids[0].timestamp);
|
||||
}else{
|
||||
startTime = Lots[0].timestamp;
|
||||
startTime = TimestampInSecond(Lots[0].timestamp);
|
||||
}
|
||||
|
||||
let LastBid = [...Lots].reverse().find(lot => lot.auctioned !== undefined);
|
||||
|
||||
let endTime = 0;
|
||||
if (Array.isArray(LastBid.Bids)) {
|
||||
endTime = LastBid.Bids[LastBid.Bids.length-1].timestamp;
|
||||
endTime = TimestampInSecond(LastBid.Bids[LastBid.Bids.length-1].timestamp);
|
||||
}else{
|
||||
endTime = LastBid.timestamp;
|
||||
endTime = TimestampInSecond(LastBid.timestamp);
|
||||
}
|
||||
console.log("Start Time: "+startTime);
|
||||
console.log("End Time: "+endTime);
|
||||
|
||||
let duration = endTime-startTime;
|
||||
let duration = (endTime-startTime).toFixed(0);
|
||||
|
||||
let totalAmount = 0;
|
||||
let unsoldLots = 0;
|
||||
for (let lot of Lots) {
|
||||
if (lot.auctioned) {
|
||||
totalAmount += lot.auctioned.amount;
|
||||
} else {
|
||||
unsoldLots++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +333,15 @@ exports.postProcessing = asyncHandler(async (req, res, next) => {
|
||||
let postProcessing = {
|
||||
nbrLots: Lots.length,
|
||||
duration: duration,
|
||||
bidsDuration: bidsDuration.toFixed(0),
|
||||
durationPerLots: (duration/Lots.length).toFixed(0),
|
||||
totalAmount: totalAmount,
|
||||
averageAmount: (totalAmount/Lots.length).toFixed(2),
|
||||
medianAmount: calculateMedian(amounts).toFixed(2),
|
||||
minAmount: Math.min(...amounts).toFixed(2),
|
||||
maxAmount: Math.max(...amounts).toFixed(2),
|
||||
unsoldLots: unsoldLots,
|
||||
unsoldPercentage: ((unsoldLots/Lots.length)*100).toFixed(2)
|
||||
}
|
||||
|
||||
console.log(postProcessing);
|
||||
@@ -279,4 +355,86 @@ exports.postProcessing = asyncHandler(async (req, res, next) => {
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.SaleStatXsl = asyncHandler(async (req, res, next) => {
|
||||
try{
|
||||
const id = req.params.id;
|
||||
|
||||
Sale = await saleDb.get(id);
|
||||
if(!Sale){
|
||||
console.error("Sale not found");
|
||||
return res.status(404).send("Sale not found");
|
||||
}
|
||||
|
||||
Lots = await lotDb.getBySaleId(Sale._id.toString(),Sale.platform);
|
||||
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const worksheet = workbook.addWorksheet('Sale Stats');
|
||||
|
||||
worksheet.columns = [
|
||||
{ header: 'Lot #', key: 'lotNumber', width: 10 },
|
||||
{ header: 'Description', key: 'description', width: 100 },
|
||||
{ header: 'Auctioned Amount', key: 'auctionedAmount', width: 20 },
|
||||
{ header: 'Estimate Low', key: 'estimateLow', width: 20 },
|
||||
{ header: 'Estimate High', key: 'estimateHigh', width: 20 },
|
||||
{ header: 'Bids', key: 'nbrBids', width: 10 },
|
||||
{ header: 'Highest Bid', key: 'highestBid', width: 20 },
|
||||
{ header: 'Duration (in s)', key: 'duration', width: 10 },
|
||||
{ header: '% Above Low', key: 'percentageAboveUnderLow', width: 20 },
|
||||
{ header: '% Above High', key: 'percentageAboveUnderHigh', width: 20 }
|
||||
];
|
||||
|
||||
let row = 2;
|
||||
for (let lot of Lots) {
|
||||
let Row = worksheet.addRow({
|
||||
lotNumber: lot.lotNumber,
|
||||
description: lot.description,
|
||||
auctionedAmount: lot.auctioned?.amount,
|
||||
estimateLow: lot.EstimateLow,
|
||||
estimateHigh: lot.EstimateHigh,
|
||||
nbrBids: lot.postProcessing?.nbrBids,
|
||||
highestBid: lot.postProcessing?.highestBid,
|
||||
duration: lot.postProcessing?.duration,
|
||||
percentageAboveUnderLow: lot.postProcessing?.percentageAboveUnderLow/100,
|
||||
percentageAboveUnderHigh: lot.postProcessing?.percentageAboveUnderHigh/100
|
||||
});
|
||||
|
||||
Row.getCell('C').numFmt = '€0.00';
|
||||
Row.getCell('D').numFmt = '€0.00';
|
||||
Row.getCell('E').numFmt = '€0.00';
|
||||
Row.getCell('B').numFmt = '€0.00';
|
||||
Row.getCell('G').numFmt = '€0.00';
|
||||
|
||||
Row.getCell('I').numFmt = '0%';
|
||||
Row.getCell('J').numFmt = '0%';
|
||||
|
||||
row++;
|
||||
}
|
||||
|
||||
worksheet.addRow({
|
||||
lotNumber: 'Total',
|
||||
auctionedAmount: Sale.postProcessing?.totalAmount,
|
||||
estimateLow: '',
|
||||
estimateHigh: '',
|
||||
nbrBids: '',
|
||||
highestBid: '',
|
||||
duration: Sale.postProcessing?.duration,
|
||||
percentageAboveUnderLow: '',
|
||||
percentageAboveUnderHigh: ''
|
||||
});
|
||||
|
||||
// send the Xls File
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
"attachment; filename=" + "SaleStats.xlsx"
|
||||
);
|
||||
|
||||
await workbook.xlsx.write(res);
|
||||
return res.status(200).end();
|
||||
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,199 @@
|
||||
const asyncHandler = require("express-async-handler");
|
||||
const moment = require('moment-timezone');
|
||||
const { ObjectId } = require('mongodb');
|
||||
const { UserDb } = require("../services/userDb");
|
||||
const crypto = require('crypto');
|
||||
|
||||
function ClearUserData(user){
|
||||
delete user.salt;
|
||||
delete user.hashed_password;
|
||||
delete user.salt;
|
||||
delete user.isAgent;
|
||||
return user;
|
||||
}
|
||||
|
||||
function ClearUserDataForAdmin(user){
|
||||
delete user.salt;
|
||||
delete user.hashed_password;
|
||||
delete user.salt;
|
||||
return user;
|
||||
}
|
||||
|
||||
// DB
|
||||
exports.get = asyncHandler(async (req, res, next) => {
|
||||
|
||||
try{
|
||||
const userDb = await UserDb.init();
|
||||
const id = req.params.id;
|
||||
let result = await userDb.get(id);
|
||||
if (req.user.isAdmin){
|
||||
res.status(200).send(ClearUserDataForAdmin(result));
|
||||
}else{
|
||||
res.status(200).send(ClearUserData(result));
|
||||
}
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.post = asyncHandler(async (req, res, next) => {
|
||||
|
||||
try{
|
||||
const userDb = await UserDb.init();
|
||||
// check if double
|
||||
let User = await userDb.getByEmail(req.body.email);
|
||||
if(User){
|
||||
return res.status(500).send("User already exists");
|
||||
}
|
||||
|
||||
// check password
|
||||
if(!req.body.password){
|
||||
return res.status(500).send("Password not set");
|
||||
}
|
||||
if(req.body.password != req.body.confirmPassword){
|
||||
return res.status(500).send("Passwords do not match");
|
||||
}
|
||||
if(req.body.password.length < 8){
|
||||
return res.status(500).send("Password too short");
|
||||
}
|
||||
|
||||
if(req.body.isAdmin){
|
||||
if(req.user){
|
||||
if(!req.user.isAdmin){
|
||||
return res.status(500).send("You are not allowed to create an admin user");
|
||||
}
|
||||
}else{
|
||||
req.body.isAdmin = false
|
||||
}
|
||||
}
|
||||
|
||||
if(req.body.isAgent){
|
||||
if(req.user){
|
||||
if(!req.user.isAgent){
|
||||
return res.status(500).send("You are not allowed to create an agent user");
|
||||
}
|
||||
}else{
|
||||
req.body.isAgent = false
|
||||
}
|
||||
}
|
||||
|
||||
let salt = crypto.randomBytes(16).toString('hex');
|
||||
let user = {
|
||||
username: req.body.username,
|
||||
hashed_password: crypto.pbkdf2Sync(req.body.password, salt, 310000, 32, 'sha256').toString('hex'),
|
||||
salt: salt,
|
||||
email: req.body.email,
|
||||
isAdmin: req.body.isAdmin,
|
||||
isAgent: req.body.isAgent,
|
||||
}
|
||||
|
||||
let createData = await userDb.post(user);
|
||||
|
||||
res.status(204).send();
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.put = asyncHandler(async (req, res, next) => {
|
||||
|
||||
try{
|
||||
const userDb = await UserDb.init();
|
||||
const id = req.params.id;
|
||||
|
||||
const User = await userDb.get(id);
|
||||
if(!User){
|
||||
return res.status(500).send("User not found");
|
||||
}
|
||||
|
||||
// check password
|
||||
let hashed_password = "";
|
||||
let salt = "";
|
||||
if(req.body.password){
|
||||
if(req.body.password != req.body.confirmPassword){
|
||||
return res.status(500).send("Passwords do not match");
|
||||
}
|
||||
if(req.body.password.length < 8){
|
||||
return res.status(500).send("Password too short");
|
||||
}
|
||||
salt = crypto.randomBytes(16).toString('hex');
|
||||
hashed_password = crypto.pbkdf2Sync(req.body.password, salt, 310000, 32, 'sha256').toString('hex');
|
||||
}else{
|
||||
salt = User.salt;
|
||||
hashed_password = User.hashed_password;
|
||||
}
|
||||
|
||||
if(req.body.isAdmin){
|
||||
if(!req.user.isAdmin){
|
||||
return res.status(500).send("You are not allowed to create an admin user");
|
||||
}
|
||||
}
|
||||
if(req.body.isAgent){
|
||||
if(!req.user.isAdmin){
|
||||
return res.status(500).send("You are not allowed to create an agent user");
|
||||
}
|
||||
}
|
||||
|
||||
let user = {
|
||||
username: req.body.username,
|
||||
hashed_password: hashed_password,
|
||||
salt: salt,
|
||||
email: req.body.email,
|
||||
isAdmin: req.body.isAdmin,
|
||||
isAgent: req.body.isAgent,
|
||||
}
|
||||
|
||||
let result = await userDb.put(id, user);
|
||||
console.log(result);
|
||||
res.status(200).send(result);
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.delete = asyncHandler(async (req, res, next) => {
|
||||
try{
|
||||
const userDb = await UserDb.init();
|
||||
const id = req.params.id;
|
||||
|
||||
// Remove the sale
|
||||
await userDb.remove(id);
|
||||
|
||||
res.status(200).send({"message": "User deleted"});
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Functions
|
||||
exports.current = asyncHandler(async (req, res, next) => {
|
||||
try{
|
||||
const user = ClearUserData(req.user);
|
||||
res.status(200).send(user);
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
exports.getAllUsers = asyncHandler(async (req, res, next) => {
|
||||
try{
|
||||
const userDb = await UserDb.init();
|
||||
let result = await userDb.getAll();
|
||||
result = result.map(user => ClearUserDataForAdmin(user));
|
||||
res.status(200).send(result);
|
||||
}catch(err){
|
||||
console.log(err);
|
||||
return res.status(500).send(err);
|
||||
}
|
||||
|
||||
});
|
||||
+46
-2
@@ -1,3 +1,4 @@
|
||||
const config = require("./config.js");
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
|
||||
@@ -9,17 +10,60 @@ app.use(cors());
|
||||
// Enable preflight requests for all routes
|
||||
app.options('*', cors());
|
||||
|
||||
|
||||
// Session support
|
||||
const session = require('express-session');
|
||||
app.use(session({
|
||||
secret: 'jucundus.ses',
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
cookie: { secure: true }
|
||||
}))
|
||||
// const MongoStore = require('connect-mongo');
|
||||
|
||||
// const keys = require("./.Keys.js");
|
||||
|
||||
// const sassionConfig = {
|
||||
// ...config.session.sessionConfig,
|
||||
// secret: keys.session,
|
||||
// store: MongoStore.create({
|
||||
// mongoUrl: `${config.db.connectionString}/${config.db.dbName}`,
|
||||
// collection: config.session.sessionCollection,
|
||||
// stringify: false,
|
||||
// autoReconnect: true,
|
||||
// autoRemove: 'native'
|
||||
// })};
|
||||
|
||||
// app.use(session(sassionConfig));
|
||||
|
||||
// Authentication
|
||||
const passport = require('passport');
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
|
||||
app.use('/', require('./routes/auth'));
|
||||
|
||||
|
||||
// Agenda Scheduller
|
||||
const agenda = require('./services/agenda');
|
||||
(async function() {
|
||||
|
||||
//lunch sheduller
|
||||
await agenda.start();
|
||||
})();
|
||||
|
||||
|
||||
//create first user
|
||||
const { UserDb } = require('./services/userDb');
|
||||
const userDb = await UserDb.init();
|
||||
userDb.creatFirstUserifEmpty();
|
||||
|
||||
})();
|
||||
|
||||
// Agenda UI
|
||||
var Agendash = require("agendash");
|
||||
app.use("/dash", Agendash(agenda));
|
||||
|
||||
// routes
|
||||
app.use('/api/user', require('./routes/user'));
|
||||
app.use('/api/lot', require('./routes/lot'));
|
||||
app.use('/api/sale', require('./routes/sale'));
|
||||
app.use('/api/favorite', require('./routes/favorite'));
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
function checkIsConcernedUserOrAdmin(req, res, next) {
|
||||
const user = req.user; // User is set by Passport
|
||||
const userIdParam = req.params.id;
|
||||
|
||||
if (user.isAdmin === true || user._id === userIdParam) {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
}
|
||||
|
||||
function checkIsAdmin(req, res, next) {
|
||||
const user = req.user; // User is set by Passport
|
||||
|
||||
if (user.isAdmin === true) {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
}
|
||||
|
||||
function checkIsAgent(req, res, next) {
|
||||
const user = req.user; // User is set by Passport
|
||||
|
||||
if (user.isAgent === true) {
|
||||
next();
|
||||
} else {
|
||||
res.status(403).json({ error: 'Forbidden' });
|
||||
}
|
||||
}
|
||||
module.exports = { checkIsConcernedUserOrAdmin, checkIsAgent, checkIsAdmin };
|
||||
Generated
+1111
-30
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js",
|
||||
"dev": "nodemon --watch ./ server.js --ignore node_modules/"
|
||||
"dev": "nodemon --inspect=0.0.0.0 --watch ./ server.js --ignore node_modules/"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
@@ -15,11 +15,18 @@
|
||||
"@angular/cli": "^17.1.3",
|
||||
"@hokify/agenda": "^6.3.0",
|
||||
"agendash": "^4.0.0",
|
||||
"connect-mongo": "^5.1.0",
|
||||
"cors": "^2.8.5",
|
||||
"exceljs": "^4.4.0",
|
||||
"express": "^4.18.2",
|
||||
"express-async-handler": "^1.2.0",
|
||||
"express-session": "^1.18.0",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"mongodb": "^6.5.0",
|
||||
"node-fetch": "^2.7.0"
|
||||
"node-fetch": "^2.7.0",
|
||||
"passport": "^0.7.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.0.3"
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
var passport = require('passport');
|
||||
var LocalStrategy = require('passport-local');
|
||||
var crypto = require('crypto');
|
||||
const router = require('express').Router()
|
||||
const config = require("../config.js");
|
||||
const keys = require("../.Keys.js");
|
||||
|
||||
/* Configure password authentication strategy.
|
||||
*
|
||||
* The `LocalStrategy` authenticates users by verifying a username and password.
|
||||
* The strategy parses the username and password from the request and calls the
|
||||
* `verify` function.
|
||||
*
|
||||
* The `verify` function queries the database for the user record and verifies
|
||||
* the password by hashing the password supplied by the user and comparing it to
|
||||
* the hashed password stored in the database. If the comparison succeeds, the
|
||||
* user is authenticated; otherwise, not.
|
||||
*/
|
||||
const { UserDb }= require('../services/userDb');
|
||||
|
||||
passport.use(new LocalStrategy({
|
||||
usernameField: 'email',
|
||||
passwordField: 'password'
|
||||
},async function verify(email, password, cb) {
|
||||
try {
|
||||
const userDb = await UserDb.init();
|
||||
const user = await userDb.getByEmail(email);
|
||||
if (!user) {
|
||||
return cb(null, false, { message: 'Incorrect username or password.' });
|
||||
}
|
||||
|
||||
crypto.pbkdf2(password, user.salt, 310000, 32, 'sha256', async function(err, hashedPassword) {
|
||||
if (err) { return cb(err); }
|
||||
if (!crypto.timingSafeEqual(Buffer.from(user.hashed_password, 'hex'), Buffer.from(hashedPassword, 'hex'))) {
|
||||
return cb(null, false, { message: 'Incorrect username or password.' });
|
||||
}
|
||||
return cb(null, user);
|
||||
});
|
||||
} catch (err) {
|
||||
return cb(err);
|
||||
}
|
||||
}));
|
||||
|
||||
/* Configure session management.
|
||||
*
|
||||
* When a login session is established, information about the user will be
|
||||
* stored in the session. This information is supplied by the `serializeUser`
|
||||
* function, which is yielding the user ID and username.
|
||||
*
|
||||
* As the user interacts with the app, subsequent requests will be authenticated
|
||||
* by verifying the session. The same user information that was serialized at
|
||||
* session establishment will be restored when the session is authenticated by
|
||||
* the `deserializeUser` function.
|
||||
*
|
||||
* Since every request to the app needs the user ID and username, in order to
|
||||
* fetch todo records and render the user element in the navigation bar, that
|
||||
* information is stored in the session.
|
||||
*/
|
||||
passport.serializeUser(function(user, cb) {
|
||||
process.nextTick(function() {
|
||||
cb(null, { id: user._id, username: user.email });
|
||||
});
|
||||
});
|
||||
|
||||
passport.deserializeUser(function(user, cb) {
|
||||
process.nextTick(function() {
|
||||
return cb(null, user);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// JWT
|
||||
var jwt = require('jsonwebtoken');
|
||||
var JwtStrategy = require('passport-jwt').Strategy,
|
||||
ExtractJwt = require('passport-jwt').ExtractJwt;
|
||||
var opts = {}
|
||||
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
|
||||
opts.secretOrKey = keys.jwt;
|
||||
opts.issuer = config.jwtOptions.issuer;
|
||||
opts.audience = config.jwtOptions.audience;
|
||||
passport.use(new JwtStrategy(opts, async function(jwt_payload, done) {
|
||||
const userDb = await UserDb.init();
|
||||
try {
|
||||
const user = await userDb.get(jwt_payload.sub);
|
||||
if (user) {
|
||||
return done(null, user);
|
||||
} else {
|
||||
return done(null, false);
|
||||
// or you could create a new account
|
||||
}
|
||||
} catch (err) {
|
||||
return done(err, false);
|
||||
}
|
||||
}));
|
||||
|
||||
router.post('/authenticate', async function(req, res) {
|
||||
passport.authenticate('local', async function(err, user, info) {
|
||||
if (err) { return res.status(500).json({message: err.message}); }
|
||||
if (!user) { return res.status(401).json({message: 'Incorrect email or password.'}); }
|
||||
|
||||
// User found, generate a JWT for the user
|
||||
var token = jwt.sign({ sub: user._id, email: user.email }, opts.secretOrKey, {
|
||||
issuer: opts.issuer,
|
||||
audience: opts.audience,
|
||||
expiresIn: 86400 * 30 // 30 days
|
||||
});
|
||||
res.json({ token: token });
|
||||
//return res.status(500).json({message: 'Incorrect email or password.'})
|
||||
|
||||
})(req, res);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
@@ -1,7 +1,9 @@
|
||||
const controllers = require('../controllers/favorite')
|
||||
const router = require('express').Router()
|
||||
const passport = require('passport');
|
||||
const { checkIsConcernedUserOrAdmin } = require('../middleware/authMiddleware')
|
||||
|
||||
router.post('/save/', controllers.save)
|
||||
router.get('/getAll/', controllers.getAll)
|
||||
router.post('/save/', passport.authenticate('jwt', { session: false }), controllers.save)
|
||||
router.get('/getAll/', passport.authenticate('jwt', { session: false }), controllers.getAll)
|
||||
|
||||
module.exports = router
|
||||
+15
-6
@@ -1,12 +1,21 @@
|
||||
const controllers = require('../controllers/lot')
|
||||
const router = require('express').Router()
|
||||
const passport = require('passport');
|
||||
const { checkIsAgent, checkIsAdmin } = require('../middleware/authMiddleware')
|
||||
|
||||
router.get('/getInfos/:url', controllers.getInfos)
|
||||
router.get('/getPictures/:url', controllers.getPictures)
|
||||
router.get('/getLotsBySale/:id', controllers.getLotsBySale)
|
||||
router.get('/getInfos/:url', passport.authenticate('jwt', { session: false }), controllers.getInfos)
|
||||
router.get('/getPictures/:url', passport.authenticate('jwt', { session: false }), controllers.getPictures)
|
||||
router.get('/getLotsBySale/:id', passport.authenticate('jwt', { session: false }), controllers.getLotsBySale)
|
||||
|
||||
router.post('/NextItem/', controllers.NextItem)
|
||||
router.post('/AuctionedItem/', controllers.AuctionedItem)
|
||||
router.post('/Bid/', controllers.Bid)
|
||||
// DB
|
||||
router.get('/lot/:id', passport.authenticate('jwt', { session: false }), checkIsAdmin, controllers.get)
|
||||
router.post('/lot/', passport.authenticate('jwt', { session: false }), checkIsAdmin, controllers.post)
|
||||
router.put('/lot/:id', passport.authenticate('jwt', { session: false }), checkIsAdmin, controllers.put)
|
||||
router.delete('/lot/:id', passport.authenticate('jwt', { session: false }), checkIsAdmin, controllers.delete)
|
||||
|
||||
// Live Data
|
||||
router.post('/NextItem/', checkIsAgent, controllers.NextItem)
|
||||
router.post('/AuctionedItem/', checkIsAgent, controllers.AuctionedItem)
|
||||
router.post('/Bid/', checkIsAgent, controllers.Bid)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,4 +1,5 @@
|
||||
const controllers = require('../controllers/sale')
|
||||
const passport = require('passport');
|
||||
const router = require('express').Router()
|
||||
|
||||
// AuctionAgent
|
||||
@@ -13,9 +14,11 @@ router.post('/sale/', controllers.post)
|
||||
router.put('/sale/:id', controllers.put)
|
||||
router.delete('/sale/:id', controllers.delete)
|
||||
|
||||
router.get('/getAll/', controllers.getAll)
|
||||
//router.get('/getAll/', controllers.getAll)
|
||||
router.get('/getAll/', passport.authenticate('jwt', { session: false }), controllers.getAll);
|
||||
router.get('/getByUrl/:url', controllers.getByUrl)
|
||||
router.get('/postProcessing/:id', controllers.postProcessing)
|
||||
router.get('/SaleStatXsl/:id', controllers.SaleStatXsl)
|
||||
|
||||
|
||||
module.exports = router
|
||||
@@ -0,0 +1,15 @@
|
||||
const controllers = require('../controllers/user')
|
||||
const passport = require('passport');
|
||||
const router = require('express').Router()
|
||||
const { checkIsConcernedUserOrAdmin, checkIsAdmin } = require('../middleware/authMiddleware')
|
||||
|
||||
// DB
|
||||
router.get('/user/:id', passport.authenticate('jwt', { session: false }), checkIsConcernedUserOrAdmin, controllers.get);
|
||||
router.post('/user/', controllers.post)
|
||||
router.put('/user/:id', passport.authenticate('jwt', { session: false }), checkIsConcernedUserOrAdmin, controllers.put)
|
||||
router.delete('/user/:id', passport.authenticate('jwt', { session: false }), checkIsConcernedUserOrAdmin, controllers.delete)
|
||||
|
||||
router.get('/current', passport.authenticate('jwt', { session: false }), controllers.current)
|
||||
router.get('/getAllUsers', passport.authenticate('jwt', { session: false }), checkIsAdmin, controllers.getAllUsers)
|
||||
|
||||
module.exports = router
|
||||
@@ -1,5 +1,6 @@
|
||||
const MongoClient = require("mongodb").MongoClient;
|
||||
const connectionString = "mongodb://db:27017";
|
||||
const config = require("../config.js");
|
||||
const connectionString = config.db.connectionString;
|
||||
const client = new MongoClient(connectionString);
|
||||
|
||||
let db;
|
||||
@@ -8,7 +9,7 @@ const connectDb = async () => {
|
||||
if (db) return db;
|
||||
try {
|
||||
const conn = await client.connect();
|
||||
db = conn.db("jucundus");
|
||||
db = conn.db(config.db.dbName);
|
||||
return db;
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
const { ObjectId } = require('mongodb');
|
||||
const connectDb = require("./db");
|
||||
const crypto = require('crypto');
|
||||
|
||||
const UserDb = class
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
}
|
||||
|
||||
static async init() {
|
||||
const userDb = new UserDb();
|
||||
await userDb.getCollection();
|
||||
return userDb;
|
||||
}
|
||||
|
||||
async getCollection()
|
||||
{
|
||||
const db = await connectDb();
|
||||
if (!db) {
|
||||
throw new Error('Database not connected');
|
||||
}
|
||||
this.collection = db.collection("Users");
|
||||
}
|
||||
|
||||
// CRUD
|
||||
async get(id)
|
||||
{
|
||||
let result = await this.collection.findOne({_id: new ObjectId(id)});
|
||||
return result;
|
||||
}
|
||||
|
||||
async post(newDocument)
|
||||
{
|
||||
delete newDocument._id;
|
||||
let result = await this.collection.insertOne(newDocument);
|
||||
return result;
|
||||
}
|
||||
|
||||
async put(id, data)
|
||||
{
|
||||
delete data._id;
|
||||
let result = await this.collection.updateOne({_id: new ObjectId(id)}, {$set: data});
|
||||
return result;
|
||||
}
|
||||
|
||||
async remove(id)
|
||||
{
|
||||
let result = await this.collection.deleteOne({_id: new ObjectId(id)});
|
||||
return result;
|
||||
}
|
||||
|
||||
// Functions
|
||||
|
||||
async getAll()
|
||||
{
|
||||
let result = await this.collection.find({}).toArray();
|
||||
return result;
|
||||
}
|
||||
|
||||
async getByUsername(username)
|
||||
{
|
||||
let result = await this.collection.findOne({username: username});
|
||||
return result;
|
||||
}
|
||||
async getByEmail(email)
|
||||
{
|
||||
let result = await this.collection.findOne({email: email});
|
||||
return result;
|
||||
}
|
||||
|
||||
async creatFirstUserifEmpty( ){
|
||||
const allUsers = await this.getAll();
|
||||
if(allUsers.length == 0){
|
||||
console.log("Creating first user");
|
||||
let salt = crypto.randomBytes(16).toString('hex');
|
||||
let user = {
|
||||
username: "admin",
|
||||
hashed_password: crypto.pbkdf2Sync('admin', salt, 310000, 32, 'sha256').toString('hex'),
|
||||
salt: salt,
|
||||
email: "admin@admin.com",
|
||||
isAdmin: true,
|
||||
isAgent: false,
|
||||
|
||||
}
|
||||
this.post(user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { UserDb };
|
||||
Reference in New Issue
Block a user