From 89fd992f0360a8c93803e46354c56f29081b62d9 Mon Sep 17 00:00:00 2001 From: firdaous elhalafi Date: Wed, 15 Nov 2023 20:35:14 +0100 Subject: [PATCH 1/2] Correction des mutations addAD updateAd deleteAd askQuestion answerQuestion --- controllers/User.js | 13 +- data-access/connection.js | 2 +- schemas/User&AdSchema.js | 46 +++--- service/AdService.js | 325 ++++++++++++++++++++------------------ 4 files changed, 193 insertions(+), 193 deletions(-) diff --git a/controllers/User.js b/controllers/User.js index f3a2172..763d0bf 100644 --- a/controllers/User.js +++ b/controllers/User.js @@ -3,9 +3,11 @@ const passport = require('../passeport-config'); const jwt = require('jsonwebtoken'); const utils = require('../utils/writer.js'); -const { typeDefs, resolvers } = require('../schemas/User&AdSchema'); +const { typeDefs, resolvers, schema} = require('../schemas/User&AdSchema'); const User = require('../service/UserService'); +const {default: expressPlayground} = require("graphql-playground-middleware-express"); +const {createHandler} = require("graphql-http/lib/use/express"); const authRouter = express.Router(); @@ -48,13 +50,4 @@ authRouter.post('/logout', async (req, res) => { } }); -/* -const expressGraphQL = require('express-graphql').graphqlHTTP; - -authRouter.use('/graphql', expressGraphQL({ - schema: typeDefs, - rootValue: resolvers, - graphiql: true, -})); -*/ module.exports = authRouter; diff --git a/data-access/connection.js b/data-access/connection.js index 40cc13b..c1c6259 100644 --- a/data-access/connection.js +++ b/data-access/connection.js @@ -2,7 +2,7 @@ const mongoose = require('mongoose'); require('dotenv').config(); const dbName = process.env.DB_NAME; -const url = `mongodb://172.24.0.2:27017/${dbName}`; +const url = `mongodb://mongodb:27017/${dbName}`; const connectToDatabase = async () => { try { diff --git a/schemas/User&AdSchema.js b/schemas/User&AdSchema.js index d0bb962..257ad79 100644 --- a/schemas/User&AdSchema.js +++ b/schemas/User&AdSchema.js @@ -1,4 +1,4 @@ -const { makeExecutableSchema } = require("@graphql-tools/schema"); +const {makeExecutableSchema} = require("@graphql-tools/schema"); const UserModel = require("../models/User"); const axios = require('axios'); const { @@ -13,7 +13,7 @@ const { const typeDefs = ` type Ad { - _id: ID! + _id: ID title: String! propertyType: String! publicationStatus: String! @@ -34,7 +34,6 @@ const typeDefs = ` } type Answer { - user: String! answer: String! } @@ -52,13 +51,8 @@ const typeDefs = ` addAd(input: AdInput, token: String): Ad updateAd(announcementId: ID!, input: AdInput, token: String): Ad deleteAd(announcementId: ID!, token: String): String - askQuestion(announcementId: ID!, question: String!, token: String): String - answerQuestion( - announcementId: ID! - questionId: ID! - answer: String! - token: String - ): String + askQuestion(announcementId: ID!, question: String!, token: String): Ad + answerQuestion(announcementId: ID!, questionId: ID!, answer: String!, token: String): Ad createUser(input: UserInput): User loginUser(username: String!, password: String!): AuthPayload logoutUser: String @@ -73,9 +67,8 @@ const typeDefs = ` price: Float! availabilityDate: String! photos: [String] - userName: String! } - + type User { _id: ID! username: String! @@ -92,26 +85,25 @@ const typeDefs = ` const resolvers = { Query: { - getAds: (_, { token }) => getAds(token), - getAdById: (_, { announcementId, token }) => getAdById(announcementId, token), - getUser: async (parent, { id, username }) => { + getAds: (_, {token}) => getAds(token), + getAdById: (_, {announcementId, token}) => getAdById(announcementId, token), + getUser: async (parent, {id, username}) => { if (id) { return await UserModel.findById(id); } else if (username) { - return await UserModel.findOne({ username }); + return await UserModel.findOne({username}); } else { return null; } }, }, Mutation: { - addAd: (_, { input, token }) => addAd(input, token), - updateAd: (_, { announcementId, input, token }) => updateAd(announcementId, input, token), - deleteAd: (_, { announcementId, token }) => deleteAd(announcementId, token), - askQuestion: (_, { announcementId, question, token }) => askQuestion(announcementId, question, token), - answerQuestion: (_, { announcementId, questionId, answer, token }) => - answerQuestion(announcementId, questionId, answer, token), - createUser: async (_, { input }) => { + addAd: (_, {input, token}) => addAd(input, token), + updateAd: (_, {announcementId, input, token}) => updateAd(announcementId, input, token), + deleteAd: (_, {announcementId, token}) => deleteAd(announcementId, token), + askQuestion: (_, {announcementId, question, token}) => askQuestion(announcementId, question, token), + answerQuestion: (_, {announcementId, questionId, answer, token}) => answerQuestion(announcementId, questionId, answer, token), + createUser: async (_, {input}) => { try { const response = await axios.post('http://localhost:8080/user', input); if (response.data.exports) { @@ -123,12 +115,12 @@ const resolvers = { throw new Error('Erreur lors de la création de l\'utilisateur. Vérifiez les détails dans les journaux.'); } }, - loginUser: async (_, { username, password }) => { + loginUser: async (_, {username, password}) => { try { - const response = await axios.post('http://localhost:8080/user/login', { username, password }); + const response = await axios.post('http://localhost:8080/user/login', {username, password}); if (response.status === 200) { - return { token: response.data.token }; + return {token: response.data.token}; } else { throw new Error('Invalid username or password.'); } @@ -154,4 +146,4 @@ const resolvers = { }, }; -exports.schema = makeExecutableSchema({ typeDefs, resolvers }); +exports.schema = makeExecutableSchema({typeDefs, resolvers}); diff --git a/service/AdService.js b/service/AdService.js index 18c98b7..894526d 100644 --- a/service/AdService.js +++ b/service/AdService.js @@ -8,7 +8,7 @@ const secretKey = 'secretKey'; // Service for adding an ad exports.addAd = async function (body, token) { try { - const { title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate} = body; + const {title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate} = body; const photos = []; /* req.files.forEach(file => { @@ -16,7 +16,7 @@ exports.addAd = async function (body, token) { }); */ const decoded = await extractUserFromToken(token, secretKey); - const user = await User.findOne({ username: decoded.username }); + const user = await User.findOne({username: decoded.username}); if (user.isAgent === false) { throw new Error('User non autorisée.'); @@ -46,174 +46,189 @@ exports.addAd = async function (body, token) { // Méthode pour mettre à jour une annonce exports.updateAd = function (announcementId, reqBody, token) { - return new Promise(async (resolve, reject) => { - try { - const user = await extractUserFromToken(token, secretKey); - const { title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate } = reqBody; - /* - let photos = []; - const oldPhotos = reqBody.oldPhotos || []; - - reqFiles.forEach(file => { - photos.push(file.filename); - }); - - photos = photos.concat(oldPhotos); - */ - const updatedAnnouncement = await Ad.findByIdAndUpdate( - announcementId, - { - title, - propertyType, - publicationStatus, - propertyStatus, - description, - price, - availabilityDate, - //photos, - } - ); - if (!updatedAnnouncement) { - return resolve({status: 404, message: 'annonce non trouvée'}); - } - if (user.username !== updatedAnnouncement.userName) { - return resolve({status: 401, message: 'Utilisateur non autorisé'}); - } - - resolve({ status: 200, message: 'Annonce Modifié avec succès' }); - } catch (error) { - reject(error); - } - }); + return new Promise(async (resolve, reject) => { + try { + const user = await extractUserFromToken(token, secretKey); + const Announcement = await Ad.findById(announcementId); + if (user.username !== Announcement.userName) { + return resolve({status: 403, message: 'User non autorisé'}); + } + const { + title, + propertyType, + publicationStatus, + propertyStatus, + description, + price, + availabilityDate + } = reqBody; + /* + let photos = []; + const oldPhotos = reqBody.oldPhotos || []; + + reqFiles.forEach(file => { + photos.push(file.filename); + }); + + photos = photos.concat(oldPhotos); + */ + const updatedAnnouncement = await Ad.findByIdAndUpdate( + announcementId, + { + title, + propertyType, + publicationStatus, + propertyStatus, + description, + price, + availabilityDate, + //photos, + }, + {new: true} + ); + if (!updatedAnnouncement) { + return resolve({status: 404, message: 'annonce non trouvée'}); + } else if (user.username !== updatedAnnouncement.userName) { + return resolve({status: 401, message: 'Utilisateur non autorisé'}); + } else { + return resolve(updatedAnnouncement); + } + } catch (error) { + reject(error); + } + }); } exports.deleteAd = function (announcementId, token) { - return new Promise(async (resolve, reject) => { - try { - const user = await extractUserFromToken(token, secretKey); - const Announcement = await Ad.findById(announcementId); - if (user.username !== Announcement.userName) { - return resolve({ status: 403, message: 'User non autorisé' }); - } - - const deletedAnnouncement = await Ad.findByIdAndRemove(announcementId); - - if (!deletedAnnouncement) { - return resolve({ status: 404, message: 'annonce non trouvée' }); - } - - /* - deletedAnnouncement.photos.forEach((photo) => { - const filePath = path.join('public', 'uploads', photo); - if (fs.existsSync(filePath)) { - fs.unlinkSync(filePath); + return new Promise(async (resolve, reject) => { + try { + const user = await extractUserFromToken(token, secretKey); + const Announcement = await Ad.findById(announcementId); + if (user.username !== Announcement.userName) { + return resolve({status: 403, message: 'User non autorisé'}); + } + + const deletedAnnouncement = await Ad.findByIdAndRemove(announcementId); + + if (!deletedAnnouncement) { + return resolve({status: 404, message: 'annonce non trouvée'}); + } + + /* + deletedAnnouncement.photos.forEach((photo) => { + const filePath = path.join('public', 'uploads', photo); + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } + }); + */ + return resolve('Annonce supprimée avec succès'); + } catch (error) { + reject(error); } - }); - */ - resolve({ status: 200, message: 'Annonce supprimée avec succès' }); - } catch (error) { - reject(error); - } - }); + }); }; exports.getAds = function (token) { - return new Promise(async (resolve, reject) => { - try { - const decoded = await extractUserFromToken(token, secretKey); - let announcements; - const user = await User.findOne({ username: decoded.username }); - if (user && user.isAgent) { - announcements = await Ad.find({ userName: user.username }); - } else { - announcements = await Ad.find({ publicationStatus: 'Publiée' }); + return new Promise(async (resolve, reject) => { + try { + const decoded = await extractUserFromToken(token, secretKey); + let announcements; + const user = await User.findOne({username: decoded.username}); + if (user && user.isAgent) { + announcements = await Ad.find({userName: user.username}); + } else { + announcements = await Ad.find({publicationStatus: 'Publiée'}); + } + resolve(announcements); + } catch (error) { + reject(error); } - resolve(announcements); - } catch (error) { - reject(error); - } - }); + }); }; exports.getAdById = function (announcementId, token) { - return new Promise(async (resolve, reject) => { - try { - const announcementDetails = await Ad.findById(announcementId); - const decoded = await extractUserFromToken(token, secretKey); - const user = await User.findOne({ username: decoded.username }); - - - if ( - (user && user.username !== announcementDetails.userName || !user) && - announcementDetails.publicationStatus !== 'Publiée' - ) { - return resolve({ status: 404, message: 'Cette annonce est introuvable ou non disponible.' }); - } - if (user && user.username !== announcementDetails.userName && user.isAgent) { - return resolve({ status: 403, message: 'User non autorisée.' }); - } - - if( !announcementDetails ) { - return resolve({ status: 404, message: 'Cette annonce est introuvable ou non disponible.' }); - } - resolve(announcementDetails); - } catch (error) { - reject(error); - } - }); + return new Promise(async (resolve, reject) => { + try { + const announcementDetails = await Ad.findById(announcementId); + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); + + + if ( + (user && user.username !== announcementDetails.userName || !user) && + announcementDetails.publicationStatus !== 'Publiée' + ) { + return resolve({status: 404, message: 'Cette annonce est introuvable ou non disponible.'}); + } + if (user && user.username !== announcementDetails.userName && user.isAgent) { + return resolve({status: 403, message: 'User non autorisée.'}); + } + + if (!announcementDetails) { + return resolve({status: 404, message: 'Cette annonce est introuvable ou non disponible.'}); + } + resolve(announcementDetails); + } catch (error) { + reject(error); + } + }); }; // Service pour poser une question sur une annonce -exports.askQuestion = async function(announcementId, question, token) { - return new Promise(async (resolve, reject) => { - try { - const announcement = await Ad.findById(announcementId); - const decoded = await extractUserFromToken(token, secretKey); - const user = await User.findOne({ username: decoded.username }); - - if (!announcement) { - return resolve({ status: 404, message: 'Annonce non trouvée.' }); - } - if (announcement.propertyStatus !== 'Disponible') { - return resolve({ status: 404, message: 'Vous ne pouvez poser une question que sur les annonces non disponibles.' }); - } - announcement.questions.push({ - user: user.username, - question - }); - await announcement.save(); - resolve({ status: 200, message: 'Question posée avec succès.' }); - } catch (error) { - throw error; - } - }); +exports.askQuestion = async function (announcementId, question, token) { + return new Promise(async (resolve, reject) => { + try { + const announcement = await Ad.findById(announcementId); + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); + + if (!announcement) { + return resolve({status: 404, message: 'Annonce non trouvée.'}); + } + if (announcement.propertyStatus !== 'Disponible') { + return resolve({ + status: 404, + message: 'Vous ne pouvez poser une question que sur les annonces non disponibles.' + }); + } + announcement.questions.push({ + user: user.username, + question + }); + const newAnnouncement = await announcement.save(); + resolve(newAnnouncement); + } catch (error) { + throw error; + } + }); }; // Service pour répondre à une question sur une annonce -exports.answerQuestion = async function(announcementId, questionId, answer, token) { - return new Promise(async (resolve, reject) => { - try { - const announcement = await Ad.findById(announcementId); - const decoded = await extractUserFromToken(token, secretKey); - const user = await User.findOne({ username: decoded.username }); - - if (!announcement) { - return resolve({ status: 404, message: 'Annonce non trouvée.' }); - } - - if (user.username !== announcement.userName) { - return resolve({ status: 403, message: 'User non autorisée.' }); - } - - const question = announcement.questions.id(questionId); - if (!question) { - return resolve({ status: 404, message: 'Question non trouvée.' }); - } - question.answers.push({ user: user.username, answer }); - await announcement.save(); - resolve({ status: 200, message: 'Réponse ajoutée avec succès.' }); - } catch (error) { - throw error; - } - }); +exports.answerQuestion = async function (announcementId, questionId, answer, token) { + return new Promise(async (resolve, reject) => { + try { + const announcement = await Ad.findById(announcementId); + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); + console.log('user', user.username); + if (!announcement) { + return resolve({status: 404, message: 'Annonce non trouvée.'}); + } + + if (user.username !== announcement.userName) { + return resolve({status: 403, message: 'User non autorisée.'}); + } + + const question = announcement.questions.id(questionId); + if (!question) { + return resolve({status: 404, message: 'Question non trouvée.'}); + } + question.answers.push({user: user.username, answer}); + const newAnnouncement = await announcement.save(); + resolve(newAnnouncement); + } catch (error) { + throw error; + } + }); } -- GitLab From c7242a6c86040a2ab0e054241e42c9ea9f0e53d9 Mon Sep 17 00:00:00 2001 From: firdaous elhalafi Date: Wed, 15 Nov 2023 21:00:48 +0100 Subject: [PATCH 2/2] Indenter le code et mettre la cle secrete dans le .env --- api/openapi.yaml | 12 +++---- controllers/Ad.js | 30 +++++++++++------- controllers/User.js | 33 +++++++++++++++----- data-access/connection.js | 2 +- index.js | 8 ++--- models/Ad.js | 20 ++++++------ models/User.js | 6 ++-- passeport-config.js | 18 ++++++----- schemas/User&AdSchema.js | 7 ++++- service/AdService.js | 2 +- service/UserService.js | 64 ++++++++++++++++++------------------- utils/writer.js | 66 +++++++++++++++++++-------------------- 12 files changed, 149 insertions(+), 119 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 859736f..d86d82b 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -151,7 +151,7 @@ paths: schema: type: string security: - - bearerAuth: [] + - bearerAuth: [ ] responses: '200': description: Succès. L'annonce a été supprimée avec succès. @@ -180,7 +180,7 @@ paths: schema: type: string security: - - bearerAuth: [] + - bearerAuth: [ ] responses: "200": description: Succès. Détails de l'annonce récupérés avec succès. @@ -217,7 +217,7 @@ paths: schema: $ref: '#/components/schemas/askQuestion' security: - - bearerAuth: [] + - bearerAuth: [ ] responses: '200': description: Succès. La question a été posée avec succès. @@ -255,7 +255,7 @@ paths: answer: type: string security: - - bearerAuth: [] + - bearerAuth: [ ] responses: '200': description: Succès. La réponse a été enregistrée avec succès. @@ -504,8 +504,8 @@ components: $ref: '#/components/schemas/User' securitySchemes: bearerAuth: - type: http - scheme: bearer + type: http + scheme: bearer oAuthSample: type: oauth2 description: This API uses OAuth 2 with the implicit grant flow. diff --git a/controllers/Ad.js b/controllers/Ad.js index 38e88fd..20b7b7c 100644 --- a/controllers/Ad.js +++ b/controllers/Ad.js @@ -4,8 +4,16 @@ const AdService = require('../service/AdService'); const utils = require('../utils/writer.js'); const extractToken = (req, res, next) => { - req.token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : null; - next(); + const extractToken = (req, res, next) => { + const authorizationHeader = req.headers.authorization; + + if (authorizationHeader && authorizationHeader.startsWith('Bearer ')) { + req.token = authorizationHeader.slice(7); + next(); + } else { + res.status(401).json({message: 'Authentication is required.'}); + } + }; }; router.post('/', extractToken, async (req, res) => { @@ -13,7 +21,7 @@ router.post('/', extractToken, async (req, res) => { const response = await AdService.addAd(req.body, req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); @@ -22,7 +30,7 @@ router.put('/update/:id', extractToken, async (req, res) => { const response = await AdService.updateAd(req.params.id, req.body, req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); @@ -31,7 +39,7 @@ router.post('/delete/:id', extractToken, async (req, res) => { const response = await AdService.deleteAd(req.params.id, req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); @@ -40,7 +48,7 @@ router.get('/', extractToken, async (req, res) => { const response = await AdService.getAds(req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); @@ -49,30 +57,30 @@ router.get('/:id', extractToken, async (req, res) => { const response = await AdService.getAdById(req.params.id, req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); router.put('/:id/ask', extractToken, async (req, res) => { const announcementId = req.params.id; - const { question } = req.body; + const {question} = req.body; try { const response = await AdService.askQuestion(announcementId, question, req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); router.put('/:id/question/:questionId/answer', extractToken, async (req, res) => { const announcementId = req.params.id; const questionId = req.params.questionId; - const { answer } = req.body; + const {answer} = req.body; try { const response = await AdService.answerQuestion(announcementId, questionId, answer, req.token); utils.writeJson(res, response); } catch (error) { - res.status(500).json({ message: error.message }); + res.status(500).json({message: error.message}); } }); diff --git a/controllers/User.js b/controllers/User.js index 763d0bf..07c6884 100644 --- a/controllers/User.js +++ b/controllers/User.js @@ -3,22 +3,35 @@ const passport = require('../passeport-config'); const jwt = require('jsonwebtoken'); const utils = require('../utils/writer.js'); -const { typeDefs, resolvers, schema} = require('../schemas/User&AdSchema'); +const {typeDefs, resolvers, schema} = require('../schemas/User&AdSchema'); const User = require('../service/UserService'); const {default: expressPlayground} = require("graphql-playground-middleware-express"); const {createHandler} = require("graphql-http/lib/use/express"); +const {extractUserFromToken} = require("../service/UserService"); + +const extractToken = (req, res, next) => { + const authorizationHeader = req.headers.authorization; + + if (authorizationHeader && authorizationHeader.startsWith('Bearer ')) { + req.token = authorizationHeader.slice(7); + next(); + } else { + res.status(401).json({ message: 'Authentication is required.' }); + } +}; +const secretKey = process.env.SECRET_KEY; const authRouter = express.Router(); authRouter.post('/', async (req, res) => { try { - const { username, password, isAgent } = req.body; + const {username, password, isAgent} = req.body; user = await User.createUser(username, password, isAgent); console.log("user", user) - utils.writeJson(res, { message: 'Utilisateur créé avec succès', user }); + utils.writeJson(res, {message: 'Utilisateur créé avec succès', user}); } catch (error) { - utils.writeJson(res, { error: error.message }); + utils.writeJson(res, {error: error.message}); } }); @@ -31,8 +44,8 @@ authRouter.post('/login', async (req, res, next) => { if (!user) { return res.status(401).send('Invalid username or password.'); // Unauthorized } - const token = jwt.sign({ username: user.username }, 'secretKey', { expiresIn: '1h' }); - return res.status(200).json({ token }); + const token = jwt.sign({username: user.username}, secretKey, {expiresIn: '1h'}); + return res.status(200).json({token}); })(req, res, next); } catch (error) { console.error("Erreur lors de la tentative de connexion :", error); @@ -40,10 +53,14 @@ authRouter.post('/login', async (req, res, next) => { } }); -authRouter.post('/logout', async (req, res) => { +authRouter.post('/logout', extractToken, async (req, res) => { try { // Perform logout logic if needed - return res.status(200).send('Logout successful.'); // Success + const decoded = await extractUserFromToken(req.token, secretKey); + if (!decoded) { + return res.status(401).send('Invalid token.'); + } + return res.status(200).send('Logout successful.'); } catch (error) { console.error("Erreur lors de la déconnexion de l'utilisateur :", error); return res.status(500).send(error); diff --git a/data-access/connection.js b/data-access/connection.js index c1c6259..e8711d8 100644 --- a/data-access/connection.js +++ b/data-access/connection.js @@ -6,7 +6,7 @@ const url = `mongodb://mongodb:27017/${dbName}`; const connectToDatabase = async () => { try { - await mongoose.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }); + await mongoose.connect(url, {useNewUrlParser: true, useUnifiedTopology: true}); console.log(`Connected to database ${dbName}`); } catch (err) { console.error(err); diff --git a/index.js b/index.js index 442d5d2..6148f35 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ const express = require('express'); const swaggerUi = require('swagger-ui-express'); -const { makeExecutableSchema } = require('@graphql-tools/schema'); -const { createHandler } = require('graphql-http/lib/use/express'); +const {makeExecutableSchema} = require('@graphql-tools/schema'); +const {createHandler} = require('graphql-http/lib/use/express'); const expressPlayground = require('graphql-playground-middleware-express').default; const YAML = require('yamljs'); const swaggerJsdoc = require('swagger-jsdoc'); @@ -46,8 +46,8 @@ const swaggerSpec = swaggerJsdoc(options); const {schema} = require("./schemas/User&AdSchema"); app.use('/docs', swaggerUi.serve, swaggerUi.setup(openApiDocument, swaggerSpec)); -app.get('/graphql-playground', expressPlayground({ endpoint: '/graphql' })); -app.post('/graphql', createHandler({ schema })); +app.get('/graphql-playground', expressPlayground({endpoint: '/graphql'})); +app.post('/graphql', createHandler({schema})); app.use('/announcements', apiRouter); app.use('/user', authRouter); diff --git a/models/Ad.js b/models/Ad.js index 340aa57..22c3eef 100644 --- a/models/Ad.js +++ b/models/Ad.js @@ -3,7 +3,7 @@ var Schema = mongoose.Schema; var passportLocalMongoose = require('passport-local-mongoose'); const AdSchema = new Schema({ - title: { type: String, required: true }, + title: {type: String, required: true}, propertyType: { type: String, enum: ['À la vente', 'À la location'], @@ -19,17 +19,17 @@ const AdSchema = new Schema({ enum: ['Disponible', 'Loué', 'Vendu'], required: true }, - description: { type: String, required: true }, - price: { type:Number, required: true }, - availabilityDate: { type: Date, required: true }, - photos:{ type: [String] }, - userName: { type: String, required: true }, + description: {type: String, required: true}, + price: {type: Number, required: true}, + availabilityDate: {type: Date, required: true}, + photos: {type: [String]}, + userName: {type: String, required: true}, questions: [ { - user: { type: String, required: true }, - question: { type: String, required: true }, - answers: [ { answer : { type: String } } ], - date: { type: Date, default: Date.now } + user: {type: String, required: true}, + question: {type: String, required: true}, + answers: [{answer: {type: String}}], + date: {type: Date, default: Date.now} } ] }); diff --git a/models/User.js b/models/User.js index 7a48da6..d5d1207 100644 --- a/models/User.js +++ b/models/User.js @@ -3,9 +3,9 @@ const Schema = mongoose.Schema; const passportLocalMongoose = require('passport-local-mongoose'); const userSchema = new Schema({ - username: { type: String, required: true }, - password: { type: String }, - isAgent: { type: Boolean, default: false } + username: {type: String, required: true}, + password: {type: String}, + isAgent: {type: Boolean, default: false} }); userSchema.plugin(passportLocalMongoose); diff --git a/passeport-config.js b/passeport-config.js index 7db6a16..2d685e2 100644 --- a/passeport-config.js +++ b/passeport-config.js @@ -4,10 +4,12 @@ const LocalStrategy = require('passport-local').Strategy; const User = require('./models/User'); passport.use(new LocalStrategy( - { usernameField: 'username' }, - function(username, password, done) { - User.authenticate()(username, password, async function(err, user) { - if (err) { return done(err); } + {usernameField: 'username'}, + function (username, password, done) { + User.authenticate()(username, password, async function (err, user) { + if (err) { + return done(err); + } if (!user) { return done(null, false); } @@ -16,15 +18,15 @@ passport.use(new LocalStrategy( } )); -passport.serializeUser(function(user, done) { +passport.serializeUser(function (user, done) { done(null, user.username); }); -passport.deserializeUser( async function(username, done) { +passport.deserializeUser(async function (username, done) { try { - const user = await User.findOne({ username: username }); + const user = await User.findOne({username: username}); if (!user) { - return done(null, false, { message: 'Utilisateur non trouvé.' }); + return done(null, false, {message: 'Utilisateur non trouvé.'}); } return done(null, user); } catch (error) { diff --git a/schemas/User&AdSchema.js b/schemas/User&AdSchema.js index 257ad79..6f28269 100644 --- a/schemas/User&AdSchema.js +++ b/schemas/User&AdSchema.js @@ -102,7 +102,12 @@ const resolvers = { updateAd: (_, {announcementId, input, token}) => updateAd(announcementId, input, token), deleteAd: (_, {announcementId, token}) => deleteAd(announcementId, token), askQuestion: (_, {announcementId, question, token}) => askQuestion(announcementId, question, token), - answerQuestion: (_, {announcementId, questionId, answer, token}) => answerQuestion(announcementId, questionId, answer, token), + answerQuestion: (_, { + announcementId, + questionId, + answer, + token + }) => answerQuestion(announcementId, questionId, answer, token), createUser: async (_, {input}) => { try { const response = await axios.post('http://localhost:8080/user', input); diff --git a/service/AdService.js b/service/AdService.js index 894526d..cdc776c 100644 --- a/service/AdService.js +++ b/service/AdService.js @@ -3,7 +3,7 @@ const User = require('../models/User'); const {extractUserFromToken} = require("./UserService"); -const secretKey = 'secretKey'; +const secretKey = process.env.SECRET_KEY; // Service for adding an ad exports.addAd = async function (body, token) { diff --git a/service/UserService.js b/service/UserService.js index 3559f14..e81e3a5 100644 --- a/service/UserService.js +++ b/service/UserService.js @@ -14,16 +14,16 @@ passport.use(User.createStrategy()); * body User Created user object (optional) * returns User **/ -exports.createUser = async function(username, password, isAgent) { - const existingUser = await User.findOne({ username }); +exports.createUser = async function (username, password, isAgent) { + const existingUser = await User.findOne({username}); - if (existingUser) { - throw new Error('This user already exists.'); - } + if (existingUser) { + throw new Error('This user already exists.'); + } - const user = await User.register(new User ({ username : username, isAgent : isAgent}), password); - console.log("user", user) - return user; + const user = await User.register(new User({username: username, isAgent: isAgent}), password); + console.log("user", user) + return user; }; /** @@ -34,32 +34,32 @@ exports.createUser = async function(username, password, isAgent) { * returns String **/ exports.isAuthenticated = function (req, res, next) { - if (req.isAuthenticated()) { - return next(); - } - res.status(401).json({ message: 'Authentification requise' }); + if (req.isAuthenticated()) { + return next(); + } + res.status(401).json({message: 'Authentification requise'}); } -exports.extractUserFromToken = function(token, secretKey) { - return new Promise(async (resolve, reject) => { - try { - const decoded = await jwt.verify(token, secretKey); - // Vérifier la date d'expiration - const currentTimestamp = Math.floor(Date.now() / 1000); - if (decoded.exp && decoded.exp < currentTimestamp) { - reject(new Error('Token expiré.')); - return; - } +exports.extractUserFromToken = function (token, secretKey) { + return new Promise(async (resolve, reject) => { + try { + const decoded = await jwt.verify(token, secretKey); + // Vérifier la date d'expiration + const currentTimestamp = Math.floor(Date.now() / 1000); + if (decoded.exp && decoded.exp < currentTimestamp) { + reject(new Error('Token expiré.')); + return; + } - const user = await User.findOne({ username: decoded.username }); + const user = await User.findOne({username: decoded.username}); - if (!user) { - reject(new Error('Utilisateur non trouvé.')); - } else { - resolve(decoded); - } - } catch (err) { - reject(err); - } - }); + if (!user) { + reject(new Error('Utilisateur non trouvé.')); + } else { + resolve(decoded); + } + } catch (err) { + reject(err); + } + }); }; diff --git a/utils/writer.js b/utils/writer.js index d79f6e1..fa55a0b 100644 --- a/utils/writer.js +++ b/utils/writer.js @@ -1,43 +1,41 @@ -var ResponsePayload = function(code, payload) { - this.code = code; - this.payload = payload; +var ResponsePayload = function (code, payload) { + this.code = code; + this.payload = payload; } -exports.respondWithCode = function(code, payload) { - return new ResponsePayload(code, payload); +exports.respondWithCode = function (code, payload) { + return new ResponsePayload(code, payload); } -var writeJson = exports.writeJson = function(response, arg1, arg2) { - var code; - var payload; +var writeJson = exports.writeJson = function (response, arg1, arg2) { + var code; + var payload; - if(arg1 && arg1 instanceof ResponsePayload) { - writeJson(response, arg1.payload, arg1.code); - return; - } + if (arg1 && arg1 instanceof ResponsePayload) { + writeJson(response, arg1.payload, arg1.code); + return; + } - if(arg2 && Number.isInteger(arg2)) { - code = arg2; - } - else { - if(arg1 && Number.isInteger(arg1)) { - code = arg1; + if (arg2 && Number.isInteger(arg2)) { + code = arg2; + } else { + if (arg1 && Number.isInteger(arg1)) { + code = arg1; + } + } + if (code && arg1) { + payload = arg1; + } else if (arg1) { + payload = arg1; } - } - if(code && arg1) { - payload = arg1; - } - else if(arg1) { - payload = arg1; - } - if(!code) { - // if no response code given, we default to 200 - code = 200; - } - if(typeof payload === 'object') { - payload = JSON.stringify(payload, null, 2); - } - response.writeHead(code, {'Content-Type': 'application/json'}); - response.end(payload); + if (!code) { + // if no response code given, we default to 200 + code = 200; + } + if (typeof payload === 'object') { + payload = JSON.stringify(payload, null, 2); + } + response.writeHead(code, {'Content-Type': 'application/json'}); + response.end(payload); } -- GitLab