From 2e777154b510c2c1d16e7f9f2b45f72640837687 Mon Sep 17 00:00:00 2001 From: firdaous elhalafi Date: Thu, 16 Nov 2023 19:06:29 +0100 Subject: [PATCH 1/2] resolution conflicts --- service/AdService.js | 65 ++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/service/AdService.js b/service/AdService.js index 831a076..4aaf93d 100644 --- a/service/AdService.js +++ b/service/AdService.js @@ -9,9 +9,13 @@ const secretKey = process.env.SECRET_KEY; // Service for adding an ad exports.addAdWithPhotos = async function (body, photos, token) { try { - const { title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate } = body; + const {title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate} = body; const user = await extractUserFromToken(token, secretKey); + if (user.isAgent === false) { + throw new Error('User non autorisée.'); + } + const photoPaths = photos.map(file => { // Process and store the file, return its path const photoFileName = `${Date.now()}_${file.originalname}`; @@ -43,7 +47,7 @@ exports.addAdWithPhotos = async function (body, photos, token) { // Service for adding photos to an ad -exports.addPhotosToAd = async function (announcementId, photos,token) { +exports.addPhotosToAd = async function (announcementId, photos, token) { try { console.log(announcementId, ' ', photos); const user = await extractUserFromToken(token, secretKey); @@ -56,15 +60,15 @@ exports.addPhotosToAd = async function (announcementId, photos,token) { const updatedAnnouncement = await Ad.findByIdAndUpdate( announcementId, - { $push: { photos: { $each: photoPaths } } }, - { new: true } + {$push: {photos: {$each: photoPaths}}}, + {new: true} ); if (!updatedAnnouncement) { - return { status: 404, message: 'Ad not found.' }; + return {status: 404, message: 'Ad not found.'}; } - return { status: 200, message: 'Photos added successfully.', updatedAd: updatedAnnouncement }; + return {status: 200, message: 'Photos added successfully.', updatedAd: updatedAnnouncement}; } catch (error) { throw error; } @@ -74,7 +78,10 @@ exports.addPhotosToAd = async function (announcementId, photos,token) { exports.updateAd = async function (announcementId, reqBody, files, token) { try { const user = await extractUserFromToken(token, secretKey); - const { title, propertyType, publicationStatus, description, price, availabilityDate } = reqBody; + const {title, propertyType, publicationStatus, description, price, availabilityDate} = reqBody; + if (user.username !== Announcement.userName) { + return resolve({status: 403, message: 'User non autorisé'}); + } const photoPaths = files.map(file => { const photoFileName = `${Date.now()}_${file.originalname}`; @@ -93,46 +100,20 @@ exports.updateAd = async function (announcementId, reqBody, files, token) { description, price, availabilityDate, - $push: { photos: { $each: photoPaths } } + $push: {photos: {$each: photoPaths}} }, - { new: true } + {new: true} ); - 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); + 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); } - - return { status: 200, message: 'Annonce modifiée avec succès.', updatedAd: updatedAnnouncement }; } catch (error) { - console.error('Error updating ad with photos:', error); - throw new Error('Failed to update ad with photos. Check server logs for details.'); + reject(error); } }; -- GitLab From 7f43d858188763a19045f68d03e38ad81b820824 Mon Sep 17 00:00:00 2001 From: firdaous elhalafi Date: Fri, 17 Nov 2023 18:21:27 +0100 Subject: [PATCH 2/2] refacto code --- api/openapi.yaml | 201 +++++++----------------- controllers/Ad.js | 54 ++++--- index.js | 2 +- multer-config.js | 14 ++ schemas/User&AdSchema.js | 80 +++++++--- service/AdService.js | 325 +++++++++++++++++++-------------------- 6 files changed, 321 insertions(+), 355 deletions(-) create mode 100644 multer-config.js diff --git a/api/openapi.yaml b/api/openapi.yaml index 475b87f..e5f251d 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -58,44 +58,24 @@ paths: type: array items: type: object - /announcements: + /: post: tags: - ad - summary: Add a new ad with photos - description: Add a new ad to the list with photo uploads + summary: Ajouter une nouvelle annonce + description: Ajouter une nouvelle annonce à la liste avec téléchargement de photos operationId: addAdWithPhotos requestBody: required: true content: multipart/form-data: schema: - type: object - properties: - title: - type: string - propertyType: - type: string - publicationStatus: - type: string - propertyStatus: - type: string - description: - type: string - price: - type: number - availabilityDate: - type: string - photos: - type: array - items: - type: string - format: binary + $ref: '#/components/schemas/Ad' security: - bearerAuth: [ ] responses: "200": - description: Successful operation + description: Succès. L'annonce a été ajoutée avec succès. content: application/json: schema: @@ -103,8 +83,6 @@ paths: "405": description: Invalid input x-swagger-router-controller: Ad - - get: tags: - ad @@ -119,12 +97,47 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/AnnouncementList' + $ref: '#/components/schemas/AdsList' "500": description: Erreur serveur interne. Veuillez réessayer plus tard. x-swagger-router-controller: Ad - - /announcements/update/{id}: + /{id}/photos: + post: + tags: + - ad + summary: Ajouter des photos à une annonce + description: Télécharger des photos sur une annonce existante + operationId: addPhotosToAd + parameters: + - name: id + in: path + description: ID de l'annonce à laquelle les photos seront ajoutées + required: true + schema: + type: string + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + photos: + type: array + items: + type: string + format: binary + description: Sélectionnez un ou plusieurs fichiers image. + security: + - bearerAuth: [ ] + responses: + '200': + description: Succès. Les photos ont été ajoutées avec succès. + '404': + description: Annonce non trouvée. + '500': + description: Internal server error. Please try again later. + x-swagger-router-controller: Ad + /{id}: put: tags: - ad @@ -144,7 +157,7 @@ paths: content: multipart/form-data: schema: - $ref: '#/components/schemas/UpdateAdWithPhotos' + $ref: '#/components/schemas/Ad' security: - bearerAuth: [ ] responses: @@ -155,9 +168,7 @@ paths: '404': description: Non trouvé. L'annonce avec cet ID n'a pas été trouvée. x-swagger-router-controller: Ad - - /announcements/delete/{id}: - post: + delete: tags: - ad summary: Supprimer une annonce @@ -185,7 +196,6 @@ paths: '500': description: Erreur serveur interne. Veuillez réessayer plus tard. x-swagger-router-controller: Ad - /announcements/{id}: get: tags: - ad @@ -215,45 +225,7 @@ paths: "500": description: Erreur serveur interne. Veuillez réessayer plus tard. x-swagger-router-controller: Ad - - /announcements/{id}/photos: - post: - tags: - - ad - summary: Add photos to an ad - description: Upload photos to an existing ad. - operationId: addPhotosToAd - parameters: - - name: id - in: path - description: ID of the ad to which photos will be added - required: true - schema: - type: string - requestBody: - content: - multipart/form-data: - schema: - type: object - properties: - photos: - type: array - items: - type: string - format: binary - security: - - bearerAuth: [ ] - responses: - '200': - description: Success. Returns the updated ad details. - '404': - description: Ad not found. - '500': - description: Internal server error. Please try again later. - x-swagger-router-controller: Ad - - - /announcements/{id}/ask: + /{id}/ask: put: tags: - ad @@ -283,7 +255,7 @@ paths: description: Erreur serveur interne. Veuillez réessayer plus tard. x-swagger-router-controller: Ad - /announcements/{id}/question/{questionId}/answer: + /{id}/question/{questionId}/answer: put: tags: - ad @@ -313,6 +285,7 @@ paths: properties: answer: type: string + example: "Réponse" security: - bearerAuth: [ ] responses: @@ -409,63 +382,42 @@ paths: components: schemas: - UpdateAdWithPhotos: - type: object - properties: - title: - type: string - propertyType: - type: string - publicationStatus: - type: string - description: - type: string - price: - type: number - availabilityDate: - type: string - photos: - type: array - items: - type: string - format: binary - required: - - title - - propertyType - - publicationStatus - - description - - price - - availabilityDate Ad: type: object properties: title: type: string + example: "Maison à vendre" propertyType: type: string enum: - À la vente - À la location + example: "À la vente" publicationStatus: type: string enum: - Publiée - Non publiée + example: "Publiée" propertyStatus: type: string enum: - Disponible - Loué - Vendu + example: "Disponible" description: type: string + example: "Maison à vendre" price: type: number minimum: 0 + example: 100000 availabilityDate: type: string format: date-time - example: "2023-11-03T14:30:00Z" + example: "2023-12-25T14:30:00Z" photos: type: array items: @@ -480,47 +432,7 @@ components: - description - price - availabilityDate - UpdateAd: - type: object - properties: - title: - type: string - propertyType: - type: string - enum: - - À la vente - - À la location - publicationStatus: - type: string - enum: - - Publiée - - Non publiée - propertyStatus: - type: string - enum: - - Disponible - - Loué - - Vendu - description: - type: string - price: - type: number - minimum: 0 - availabilityDate: - type: string - format: date-time - photos: - type: string - format: binary - required: - - title - - propertyType - - publicationStatus - - propertyStatus - - description - - price - - availabilityDate - AnnouncementList: + AdsList: type: array items: $ref: '#/components/schemas/Ad' @@ -529,6 +441,7 @@ components: properties: question: type: string + example: "Question" required: - question User: diff --git a/controllers/Ad.js b/controllers/Ad.js index 16729a7..215abc4 100644 --- a/controllers/Ad.js +++ b/controllers/Ad.js @@ -3,18 +3,16 @@ const router = express.Router(); const AdService = require('../service/AdService'); const utils = require('../utils/writer.js'); const multer = require('multer'); -const upload = multer(); +const upload = require('../multer-config'); const extractToken = (req, res, next) => { - const extractToken = (req, res, next) => { - const authorizationHeader = req.headers.authorization; + 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.'}); - } - }; + if (authorizationHeader && authorizationHeader.startsWith('Bearer ')) { + req.token = authorizationHeader.slice(7); + next(); + } else { + res.status(401).json({message: 'Authentication is required'}); + } }; router.post('/', extractToken, upload.array('photos'), async (req, res) => { @@ -26,27 +24,35 @@ router.post('/', extractToken, upload.array('photos'), async (req, res) => { } }); -router.put('/update/:id', extractToken, upload.array('photos'), async (req, res) => { +router.get('/', extractToken, async (req, res) => { try { - const response = await AdService.updateAd(req.params.id, req.body, req.files, req.token); + const response = await AdService.getAds(req.token); + utils.writeJson(res, response); + } catch (error) { + res.status(500).json({message: error.message}); + } +}); +router.post('/:id/photos', extractToken, upload.array('photos'), async (req, res) => { + try { + const response = await AdService.addPhotosToAd(req.params.id, req.files, req.token); utils.writeJson(res, response); } catch (error) { res.status(500).json({message: error.message}); } }); -router.post('/delete/:id', extractToken, async (req, res) => { +router.put('/:id', extractToken, upload.array('photos'), async (req, res) => { try { - const response = await AdService.deleteAd(req.params.id, req.token); + const response = await AdService.updateAd(req.params.id, req.body, req.files, req.token); utils.writeJson(res, response); } catch (error) { res.status(500).json({message: error.message}); } }); -router.get('/', extractToken, async (req, res) => { +router.delete('/:id', extractToken, async (req, res) => { try { - const response = await AdService.getAds(req.token); + const response = await AdService.deleteAd(req.params.id, req.token); utils.writeJson(res, response); } catch (error) { res.status(500).json({message: error.message}); @@ -63,10 +69,10 @@ router.get('/:id', extractToken, async (req, res) => { }); router.put('/:id/ask', extractToken, async (req, res) => { - const announcementId = req.params.id; + const adtId = req.params.id; const {question} = req.body; try { - const response = await AdService.askQuestion(announcementId, question, req.token); + const response = await AdService.askQuestion(adtId, question, req.token); utils.writeJson(res, response); } catch (error) { res.status(500).json({message: error.message}); @@ -74,23 +80,15 @@ router.put('/:id/ask', extractToken, async (req, res) => { }); router.put('/:id/question/:questionId/answer', extractToken, async (req, res) => { - const announcementId = req.params.id; + const adtId = req.params.id; const questionId = req.params.questionId; const {answer} = req.body; try { - const response = await AdService.answerQuestion(announcementId, questionId, answer, req.token); + const response = await AdService.answerQuestion(adtId, questionId, answer, req.token); utils.writeJson(res, response); } catch (error) { res.status(500).json({message: error.message}); } }); -router.post('/:id/photos', extractToken, upload.array('photos'), async (req, res) => { - try { - const response = await AdService.addPhotosToAd(req.params.id, req.files); - utils.writeJson(res, response); - } catch (error) { - res.status(500).json({ message: error.message }); - } -}); module.exports = router; diff --git a/index.js b/index.js index 6148f35..7fdd517 100644 --- a/index.js +++ b/index.js @@ -49,7 +49,7 @@ app.use('/docs', swaggerUi.serve, swaggerUi.setup(openApiDocument, swaggerSpec)) app.get('/graphql-playground', expressPlayground({endpoint: '/graphql'})); app.post('/graphql', createHandler({schema})); -app.use('/announcements', apiRouter); +app.use('/', apiRouter); app.use('/user', authRouter); app.use(express.json()); diff --git a/multer-config.js b/multer-config.js new file mode 100644 index 0000000..1db43c9 --- /dev/null +++ b/multer-config.js @@ -0,0 +1,14 @@ +const multer = require('multer'); + +const storage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, 'uploads/'); + }, + filename: function (req, file, cb) { + cb(null, Date.now() + '-' + file.originalname); + } +}); + +const upload = multer({ storage: storage }); + +module.exports = upload; diff --git a/schemas/User&AdSchema.js b/schemas/User&AdSchema.js index 6f28269..c7ca84f 100644 --- a/schemas/User&AdSchema.js +++ b/schemas/User&AdSchema.js @@ -2,7 +2,7 @@ const {makeExecutableSchema} = require("@graphql-tools/schema"); const UserModel = require("../models/User"); const axios = require('axios'); const { - addAd, + addAdWithPhotos, updateAd, getAdById, getAds, @@ -43,16 +43,16 @@ const typeDefs = ` type Query { getAds(token: String): [Ad] - getAdById(announcementId: ID!, token: String): Ad + getAdById(adId: ID!, token: String): Ad getUser(id: ID, username: String): User } type Mutation { - 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): Ad - answerQuestion(announcementId: ID!, questionId: ID!, answer: String!, token: String): Ad + addAd(input: AdInput, photos: [String], token: String): Ad + updateAd(adId: ID!, input: AdInput, photos: [String], token: String): Ad + deleteAd(adId: ID!, token: String): String + askQuestion(adId: ID!, question: String!, token: String): Ad + answerQuestion(adId: ID!, questionId: ID!, answer: String!, token: String): Ad createUser(input: UserInput): User loginUser(username: String!, password: String!): AuthPayload logoutUser: String @@ -66,7 +66,6 @@ const typeDefs = ` description: String! price: Float! availabilityDate: String! - photos: [String] } type User { @@ -86,7 +85,15 @@ const typeDefs = ` const resolvers = { Query: { getAds: (_, {token}) => getAds(token), - getAdById: (_, {announcementId, token}) => getAdById(announcementId, token), + getAdById: async (_, {adId, token}) => { + const result = await getAdById(adId, token); + + if (result.status) { + throw new Error(result.message); + } + + return result; + }, getUser: async (parent, {id, username}) => { if (id) { return await UserModel.findById(id); @@ -98,16 +105,51 @@ const resolvers = { }, }, 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), + addAd: async (_, {input, photos, token}) => { + const result = await addAdWithPhotos(input, photos, token); + + if (result.status) { + throw new Error(result.message); + } + + return result; + }, + updateAd: async (_, {adId, input, photos, token}) => { + const result = await updateAd(adId, input, photos, token); + + if (result.status) { + throw new Error(result.message); + } + + return result; + }, + deleteAd: async (_, {adId, token}) => { + const result = await deleteAd(adId, token); + + if (result.status) { + throw new Error(result.message); + } + + return result; + }, + askQuestion: async (_, {adId, question, token}) => { + const result = await askQuestion(adId, question, token); + + if (result.status) { + throw new Error(result.message); + } + + return result; + }, + answerQuestion: async (_, {adId, questionId, answer, token}) => { + const result = await answerQuestion(adId, questionId, answer, token); + + if (result.status) { + throw new Error(result.message); + } + + return result; + }, 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 4aaf93d..5a2aa29 100644 --- a/service/AdService.js +++ b/service/AdService.js @@ -10,21 +10,20 @@ const secretKey = process.env.SECRET_KEY; exports.addAdWithPhotos = async function (body, photos, token) { try { const {title, propertyType, publicationStatus, propertyStatus, description, price, availabilityDate} = body; - const user = await extractUserFromToken(token, secretKey); + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); if (user.isAgent === false) { - throw new Error('User non autorisée.'); + return {status: 403, message: 'User non autorisé'}; } - const photoPaths = photos.map(file => { - // Process and store the file, return its path - const photoFileName = `${Date.now()}_${file.originalname}`; - const relativePath = path.join('uploads', photoFileName); - fs.writeFileSync(relativePath, file.buffer); - return relativePath; + const photoPaths = []; + + photos.forEach(file => { + photoPaths.push(file.filename); }); - const newAnnouncement = new Ad({ + const newAd = new Ad({ title, propertyType, publicationStatus, @@ -36,62 +35,90 @@ exports.addAdWithPhotos = async function (body, photos, token) { userName: user.username }); - await newAnnouncement.save(); + const ad = await newAd.save(); - return newAnnouncement; + return ad; } catch (error) { - console.error('Error adding ad with photos:', error); - throw new Error('Failed to add ad with photos. Check server logs for details.'); + throw error; } }; +// Service for getting ads +exports.getAds = async function (token) { + try { + const decoded = await extractUserFromToken(token, secretKey); + let ads; + const user = await User.findOne({username: decoded.username}); + if (user && user.isAgent) { + ads = await Ad.find({userName: user.username}); + } else { + ads = await Ad.find({publicationStatus: 'Publiée'}); + } + return ads; + } catch (error) { + throw error; + } +}; // Service for adding photos to an ad -exports.addPhotosToAd = async function (announcementId, photos, token) { +exports.addPhotosToAd = async function (adId, photos, token) { try { - console.log(announcementId, ' ', photos); - const user = await extractUserFromToken(token, secretKey); - const photoPaths = photos.map(file => { - const photoFileName = `${Date.now()}_${file.originalname}`; - const relativePath = path.relative(process.cwd(), path.join(process.cwd(), 'uploads', photoFileName)); - fs.writeFileSync(relativePath, file.buffer); - return relativePath; + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); + const ad = await Ad.findById(adId); + if (!ad) { + return {status: 404, message: 'Ad not found.'}; + } + + if (user.username !== ad.userName) { + return {status: 403, message: 'User non autorisé'}; + } + + const photoPaths = []; + + photos.forEach(file => { + photoPaths.push(file.filename); }); - const updatedAnnouncement = await Ad.findByIdAndUpdate( - announcementId, - {$push: {photos: {$each: photoPaths}}}, + const updatedAd = await Ad.findByIdAndUpdate( + adId, + { + $push: {photos: {$each: photoPaths}}, + }, {new: true} ); - if (!updatedAnnouncement) { - return {status: 404, message: 'Ad not found.'}; - } - - return {status: 200, message: 'Photos added successfully.', updatedAd: updatedAnnouncement}; + return updatedAd; } catch (error) { throw error; } }; // Service for updating an ad with photos -exports.updateAd = async function (announcementId, reqBody, files, token) { +exports.updateAd = async function (adId, reqBody, files, token) { try { - const user = await extractUserFromToken(token, secretKey); - const {title, propertyType, publicationStatus, description, price, availabilityDate} = reqBody; - if (user.username !== Announcement.userName) { - return resolve({status: 403, message: 'User non autorisé'}); + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); + const ad = await Ad.findById(adId); + + if (!ad) { + return {status: 404, message: 'Ad not found.'}; + } + + if (user.username !== ad.userName) { + return {status: 403, message: 'User non autorisé'}; } - const photoPaths = files.map(file => { - const photoFileName = `${Date.now()}_${file.originalname}`; - const relativePath = path.join('uploads', photoFileName); - fs.writeFileSync(relativePath, file.buffer); - return relativePath; + const {title, propertyType, propertyStatus, publicationStatus, description, price, availabilityDate} = reqBody; + + const photoPaths = []; + + files.forEach(file => { + photoPaths.push(file.filename); }); - const updatedAnnouncement = await Ad.findByIdAndUpdate( - announcementId, + const updateAd = await Ad.findByIdAndUpdate( + adId, { title, propertyType, @@ -100,153 +127,125 @@ exports.updateAd = async function (announcementId, reqBody, files, token) { description, price, availabilityDate, - $push: {photos: {$each: photoPaths}} + photos: photoPaths }, {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); - } + + return updateAd; + } catch (error) { - reject(error); + throw 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é'}); - } +// Service for deleting an ad +exports.deleteAd = async function (adId, token) { + try { + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); - const deletedAnnouncement = await Ad.findByIdAndRemove(announcementId); + const ad = await Ad.findById(adId); - if (!deletedAnnouncement) { - return resolve({status: 404, message: 'annonce non trouvée'}); - } + if (!ad) { + return {status: 404, message: 'Ad not found.'}; + } - /* - 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); - } - }); -}; + if (user.username !== ad.userName) { + return {status: 403, message: 'User non autorisé'}; + } + + const deletedAd = await Ad.findByIdAndRemove(adId); -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'}); + deletedAd.photos.forEach((photo) => { + const filePath = path.join('uploads', photo); + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); } - resolve(announcements); - } catch (error) { - reject(error); - } - }); + }); + + return JSON.stringify('Annonce supprimée avec succès'); + } catch (error) { + throw 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}); +// Service for getting an ad by id +exports.getAdById = async function (adId, token) { + try { + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); + const adDetails = await Ad.findById(adId); - 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 (!adDetails) { + return {status: 404, message: 'Cette annonce est introuvable ou non disponible.'}; + } - if (!announcementDetails) { - return resolve({status: 404, message: 'Cette annonce est introuvable ou non disponible.'}); - } - resolve(announcementDetails); - } catch (error) { - reject(error); + if ( + (user && user.username !== adDetails.userName || !user) && + adDetails.publicationStatus !== 'Publiée' + ) { + return {status: 404, message: 'Cette annonce est introuvable ou non disponible.'}; + } + if (user && user.username !== adDetails.userName && user.isAgent) { + return {status: 403, message: 'User non autorisée.'}; } - }); + + return adDetails; + } catch (error) { + throw 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}); +// Service for asking a question on an ad +exports.askQuestion = async function (adId, question, token) { + try { + 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; - } - }); + const ad = await Ad.findById(adId); + if (!ad) { + return {status: 404, message: 'Annonce non trouvée.'}; + } + if (ad.propertyStatus !== 'Disponible') { + return {status: 404, message: 'Vous ne pouvez poser une question que sur les annonces non disponibles.'}; + } + ad.questions.push({ + user: user.username, + question + }); + const newAd = await ad.save(); + return newAd; + } 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}); - console.log('user', user.username); - if (!announcement) { - return resolve({status: 404, message: 'Annonce non trouvée.'}); - } +// Service for answering a question on an ad +exports.answerQuestion = async function (adId, questionId, answer, token) { + try { + const decoded = await extractUserFromToken(token, secretKey); + const user = await User.findOne({username: decoded.username}); - if (user.username !== announcement.userName) { - return resolve({status: 403, message: 'User non autorisée.'}); - } + const ad = await Ad.findById(adId); + if (!ad) { + return {status: 404, message: 'Annonce non trouvé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; + if (user.username !== ad.userName) { + return {status: 403, message: 'User non autorisée.'}; } - }); + + const question = ad.questions.id(questionId); + if (!question) { + return {status: 404, message: 'Question non trouvée.'}; + } + question.answers.push({user: user.username, answer}); + const newAd = await ad.save(); + return newAd; + } catch (error) { + throw error; + } } -- GitLab