From d0b196347e2117e4cbe86f0d64930b044f21b262 Mon Sep 17 00:00:00 2001 From: Hajar RAHMOUNI Date: Wed, 15 Nov 2023 20:21:36 +0100 Subject: [PATCH] upload photos to an existing ad --- api/openapi.yaml | 41 +++++++++++++++++ controllers/Ad.js | 11 ++++- models/Ad.js | 2 +- package-lock.json | 107 ++++++++++++++++++++++--------------------- package.json | 1 + service/AdService.js | 30 +++++++++++- 6 files changed, 136 insertions(+), 56 deletions(-) diff --git a/api/openapi.yaml b/api/openapi.yaml index 859736f..c9ea4d5 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -195,6 +195,44 @@ 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: put: tags: @@ -423,6 +461,9 @@ components: availabilityDate: type: string format: date-time + photos: + type: string + format: binary required: - title - propertyType diff --git a/controllers/Ad.js b/controllers/Ad.js index 38e88fd..55061a4 100644 --- a/controllers/Ad.js +++ b/controllers/Ad.js @@ -2,7 +2,8 @@ const express = require('express'); const router = express.Router(); const AdService = require('../service/AdService'); const utils = require('../utils/writer.js'); - +const multer = require('multer'); +const upload = multer(); const extractToken = (req, res, next) => { req.token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : null; next(); @@ -76,4 +77,12 @@ router.put('/:id/question/:questionId/answer', extractToken, async (req, res) => } }); +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/models/Ad.js b/models/Ad.js index 340aa57..d2105c8 100644 --- a/models/Ad.js +++ b/models/Ad.js @@ -22,7 +22,7 @@ const AdSchema = new Schema({ description: { type: String, required: true }, price: { type:Number, required: true }, availabilityDate: { type: Date, required: true }, - photos:{ type: [String] }, + photos: [{ type: String }], userName: { type: String, required: true }, questions: [ { diff --git a/package-lock.json b/package-lock.json index d48a5da..21be099 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "js-yaml": "^3.3.0", "jsonwebtoken": "^9.0.2", "mongoose": "^7.6.3", + "multer": "^1.4.5-lts.1", "oas3-tools": "^2.2.3", "passport": "^0.6.0", "passport-local": "^1.0.0", @@ -458,15 +459,14 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/busboy": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", - "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", "dependencies": { - "dicer": "0.2.5", - "readable-stream": "1.1.x" + "streamsearch": "^1.1.0" }, "engines": { - "node": ">=0.8.0" + "node": ">=10.16.0" } }, "node_modules/bytes": { @@ -726,6 +726,14 @@ "node": ">=0.8.0" } }, + "node_modules/dicer/node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -870,47 +878,11 @@ "path-to-regexp": "^6.2.0" } }, - "node_modules/express-openapi-validator/node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/express-openapi-validator/node_modules/multer": { - "version": "1.4.5-lts.1", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", - "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", - "dependencies": { - "append-field": "^1.0.0", - "busboy": "^1.0.0", - "concat-stream": "^1.5.2", - "mkdirp": "^0.5.4", - "object-assign": "^4.1.1", - "type-is": "^1.6.4", - "xtend": "^4.0.0" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/express-openapi-validator/node_modules/path-to-regexp": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" }, - "node_modules/express-openapi-validator/node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/express-session": { "version": "1.17.3", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz", @@ -1860,22 +1832,20 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/multer": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz", - "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==", - "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", + "version": "1.4.5-lts.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", + "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==", "dependencies": { "append-field": "^1.0.0", - "busboy": "^0.2.11", + "busboy": "^1.0.0", "concat-stream": "^1.5.2", "mkdirp": "^0.5.4", "object-assign": "^4.1.1", - "on-finished": "^2.3.0", "type-is": "^1.6.4", "xtend": "^4.0.0" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 6.0.0" } }, "node_modules/negotiator": { @@ -1974,6 +1944,18 @@ "serve-static": "^1.14.1" } }, + "node_modules/oas3-tools/node_modules/busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==", + "dependencies": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/oas3-tools/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1995,6 +1977,25 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/oas3-tools/node_modules/multer": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz", + "integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==", + "deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.4", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -2476,11 +2477,11 @@ } }, "node_modules/streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", "engines": { - "node": ">=0.8.0" + "node": ">=10.0.0" } }, "node_modules/string_decoder": { diff --git a/package.json b/package.json index 6a559e5..ed75a05 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "js-yaml": "^3.3.0", "jsonwebtoken": "^9.0.2", "mongoose": "^7.6.3", + "multer": "^1.4.5-lts.1", "oas3-tools": "^2.2.3", "passport": "^0.6.0", "passport-local": "^1.0.0", diff --git a/service/AdService.js b/service/AdService.js index 39d11dc..0902265 100644 --- a/service/AdService.js +++ b/service/AdService.js @@ -1,6 +1,7 @@ const Ad = require('../models/Ad'); const User = require('../models/User'); - +const fs = require('fs'); +const path = require('path'); const {extractUserFromToken} = require("./UserService"); const secretKey = 'secretKey'; @@ -44,6 +45,33 @@ exports.addAd = async function (body, token) { } }; +// Service for adding photos to an ad +exports.addPhotosToAd = async function (announcementId, photos) { + try { + console.log(announcementId, ' ', photos); + + 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 updatedAnnouncement = await Ad.findByIdAndUpdate( + announcementId, + { $push: { photos: { $each: photoPaths } } }, + { new: true } + ); + + if (!updatedAnnouncement) { + return { status: 404, message: 'Ad not found.' }; + } + + return { status: 200, message: 'Photos added successfully.', updatedAd: updatedAnnouncement }; + } catch (error) { + throw error; + } +}; // Méthode pour mettre à jour une annonce exports.updateAd = async function (announcementId, reqBody, token) { -- GitLab