diff --git a/backend/config.js b/backend/config.js index 561d12a..581c3bf 100644 --- a/backend/config.js +++ b/backend/config.js @@ -1,4 +1,4 @@ -module.exports = { +const config = { db: { connectionString: "mongodb://db:27017", dbName: "jucundus", @@ -19,5 +19,11 @@ module.exports = { jwtOptions: { issuer: "jucundus.com", audience: "yoursite", + }, + agent :{ + ApiAgentURL: 'http://host.docker.internal:3020/api', + token: '861v48gr4YTHJTUre0reg40g8e6r8r64eggv1r4e6g4r81PKREVJ8g6reg46r8eg416reST6ger84g14er86e', } -}; \ No newline at end of file +}; + +module.exports = { config }; \ No newline at end of file diff --git a/backend/controllers/user.js b/backend/controllers/user.js index 6d63242..30b4f9e 100644 --- a/backend/controllers/user.js +++ b/backend/controllers/user.js @@ -185,6 +185,16 @@ exports.current = asyncHandler(async (req, res, next) => { }); + +exports.agentConnected = asyncHandler(async (req, res, next) => { + try{ + res.status(200).send("OK"); + }catch(err){ + console.log(err); + return res.status(500).send(err); + } +}); + exports.getAllUsers = asyncHandler(async (req, res, next) => { try{ const userDb = await UserDb.init(); diff --git a/backend/middleware/authMiddleware.js b/backend/middleware/authMiddleware.js index 7d16aa0..992c996 100644 --- a/backend/middleware/authMiddleware.js +++ b/backend/middleware/authMiddleware.js @@ -1,33 +1,53 @@ +const passport = require('passport'); +function Admited(acceptedRoles){ + return (req, res, next) => { + + // if Unconnected accepted + if (acceptedRoles.includes('Unconnected') || acceptedRoles.length == 0){ + next(); + } -function checkIsConcernedUserOrAdmin(req, res, next) { - const user = req.user; // User is set by Passport - const userIdParam = req.params.id; + passport.authenticate('jwt', { session: false }, (err, user, info) => { + + if (err) { + // An error occurred, return a JSON error response + return res.status(500).json({ error: "An error occurred" }); + } + if (!user) { + // User not authenticated, return a JSON error response + console.log('User not authenticated'); + return res.status(401).json({ error: "User not authenticated" }); + } + // User authenticated, attach user to request and proceed + req.user = user; - if (user.isAdmin === true || user._id === userIdParam) { - next(); - } else { - res.status(403).json({ error: 'Forbidden' }); + // Determine the user's role + let userRoles = []; + if (user.isAdmin) { + userRoles.push('Admin'); + } + if (user.isAgent) { + userRoles.push('Agent') + } + if (user._id.toString() === req.params.id) { + userRoles.push('ConcernedUser') + } + if (user) { + userRoles.push('NormalUser') + } + + // Check if any of the user's roles are in the list of accepted roles + const isAuthorized = userRoles.some(role => acceptedRoles.includes(role)); + + // Check if the user's role is in the list of accepted roles + if (isAuthorized) { + next(); // User's role is accepted, proceed to the next middleware/controller + } else { + res.status(403).json({ error: 'Forbidden' }); // User's role is not accepted, return 403 Forbidden + } + })(req, res, next); + } } - - 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 }; \ No newline at end of file + module.exports = { Admited }; \ No newline at end of file diff --git a/backend/routes/auth.js b/backend/routes/auth.js index a446fe3..ae95af6 100644 --- a/backend/routes/auth.js +++ b/backend/routes/auth.js @@ -2,7 +2,7 @@ var passport = require('passport'); var LocalStrategy = require('passport-local'); var crypto = require('crypto'); const router = require('express').Router() -const config = require("../config.js"); +const {config} = require("../config.js"); const keys = require("../.Keys.js"); /* Configure password authentication strategy. @@ -98,13 +98,17 @@ router.post('/authenticate', async function(req, res) { if (err) { return res.status(500).json({message: err.message}); } if (!user) { return res.status(401).json({message: 'Incorrect email or password.'}); } + console.log('/authenticate: '+user.username); + // 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 }); + console.log('Token: '+token); res.json({ token: token }); + //return res.status(500).json({message: 'Incorrect email or password.'}) })(req, res); diff --git a/backend/routes/favorite.js b/backend/routes/favorite.js index 55c8b60..75c2bd6 100644 --- a/backend/routes/favorite.js +++ b/backend/routes/favorite.js @@ -1,9 +1,8 @@ const controllers = require('../controllers/favorite') const router = require('express').Router() -const passport = require('passport'); -const { checkIsConcernedUserOrAdmin } = require('../middleware/authMiddleware') +const { Admited } = require('../middleware/authMiddleware') -router.post('/save/', passport.authenticate('jwt', { session: false }), controllers.save) -router.get('/getAll/', passport.authenticate('jwt', { session: false }), controllers.getAll) +router.post('/save/', Admited(['NormalUser']), controllers.save) +router.get('/getAll/', Admited(['NormalUser']), controllers.getAll) module.exports = router \ No newline at end of file diff --git a/backend/routes/lot.js b/backend/routes/lot.js index 328d9d0..eba9367 100644 --- a/backend/routes/lot.js +++ b/backend/routes/lot.js @@ -1,21 +1,20 @@ const controllers = require('../controllers/lot') const router = require('express').Router() -const passport = require('passport'); -const { checkIsAgent, checkIsAdmin } = require('../middleware/authMiddleware') +const { Admited } = require('../middleware/authMiddleware') -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.get('/getInfos/:url', Admited(['NormalUser']), controllers.getInfos) +router.get('/getPictures/:url', Admited(['NormalUser']), controllers.getPictures) +router.get('/getLotsBySale/:id', Admited(['NormalUser']), controllers.getLotsBySale) // 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) +router.get('/lot/:id', Admited(['Admin']), controllers.get) +router.post('/lot/', Admited(['Admin']), controllers.post) +router.put('/lot/:id', Admited(['Admin']), controllers.put) +router.delete('/lot/:id', Admited(['Admin']), controllers.delete) // Live Data -router.post('/NextItem/', checkIsAgent, controllers.NextItem) -router.post('/AuctionedItem/', checkIsAgent, controllers.AuctionedItem) -router.post('/Bid/', checkIsAgent, controllers.Bid) +router.post('/NextItem/', Admited(['Agent', 'Admin']), controllers.NextItem) +router.post('/AuctionedItem/', Admited(['Agent', 'Admin']), controllers.AuctionedItem) +router.post('/Bid/', Admited(['Agent', 'Admin']), controllers.Bid) module.exports = router \ No newline at end of file diff --git a/backend/routes/sale.js b/backend/routes/sale.js index e165faf..fbb886a 100644 --- a/backend/routes/sale.js +++ b/backend/routes/sale.js @@ -1,24 +1,24 @@ const controllers = require('../controllers/sale') -const passport = require('passport'); const router = require('express').Router() +const { Admited } = require('../middleware/authMiddleware') // AuctionAgent -router.get('/getSaleInfos/:url', controllers.getSaleInfos) -router.get('/prepareSale/:id', controllers.prepareSale) -router.get('/followSale/:id', controllers.followSale) +router.get('/getSaleInfos/:url', Admited(['NormalUser']), controllers.getSaleInfos) +router.get('/prepareSale/:id', Admited(['NormalUser']), controllers.prepareSale) +router.get('/followSale/:id', Admited(['NormalUser']), controllers.followSale) // DB -router.get('/sale/:id', controllers.get) -router.post('/sale/', controllers.post) -router.put('/sale/:id', controllers.put) -router.delete('/sale/:id', controllers.delete) +router.get('/sale/:id', Admited(['Admin']), controllers.get) +router.post('/sale/', Admited(['Admin']), controllers.post) +router.put('/sale/:id', Admited(['Admin', 'Agent']), controllers.put) +router.delete('/sale/:id', Admited(['Admin']), controllers.delete) -//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) + +router.get('/getAll/', Admited(['Admin']), controllers.getAll); +router.get('/getByUrl/:url', Admited(['Agent', 'Admin']), controllers.getByUrl) +router.get('/postProcessing/:id', Admited(['Admin']), controllers.postProcessing) +router.get('/SaleStatXsl/:id', Admited(['Admin']), controllers.SaleStatXsl) module.exports = router \ No newline at end of file diff --git a/backend/routes/user.js b/backend/routes/user.js index a6324db..a93b1e0 100644 --- a/backend/routes/user.js +++ b/backend/routes/user.js @@ -1,15 +1,15 @@ const controllers = require('../controllers/user') -const passport = require('passport'); const router = require('express').Router() -const { checkIsConcernedUserOrAdmin, checkIsAdmin } = require('../middleware/authMiddleware') +const { Admited } = 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('/user/:id', Admited(['Admin', 'ConcernedUser']), controllers.get); +router.post('/user/', Admited(['Unconnected']), controllers.post) +router.put('/user/:id', Admited(['Admin', 'ConcernedUser']), controllers.put) +router.delete('/user/:id', Admited(['Admin', 'ConcernedUser']), controllers.delete) -router.get('/current', passport.authenticate('jwt', { session: false }), controllers.current) -router.get('/getAllUsers', passport.authenticate('jwt', { session: false }), checkIsAdmin, controllers.getAllUsers) +router.get('/current', Admited(['NormalUser']), controllers.current) +router.get('/agentConnected', Admited(['Agent']), controllers.agentConnected) +router.get('/getAllUsers', Admited(['Admin']), controllers.getAllUsers) module.exports = router \ No newline at end of file diff --git a/backend/services/agent.js b/backend/services/agent.js index 91d4139..08c1f8b 100644 --- a/backend/services/agent.js +++ b/backend/services/agent.js @@ -4,20 +4,39 @@ const lotDb = new LotDb(); const { SaleDb } = require("./saleDb"); const saleDb = new SaleDb(); const moment = require('moment-timezone'); +const { config } = require("../config.js"); const Agent = class { constructor() { - this.ApiAgentURL = "http://host.docker.internal:3020/api"; + this.ApiAgentURL = config.agent.ApiAgentURL; + this.token = config.agent.token; + } + + async request(url, method){ + return new Promise((resolve, reject) => { + fetch(url,{ + method: method, + headers: { + 'authorization': this.token + } + }) + .then(response => response.json()) + .then(data => { + resolve(data); + }) + .catch(error => { + reject(error); + }); + }); } async getSaleInfos(url) { return new Promise((resolve, reject) => { url = encodeURIComponent(url); - fetch(this.ApiAgentURL+'/sale/getSaleInfos/'+url) - .then(response => response.json()) + this.request(this.ApiAgentURL+'/sale/getSaleInfos/'+url, 'GET') .then(data => { resolve(data); }) @@ -40,9 +59,7 @@ const Agent = class let url = Sale.url url = encodeURIComponent(url); - - fetch(this.ApiAgentURL+'/sale/getLotList/'+url) - .then(response => response.json()) + this.request(this.ApiAgentURL+'/sale/getLotList/'+url, 'GET') .then( async data => { for (let lot of data) { @@ -68,9 +85,7 @@ const Agent = class let url = Sale.url url = encodeURIComponent(url); - - fetch(this.ApiAgentURL+'/sale/followSale/'+url) - .then(response => response.json()) + this.request(this.ApiAgentURL+'/sale/followSale/'+url, 'GET') .then(async data => { // set the Sale status to following diff --git a/backend/services/db.js b/backend/services/db.js index 08b293b..ae2c124 100644 --- a/backend/services/db.js +++ b/backend/services/db.js @@ -1,5 +1,5 @@ const MongoClient = require("mongodb").MongoClient; -const config = require("../config.js"); +const {config} = require("../config.js"); const connectionString = config.db.connectionString; const client = new MongoClient(connectionString); diff --git a/client/src/app/features/sales/sales-page/sales-page.component.html b/client/src/app/features/sales/sales-page/sales-page.component.html index c01af30..0c5e495 100644 --- a/client/src/app/features/sales/sales-page/sales-page.component.html +++ b/client/src/app/features/sales/sales-page/sales-page.component.html @@ -61,7 +61,13 @@ Plateforme {{element.platform}} - + + + + + Status + {{element.status}} + @@ -80,7 +86,7 @@ - + @@ -120,6 +126,12 @@ {{element.platform}} + + + Status + {{element.status}} + + Post Processing @@ -137,7 +149,7 @@ - + diff --git a/client/src/app/features/sales/sales-page/sales-page.component.ts b/client/src/app/features/sales/sales-page/sales-page.component.ts index 0138b00..5319af1 100644 --- a/client/src/app/features/sales/sales-page/sales-page.component.ts +++ b/client/src/app/features/sales/sales-page/sales-page.component.ts @@ -20,8 +20,8 @@ export class SalesPageComponent implements OnInit,OnDestroy { url: string = ''; refreshSalesId: any; - displayedColumns: string[] = ['title', 'date', 'house', 'plateform', 'action']; - displayedColumnsOld: string[] = ['title', 'date', 'house', 'plateform', 'postProcessing', 'delete']; + displayedColumns: string[] = ['title', 'date', 'house', 'plateform', 'status', 'action']; + displayedColumnsOld: string[] = ['title', 'date', 'house', 'plateform', 'status', 'postProcessing', 'delete']; futureSales = [] pastSales = [] @@ -62,6 +62,10 @@ export class SalesPageComponent implements OnInit,OnDestroy { .sort((a: any, b: any) => moment(a.date).isAfter(b.date) ? 1 : -1); }); } + + trackByElementId(index: number, element: any): string { + return element._id; + } ngOnInit(): void { this.titleService.setTitle('Jucundus - Sales'); diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 8b63bd1..9bfd601 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -16,7 +16,7 @@ services: - ./backend:/backend ports: - "3000:3000" - - "9229:9229" + - "9228:9229" command: ["npm", "run", "dev"] depends_on: - db \ No newline at end of file