From ff5fd817d854c7f502dbf21fb752acb0ca8892cf Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Sun, 3 Oct 2021 05:06:40 +0100 Subject: [PATCH 01/18] Create profile.js --- server/controllers/profile.js | 116 ++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 server/controllers/profile.js diff --git a/server/controllers/profile.js b/server/controllers/profile.js new file mode 100644 index 0000000..9fe89f7 --- /dev/null +++ b/server/controllers/profile.js @@ -0,0 +1,116 @@ +const Profile = require("../models/Profile"); +const asyncHandler = require("express-async-handler"); + +// @route POST /profile/create +// @desc Create new profile +// @access Public +exports.createProfile = asyncHandler(async (req, res, next) => { + try { + const { + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + } = req.body; + const profile = await Profile.create({ + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + }); + + res.status(200).json({ + profile, + }); + } catch (err) { + res.status(400); + throw new Error("Something went wrong, please try again"); + } +}); + +// @route PUT /profile +// @desc update a profile with given ID +// @access Private +exports.updateProfile = asyncHandler(async (req, res, next) => { + try { + const id = req.user._id; + + const { + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + } = req.body; + const profile = await Profile.findOneAndUpdate( + { user: id }, + { + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + }, + { new: true } + ); + res.status(200).json({ + profile, + }); + } catch (err) { + res.status(400); + throw new Error("Something went wrong, please try again"); + } +}); + +// @route GET /profile +// @desc gets a profile with the given ID +// @access Private +exports.getProfile = asyncHandler(async (req, res, next) => { + try { + const id = req.user._id; + const profile = await Profile.findOne({ user: id }); + res.status(200).json({ + profile, + }); + } catch (err) { + res.status(400); + throw new Error("Something went wrong, please try again"); + } +}); + +// @route GET /profile +// @desc get all profiles +// @access Private +exports.getAllProfiles = asyncHandler(async (req, res, next) => { + try { + const profiles = await Profile.find(); + res.status(200).json({ + profiles, + }); + } catch (err) { + res.status(400); + throw new Error("Something went wrong, please try again"); + } +}); From 50311bfb232ea480ab2c844ff68bdb3cd4d60281 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Sun, 3 Oct 2021 05:08:55 +0100 Subject: [PATCH 02/18] Create profile.js --- server/routes/profile.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 server/routes/profile.js diff --git a/server/routes/profile.js b/server/routes/profile.js new file mode 100644 index 0000000..a584d45 --- /dev/null +++ b/server/routes/profile.js @@ -0,0 +1,19 @@ +const express = require("express"); +const protect = require("../middleware/auth"); +const {validateProfileId, validateProfileDetails} = require("../validate") +const router = express.Router(); +const { + updateProfile, + getProfile, + getAllProfiles, +} = require("../controllers/profile"); + +router.route("/create").post(protect, validateProfileDetails, createProfile); + +router.route("/update").put(protect, validateProfileId, validateProfileDetails, updateProfile); + +router.route("/").get(protect, getProfile); + +router.route("/profiles").get(protect, getAllProfiles); + +module.exports = router; From 235ae330acaaf76acf6ff9beae85476d1ef38cbd Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Sun, 3 Oct 2021 06:08:01 +0100 Subject: [PATCH 03/18] Update profile.js --- server/controllers/profile.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 9fe89f7..9f61792 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -1,5 +1,6 @@ const Profile = require("../models/Profile"); const asyncHandler = require("express-async-handler"); +const cloudinary = require("cloudinary"); // @route POST /profile/create // @desc Create new profile @@ -114,3 +115,25 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { throw new Error("Something went wrong, please try again"); } }); + +// @route GET /profile +// @desc get all profiles +// @access Private +exports.uploadProfilePic = asyncHandler(async (req, res, next) => { + try { + const {_id} = req.user; + const {fileString} = req.body.data; + const profile = await Profile.find({user: _id}); + + const uploadedResponse = await cloudinary.uploader.upload(fileString, {upload_preset: 'dogSittersAndOwnersPhotos'}); + + const updatedProfile = await + + res.status(201).json({ + msg: "Profile piture uploaded successfully", + }); + } catch (err) { + res.status(500); + throw new Error("Something went wrong, please try again"); + } +}); From ced0e7587e590745f6bf32af52a7ab5210a20afc Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Sun, 3 Oct 2021 06:25:42 +0100 Subject: [PATCH 04/18] made some changes to upload profile feature branch --- server/controllers/profile.js | 19 +++++---- server/models/Profile.js | 72 +++++++++++++++++++++++++++++++++++ server/routes/profile.js | 3 ++ 3 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 server/models/Profile.js diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 9f61792..f6c975b 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -32,11 +32,11 @@ exports.createProfile = asyncHandler(async (req, res, next) => { availability, }); - res.status(200).json({ + res.status(201).json({ profile, }); } catch (err) { - res.status(400); + res.status(500); throw new Error("Something went wrong, please try again"); } }); @@ -80,7 +80,7 @@ exports.updateProfile = asyncHandler(async (req, res, next) => { profile, }); } catch (err) { - res.status(400); + res.status(500); throw new Error("Something went wrong, please try again"); } }); @@ -96,7 +96,7 @@ exports.getProfile = asyncHandler(async (req, res, next) => { profile, }); } catch (err) { - res.status(400); + res.status(500); throw new Error("Something went wrong, please try again"); } }); @@ -111,7 +111,7 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { profiles, }); } catch (err) { - res.status(400); + res.status(500); throw new Error("Something went wrong, please try again"); } }); @@ -125,12 +125,11 @@ exports.uploadProfilePic = asyncHandler(async (req, res, next) => { const {fileString} = req.body.data; const profile = await Profile.find({user: _id}); - const uploadedResponse = await cloudinary.uploader.upload(fileString, {upload_preset: 'dogSittersAndOwnersPhotos'}); - - const updatedProfile = await + const response = await cloudinary.uploader.upload(fileString, {upload_preset: 'dogSittersAndOwnersPhotos'}); + profile.setProfilePic(response.url); - res.status(201).json({ - msg: "Profile piture uploaded successfully", + res.status(200).json({ + msg: "Profile picture uploaded successfully", }); } catch (err) { res.status(500); diff --git a/server/models/Profile.js b/server/models/Profile.js new file mode 100644 index 0000000..db83b1b --- /dev/null +++ b/server/models/Profile.js @@ -0,0 +1,72 @@ +const mongoose = require("mongoose"); + +const timeSchema = new mongoose.Schema({ + day: { + type: String, + enum: ["Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"], + required: true, + }, + //We may need to define a regex for the time range in the future + timeRange: { + type: String, + required: true, + }, +}); + +const profileSchema = new mongoose.Schema({ + firstName: { + type: String, + required: true, + }, + lastName: { + type: String, + required: true, + }, + gender: { + type: String, + enum: ["MALE", "FEMALE", "OTHER"], + required: true, + default: "MALE", + }, + birthday: { + type: Date, + required: false, + }, + /*We may need to discard this email path in the future + as it is also available in the users model. We can simply + populate the profile model and retrieve user email*/ + email: { + type: String, + required: true, + unique: true, + }, + user: { + type: Schema.Types.ObjectId, + ref: 'User', + required: true, + unique: true, + }, + phoneNumber: { + type: Number, + required: true, + }, + location: { + type: String, + required: true, + }, + description: { + type: String, + required: true, + }, + availability: [timeSchema], + profilePic: { + type: String, + default: "", + }, +}); +profileSchema.methods.setProflePic = function (imgUrl) { + this.profilePic = imgUrl; + this.save(); + }; + +module.exports = Profile = mongoose.model("profile", profileSchema); diff --git a/server/routes/profile.js b/server/routes/profile.js index a584d45..bb8cb7b 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -6,6 +6,7 @@ const { updateProfile, getProfile, getAllProfiles, + uploadProfilePic, } = require("../controllers/profile"); router.route("/create").post(protect, validateProfileDetails, createProfile); @@ -14,6 +15,8 @@ router.route("/update").put(protect, validateProfileId, validateProfileDetails, router.route("/").get(protect, getProfile); +router.route("/picture").post(protect, uploadProfilePic); + router.route("/profiles").get(protect, getAllProfiles); module.exports = router; From 45a80b242813186e35d9c60526c76b0a1fff9897 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Sun, 3 Oct 2021 06:54:12 +0100 Subject: [PATCH 05/18] added a dataURL validation middleware --- server/routes/profile.js | 2 +- server/validate.js | 26 +++----------------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/server/routes/profile.js b/server/routes/profile.js index bb8cb7b..b5be983 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -15,7 +15,7 @@ router.route("/update").put(protect, validateProfileId, validateProfileDetails, router.route("/").get(protect, getProfile); -router.route("/picture").post(protect, uploadProfilePic); +router.route("/picture").post(protect, validateDataUrl, uploadProfilePic); router.route("/profiles").get(protect, getAllProfiles); diff --git a/server/validate.js b/server/validate.js index 40a49c9..706bd07 100755 --- a/server/validate.js +++ b/server/validate.js @@ -1,32 +1,12 @@ const { check, validationResult } = require("express-validator"); -exports.validateRegister = [ - check("username", "Please enter a username").not().isEmpty(), - check("email", "Please enter a valid email address").isEmail(), - check( - "password", - "Please enter a password with 6 or more characters" - ).isLength({ - min: 6 - }), +exports.validateDataUrl = [ + check("profilePic", "Invalid data URL").exists(checkFalsyVal).isBase64().isDataURI(), (req, res, next) => { const errors = validationResult(req); - console.log(errors); if (!errors.isEmpty()) return res.status(400).json({ errors: errors.array() }); next(); - } -]; - -exports.validateLogin = [ - check("email", "Please enter a valid email address").isEmail(), - check("password", "Password is required").not().isEmpty(), - (req, res, next) => { - const errors = validationResult(req); - - if (!errors.isEmpty()) - return res.status(400).json({ errors: errors.array() }); - next(); - } + }, ]; From ea75ab576b6c6646cc6fe4af6f496c253752929a Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Mon, 4 Oct 2021 14:22:29 +0100 Subject: [PATCH 06/18] modified the upload picture branch --- server/controllers/profile.js | 14 ++++++++------ server/models/Profile.js | 21 +++++++++++++++++---- server/routes/profile.js | 6 ++++-- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index f6c975b..b29018f 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -121,18 +121,20 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { // @access Private exports.uploadProfilePic = asyncHandler(async (req, res, next) => { try { - const {_id} = req.user; - const {fileString} = req.body.data; - const profile = await Profile.find({user: _id}); + const { _id } = req.user; + const { fileString } = req.body.data; + const profile = await Profile.find({ user: _id }); - const response = await cloudinary.uploader.upload(fileString, {upload_preset: 'dogSittersAndOwnersPhotos'}); + const response = await cloudinary.uploader.upload(fileString, { + upload_preset: "dogSittersAndOwnersPhotos", + }); profile.setProfilePic(response.url); - + res.status(200).json({ msg: "Profile picture uploaded successfully", }); } catch (err) { - res.status(500); + res.status(500); throw new Error("Something went wrong, please try again"); } }); diff --git a/server/models/Profile.js b/server/models/Profile.js index db83b1b..0be63a7 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -42,7 +42,7 @@ const profileSchema = new mongoose.Schema({ }, user: { type: Schema.Types.ObjectId, - ref: 'User', + ref: "User", required: true, unique: true, }, @@ -59,14 +59,27 @@ const profileSchema = new mongoose.Schema({ required: true, }, availability: [timeSchema], - profilePic: { - type: String, + //we may need to store more images per profile + //profile pic will be saved in the photos array with 'profilPic' key + photos: { + type: [ + { + title: { + type: String, + unique: true, + }, + url: { + type: String, + unique: true, + }, + }, + ], default: "", }, }); profileSchema.methods.setProflePic = function (imgUrl) { this.profilePic = imgUrl; this.save(); - }; +}; module.exports = Profile = mongoose.model("profile", profileSchema); diff --git a/server/routes/profile.js b/server/routes/profile.js index b5be983..80222d9 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -1,6 +1,6 @@ const express = require("express"); const protect = require("../middleware/auth"); -const {validateProfileId, validateProfileDetails} = require("../validate") +const { validateProfileId, validateProfileDetails } = require("../validate"); const router = express.Router(); const { updateProfile, @@ -11,7 +11,9 @@ const { router.route("/create").post(protect, validateProfileDetails, createProfile); -router.route("/update").put(protect, validateProfileId, validateProfileDetails, updateProfile); +router + .route("/update") + .put(protect, validateProfileId, validateProfileDetails, updateProfile); router.route("/").get(protect, getProfile); From d19ce2bddb8b4af72ebc41d06b5c9b71ad9cf227 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Mon, 4 Oct 2021 15:23:25 +0100 Subject: [PATCH 07/18] modified the upload photo feature branch --- server/controllers/profile.js | 21 +++++++++++++-------- server/middleware/multer.js | 9 +++++++++ server/models/Profile.js | 17 +++-------------- server/routes/profile.js | 3 ++- server/utils/cloundinary.js | 9 +++++++++ server/validate.js | 11 ----------- 6 files changed, 36 insertions(+), 34 deletions(-) create mode 100644 server/middleware/multer.js create mode 100644 server/utils/cloundinary.js diff --git a/server/controllers/profile.js b/server/controllers/profile.js index b29018f..32b7bb6 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -1,6 +1,6 @@ const Profile = require("../models/Profile"); +const { cloudinary } = require("../utils/cloudinary"); const asyncHandler = require("express-async-handler"); -const cloudinary = require("cloudinary"); // @route POST /profile/create // @desc Create new profile @@ -92,6 +92,11 @@ exports.getProfile = asyncHandler(async (req, res, next) => { try { const id = req.user._id; const profile = await Profile.findOne({ user: id }); + + if (!profile) { + res.status(404); + throw new Error("This profile does not exist"); + } res.status(200).json({ profile, }); @@ -116,22 +121,22 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { } }); -// @route GET /profile -// @desc get all profiles -// @access Private exports.uploadProfilePic = asyncHandler(async (req, res, next) => { try { const { _id } = req.user; - const { fileString } = req.body.data; const profile = await Profile.find({ user: _id }); - const response = await cloudinary.uploader.upload(fileString, { + if (!req.file) { + res.status(400); + throw new Error("You have not chosen any file"); + } + const response = await cloudinary.uploader.upload(req.file.path, { upload_preset: "dogSittersAndOwnersPhotos", }); - profile.setProfilePic(response.url); + profile.setProfilePic(response.secure_url); res.status(200).json({ - msg: "Profile picture uploaded successfully", + msg: "Image uploaded successfully", }); } catch (err) { res.status(500); diff --git a/server/middleware/multer.js b/server/middleware/multer.js new file mode 100644 index 0000000..d99116b --- /dev/null +++ b/server/middleware/multer.js @@ -0,0 +1,9 @@ +const multer = require("multer"); + +const storage = multer.diskStorage({}); + +const upload = multer({ + storage, +}); + +module.exports = upload; \ No newline at end of file diff --git a/server/models/Profile.js b/server/models/Profile.js index 0be63a7..0ba1c7c 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -60,25 +60,14 @@ const profileSchema = new mongoose.Schema({ }, availability: [timeSchema], //we may need to store more images per profile - //profile pic will be saved in the photos array with 'profilPic' key + //profile pic will be saved in the photos array with 'profilePic' key photos: { - type: [ - { - title: { - type: String, - unique: true, - }, - url: { - type: String, - unique: true, - }, - }, - ], + type: [{}], default: "", }, }); profileSchema.methods.setProflePic = function (imgUrl) { - this.profilePic = imgUrl; + this.photos.profilePic = imgUrl; this.save(); }; diff --git a/server/routes/profile.js b/server/routes/profile.js index 80222d9..2003497 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -1,5 +1,6 @@ const express = require("express"); const protect = require("../middleware/auth"); +const upload = require("../middleware/multer"); const { validateProfileId, validateProfileDetails } = require("../validate"); const router = express.Router(); const { @@ -17,7 +18,7 @@ router router.route("/").get(protect, getProfile); -router.route("/picture").post(protect, validateDataUrl, uploadProfilePic); +router.route("/upload").post(protect, upload.single("picture"), uploadProfilePic); router.route("/profiles").get(protect, getAllProfiles); diff --git a/server/utils/cloundinary.js b/server/utils/cloundinary.js new file mode 100644 index 0000000..fe50bb6 --- /dev/null +++ b/server/utils/cloundinary.js @@ -0,0 +1,9 @@ +const cloudinary = require("cloudinary").v2; + +cloudinary.config({ + cloud_name: process.env.CLOUDINARY_NAME, + api_key: process.env.CLOUDINARY_API_KEY, + api_secret: process.env.CLOUDINARY_API_SECRET, +}); + +module.exports = { cloudinary }; \ No newline at end of file diff --git a/server/validate.js b/server/validate.js index 706bd07..8b13789 100755 --- a/server/validate.js +++ b/server/validate.js @@ -1,12 +1 @@ -const { check, validationResult } = require("express-validator"); -exports.validateDataUrl = [ - check("profilePic", "Invalid data URL").exists(checkFalsyVal).isBase64().isDataURI(), - (req, res, next) => { - const errors = validationResult(req); - - if (!errors.isEmpty()) - return res.status(400).json({ errors: errors.array() }); - next(); - }, -]; From 9d017e12da9c15db9b73f1f63e5937dd853ddb42 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Tue, 5 Oct 2021 22:42:46 +0100 Subject: [PATCH 08/18] updated upload photo feature --- server/controllers/profile.js | 8 +-- server/models/Profile.js | 4 +- server/package-lock.json | 123 ++++++++++++++++++++++++++++++++++ server/package.json | 1 + 4 files changed, 128 insertions(+), 8 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 32b7bb6..7aa1527 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -122,7 +122,6 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { }); exports.uploadProfilePic = asyncHandler(async (req, res, next) => { - try { const { _id } = req.user; const profile = await Profile.find({ user: _id }); @@ -133,13 +132,10 @@ exports.uploadProfilePic = asyncHandler(async (req, res, next) => { const response = await cloudinary.uploader.upload(req.file.path, { upload_preset: "dogSittersAndOwnersPhotos", }); - profile.setProfilePic(response.secure_url); + console.log(response) + profile.addPhoto(response.secure_url, "profilePic"); res.status(200).json({ msg: "Image uploaded successfully", }); - } catch (err) { - res.status(500); - throw new Error("Something went wrong, please try again"); - } }); diff --git a/server/models/Profile.js b/server/models/Profile.js index 0ba1c7c..2288ead 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -66,8 +66,8 @@ const profileSchema = new mongoose.Schema({ default: "", }, }); -profileSchema.methods.setProflePic = function (imgUrl) { - this.photos.profilePic = imgUrl; +profileSchema.methods.addPhoto = function (imgUrl, name) { + this.photos.name = imgUrl; this.save(); }; diff --git a/server/package-lock.json b/server/package-lock.json index 5b6afd7..b9eb25d 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -144,6 +144,11 @@ "picomatch": "^2.0.4" } }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -293,6 +298,43 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -489,6 +531,17 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -621,6 +674,38 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -1396,6 +1481,14 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "mocha": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", @@ -1575,6 +1668,21 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz", + "integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==", + "requires": { + "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" + } + }, "nanoid": { "version": "3.1.20", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", @@ -2092,6 +2200,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -2242,6 +2355,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -2432,6 +2550,11 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/server/package.json b/server/package.json index 4e628ee..65b5243 100644 --- a/server/package.json +++ b/server/package.json @@ -21,6 +21,7 @@ "jsonwebtoken": "^8.5.1", "mongoose": "^5.12.8", "morgan": "^1.10.0", + "multer": "^1.4.3", "nodemon": "^2.0.6", "socket.io": "^4.1.0" }, From cbda0a6ccba7a951c5b36a5809bb8c22857f9f95 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Tue, 5 Oct 2021 23:01:40 +0100 Subject: [PATCH 09/18] modified upload photo feature --- server/app.js | 2 + server/models/Profile.js | 2 +- server/package-lock.json | 40 ++++++-- server/package.json | 1 + server/routes/profile.js | 3 +- .../utils/{cloundinary.js => cloudinary.js} | 0 server/validate.js | 97 +++++++++++++++++++ 7 files changed, 136 insertions(+), 9 deletions(-) rename server/utils/{cloundinary.js => cloudinary.js} (100%) diff --git a/server/app.js b/server/app.js index 9054487..89842fb 100755 --- a/server/app.js +++ b/server/app.js @@ -11,6 +11,7 @@ const logger = require("morgan"); const authRouter = require("./routes/auth"); const userRouter = require("./routes/user"); +const profileRouter = require("./routes/profile"); const { json, urlencoded } = express; @@ -43,6 +44,7 @@ app.use((req, res, next) => { app.use("/auth", authRouter); app.use("/users", userRouter); +app.use("/profile", profileRouter); if (process.env.NODE_ENV === "production") { app.use(express.static(path.join(__dirname, "/client/build"))); diff --git a/server/models/Profile.js b/server/models/Profile.js index 2288ead..b40076a 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -41,7 +41,7 @@ const profileSchema = new mongoose.Schema({ unique: true, }, user: { - type: Schema.Types.ObjectId, + type: mongoose.Schema.Types.ObjectId, ref: "User", required: true, unique: true, diff --git a/server/package-lock.json b/server/package-lock.json index b9eb25d..03c065f 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -494,6 +494,22 @@ "mimic-response": "^1.0.0" } }, + "cloudinary": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.27.0.tgz", + "integrity": "sha512-3Slh8gTmEfaut+ZBIMByOXaD60QP5uw46zn3lyYYEA0mhTQ82FIrwfj98s0eZ6PciQJIJ+Ea4QPBl7Ji21TQEA==", + "requires": { + "cloudinary-core": "^2.10.2", + "core-js": "3.6.5", + "lodash": "^4.17.11", + "q": "^1.5.1" + } + }, + "cloudinary-core": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.11.4.tgz", + "integrity": "sha512-F1BZczD6f5mB73D0c8gl/iuacVQQO+UhckNZxeeS9ZIVeIHbsfqwWiAZMQmIvEb7Wti/9MLU0xVwaWOak2THHA==" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -593,6 +609,11 @@ "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", "dev": true }, + "core-js": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -943,9 +964,9 @@ "dev": true }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fresh": { "version": "0.5.2", @@ -1860,11 +1881,11 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -1890,6 +1911,11 @@ "escape-goat": "^2.0.0" } }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", diff --git a/server/package.json b/server/package.json index 65b5243..9aade1b 100644 --- a/server/package.json +++ b/server/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "bcryptjs": "^2.4.3", + "cloudinary": "^1.27.0", "colors": "^1.4.0", "cookie-parser": "^1.4.5", "dotenv": "^8.2.0", diff --git a/server/routes/profile.js b/server/routes/profile.js index 2003497..9cf04bd 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -8,6 +8,7 @@ const { getProfile, getAllProfiles, uploadProfilePic, + createProfile } = require("../controllers/profile"); router.route("/create").post(protect, validateProfileDetails, createProfile); @@ -18,7 +19,7 @@ router router.route("/").get(protect, getProfile); -router.route("/upload").post(protect, upload.single("picture"), uploadProfilePic); +router.route("/upload").post(upload.single("picture"), uploadProfilePic); router.route("/profiles").get(protect, getAllProfiles); diff --git a/server/utils/cloundinary.js b/server/utils/cloudinary.js similarity index 100% rename from server/utils/cloundinary.js rename to server/utils/cloudinary.js diff --git a/server/validate.js b/server/validate.js index 8b13789..5ef4abd 100755 --- a/server/validate.js +++ b/server/validate.js @@ -1 +1,98 @@ +const { check, validationResult } = require("express-validator"); +const msgPrefix = "Please enter a valid"; +const genderOptions = ["MALE", "FEMALE", "OTHER"]; +const checkFalsyVal = { checkFalsy: true }; + +exports.validateRegister = [ + check("username", `${msgPrefix} username`).notEmpty(), + check("email", `${msgPrefix} email address`).isEmail(), + check( + "password", + "Please enter a password with 6 or more characters" + ).isLength({ + min: 6, + }), + (req, res, next) => { + const errors = validationResult(req); + + console.log(errors); + if (!errors.isEmpty()) + return res.status(400).json({ errors: errors.array() }); + next(); + }, +]; + +exports.validateLogin = [ + check("email", `${msgPrefix} email address`).isEmail(), + check("password", "Password is required").notEmpty(), + (req, res, next) => { + const errors = validationResult(req); + + if (!errors.isEmpty()) + return res.status(400).json({ errors: errors.array() }); + next(); + }, +]; + +exports.validateProfileDetails = [ + check("firstName", ` ${msgPrefix} first name`) + .exists(checkFalsyVal) + .trim() + .escape() + .isLength({ max: 20 }), + check("lastName", ` ${msgPrefix} last name`) + .exists(checkFalsyVal) + .trim() + .escape() + .isLength({ max: 20 }), + check("gender", ` ${msgPrefix} gender`) + .exists(checkFalsyVal) + .isIn(genderOptions), + check("birthday", ` ${msgPrefix} birthday format`) + .exists(checkFalsyVal) + .toDate(), + check("email", ` ${msgPrefix} email address`) + .exists(checkFalsyVal) + .trim() + .escape() + .isEmail(), + check("phoneNumber", ` ${msgPrefix} phone number`) + .exists(checkFalsyVal) + .trim() + .isMobilePhone(), + check("location", ` ${msgPrefix} location`) + .exists(checkFalsyVal) + .trim() + .escape() + .isLength({ max: 10 }), + check("profilePic", ` ${msgPrefix} image url`) + .exists(checkFalsyVal) + .escape() + .isURL(), + check("description", ` ${msgPrefix} description format`) + .exists(checkFalsyVal) + .escape() + .isLength({ max: 100 }), + check("availability", ` ${msgPrefix} availability format`) + .exists(checkFalsyVal) + .isArray(), + (req, res, next) => { + const errors = validationResult(req); + + if (!errors.isEmpty()) + return res.status(400).json({ errors: errors.array() }); + next(); + }, +]; + +exports.validateMongoId = [ + check("_id", "Invalid profile ID").exists(checkFalsyVal).isMongoId(), + (req, res, next) => { + const errors = validationResult(req); + + if (!errors.isEmpty()) + return res.status(400).json({ errors: errors.array() }); + next(); + }, +]; From 67a1b49e02da77ab5980230dc86a2f05912fa4b8 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Wed, 6 Oct 2021 12:48:28 +0100 Subject: [PATCH 10/18] updates image upload feature --- server/controllers/profile.js | 24 ++++++++++++------------ server/middleware/multer.js | 21 ++++++++++++++++++++- server/routes/profile.js | 4 ++-- server/utils/cloudinary.js | 4 +++- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 7aa1527..08dafc2 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -122,20 +122,20 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { }); exports.uploadProfilePic = asyncHandler(async (req, res, next) => { - const { _id } = req.user; - const profile = await Profile.find({ user: _id }); + //const { _id } = req.user; + //const profile = await Profile.find({ user: _id }); if (!req.file) { res.status(400); - throw new Error("You have not chosen any file"); + throw new Error("Failed to upload photo, ensure that you have selected a valid file format") } - const response = await cloudinary.uploader.upload(req.file.path, { - upload_preset: "dogSittersAndOwnersPhotos", - }); - console.log(response) - profile.addPhoto(response.secure_url, "profilePic"); - - res.status(200).json({ - msg: "Image uploaded successfully", - }); + let response = await cloudinary.uploader.upload(req.file.path, { + folder: "dogSittersAndOwnersPhotos" + }); + console.log("hi",response) + //profile.addPhoto(response.secure_url, "profilePic"); + + res.status(200).json({ + msg: "Image uploaded successfully", + }); }); diff --git a/server/middleware/multer.js b/server/middleware/multer.js index d99116b..e70999e 100644 --- a/server/middleware/multer.js +++ b/server/middleware/multer.js @@ -1,9 +1,28 @@ const multer = require("multer"); +const path = require("path"); const storage = multer.diskStorage({}); const upload = multer({ storage, + limit: { fileSize: 1000000 }, + fileFilter: (req, file, cb) => { + checkFiletype(file, cb); + }, }); -module.exports = upload; \ No newline at end of file +const checkFiletype = (file, cb) => { + const validExtName = /jpeg|jpg|png|gif/; + const fileTypeCheck = validExtName.test( + path.extname(file.originalname).toLocaleLowerCase() + ); + const mimeTypeCheck = validExtName.test(file.mimetype); + + if (fileTypeCheck && mimeTypeCheck) { + return cb(null, true); + } else { + return cb(null, false); + } +}; + +module.exports = upload; diff --git a/server/routes/profile.js b/server/routes/profile.js index 9cf04bd..5e22f47 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -1,7 +1,7 @@ const express = require("express"); const protect = require("../middleware/auth"); const upload = require("../middleware/multer"); -const { validateProfileId, validateProfileDetails } = require("../validate"); +const { validateMongoId, validateProfileDetails } = require("../validate"); const router = express.Router(); const { updateProfile, @@ -15,7 +15,7 @@ router.route("/create").post(protect, validateProfileDetails, createProfile); router .route("/update") - .put(protect, validateProfileId, validateProfileDetails, updateProfile); + .put(validateMongoId, validateProfileDetails, updateProfile); router.route("/").get(protect, getProfile); diff --git a/server/utils/cloudinary.js b/server/utils/cloudinary.js index fe50bb6..44a9ab1 100644 --- a/server/utils/cloudinary.js +++ b/server/utils/cloudinary.js @@ -1,9 +1,11 @@ const cloudinary = require("cloudinary").v2; +require('dotenv').config(); cloudinary.config({ - cloud_name: process.env.CLOUDINARY_NAME, + cloud_name: process.env.CLOUDINARY_API_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, + secure:true }); module.exports = { cloudinary }; \ No newline at end of file From 3f8fde5c25127a7ee11353f38b441472d26b3513 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Wed, 6 Oct 2021 14:18:36 +0100 Subject: [PATCH 11/18] update cloudinary-IN --- server/controllers/profile.js | 17 ++++++----------- server/middleware/multer.js | 6 ++++-- server/utils/cloudinary.js | 8 +++++--- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 08dafc2..67766a0 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -110,30 +110,25 @@ exports.getProfile = asyncHandler(async (req, res, next) => { // @desc get all profiles // @access Private exports.getAllProfiles = asyncHandler(async (req, res, next) => { - try { const profiles = await Profile.find(); res.status(200).json({ profiles, }); - } catch (err) { - res.status(500); - throw new Error("Something went wrong, please try again"); - } }); exports.uploadProfilePic = asyncHandler(async (req, res, next) => { - //const { _id } = req.user; - //const profile = await Profile.find({ user: _id }); + const { _id, file } = req.user; + const profile = await Profile.find({ user: _id }); - if (!req.file) { + if (!file) { res.status(400); throw new Error("Failed to upload photo, ensure that you have selected a valid file format") } - let response = await cloudinary.uploader.upload(req.file.path, { + const { secure_url } = await cloudinary.uploader.upload(file.path, { folder: "dogSittersAndOwnersPhotos" }); - console.log("hi",response) - //profile.addPhoto(response.secure_url, "profilePic"); + + profile.addPhoto(secure_url, "profilePic"); res.status(200).json({ msg: "Image uploaded successfully", diff --git a/server/middleware/multer.js b/server/middleware/multer.js index e70999e..9c846e8 100644 --- a/server/middleware/multer.js +++ b/server/middleware/multer.js @@ -12,11 +12,13 @@ const upload = multer({ }); const checkFiletype = (file, cb) => { + const { originalname, mimetype } = file; const validExtName = /jpeg|jpg|png|gif/; + const fileTypeCheck = validExtName.test( - path.extname(file.originalname).toLocaleLowerCase() + path.extname(originalname).toLocaleLowerCase() ); - const mimeTypeCheck = validExtName.test(file.mimetype); + const mimeTypeCheck = validExtName.test(mimetype); if (fileTypeCheck && mimeTypeCheck) { return cb(null, true); diff --git a/server/utils/cloudinary.js b/server/utils/cloudinary.js index 44a9ab1..bb561a1 100644 --- a/server/utils/cloudinary.js +++ b/server/utils/cloudinary.js @@ -1,10 +1,12 @@ const cloudinary = require("cloudinary").v2; require('dotenv').config(); +const { CLOUDINARY_API_NAME, CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET } = process.env; + cloudinary.config({ - cloud_name: process.env.CLOUDINARY_API_NAME, - api_key: process.env.CLOUDINARY_API_KEY, - api_secret: process.env.CLOUDINARY_API_SECRET, + cloud_name: CLOUDINARY_API_NAME, + api_key: CLOUDINARY_API_KEY, + api_secret: CLOUDINARY_API_SECRET, secure:true }); From aabcb91516f4b53a10c73ce3b567f21ecbafbd25 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Tue, 12 Oct 2021 09:44:52 +0100 Subject: [PATCH 12/18] made changes to pofile upload feature branch --- server/controllers/profile.js | 3 ++- server/models/Profile.js | 6 +----- server/routes/profile.js | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 67766a0..7855351 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -129,8 +129,9 @@ exports.uploadProfilePic = asyncHandler(async (req, res, next) => { }); profile.addPhoto(secure_url, "profilePic"); + profile.save(); res.status(200).json({ - msg: "Image uploaded successfully", + message: "Image uploaded successfully", }); }); diff --git a/server/models/Profile.js b/server/models/Profile.js index 8654f7f..f39a677 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -32,9 +32,6 @@ const profileSchema = new mongoose.Schema({ type: Date, required: false, }, - /*We may need to discard this email path in the future - as it is also available in the users model. We can simply - populate the profile model and retrieve user email*/ email: { type: String, required: true, @@ -68,8 +65,7 @@ const profileSchema = new mongoose.Schema({ }); profileSchema.methods.addPhoto = function (imgUrl, name) { - this.photos.name = imgUrl; - this.save(); + this.photos[name] = imgUrl; }; module.exports = Profile = mongoose.model("profile", profileSchema); diff --git a/server/routes/profile.js b/server/routes/profile.js index 5e22f47..2f7ee23 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -19,7 +19,7 @@ router router.route("/").get(protect, getProfile); -router.route("/upload").post(upload.single("picture"), uploadProfilePic); +router.route("/upload").post(upload.single("photo"), uploadProfilePic); router.route("/profiles").get(protect, getAllProfiles); From 765edf5ae1b9f1ce3eee6b1e9f203dfabf151adf Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Thu, 14 Oct 2021 00:23:15 +0100 Subject: [PATCH 13/18] Update profile.js --- server/controllers/profile.js | 57 ++++++++++------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 7855351..b6b029c 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -1,12 +1,11 @@ const Profile = require("../models/Profile"); -const { cloudinary } = require("../utils/cloudinary"); const asyncHandler = require("express-async-handler"); // @route POST /profile/create // @desc Create new profile // @access Public exports.createProfile = asyncHandler(async (req, res, next) => { - try { + const { firstName, lastName, @@ -19,6 +18,7 @@ exports.createProfile = asyncHandler(async (req, res, next) => { description, availability, } = req.body; + const profile = await Profile.create({ firstName, lastName, @@ -35,17 +35,12 @@ exports.createProfile = asyncHandler(async (req, res, next) => { res.status(201).json({ profile, }); - } catch (err) { - res.status(500); - throw new Error("Something went wrong, please try again"); - } }); // @route PUT /profile -// @desc update a profile with given ID +// @desc updates a profile with given ID // @access Private exports.updateProfile = asyncHandler(async (req, res, next) => { - try { const id = req.user._id; const { @@ -60,6 +55,7 @@ exports.updateProfile = asyncHandler(async (req, res, next) => { description, availability, } = req.body; + const profile = await Profile.findOneAndUpdate( { user: id }, { @@ -76,62 +72,41 @@ exports.updateProfile = asyncHandler(async (req, res, next) => { }, { new: true } ); + res.status(200).json({ profile, }); - } catch (err) { - res.status(500); - throw new Error("Something went wrong, please try again"); - } }); // @route GET /profile // @desc gets a profile with the given ID // @access Private exports.getProfile = asyncHandler(async (req, res, next) => { - try { const id = req.user._id; const profile = await Profile.findOne({ user: id }); if (!profile) { res.status(404); - throw new Error("This profile does not exist"); + throw new Error("The profile does not exist"); } + res.status(200).json({ profile, }); - } catch (err) { - res.status(500); - throw new Error("Something went wrong, please try again"); - } }); -// @route GET /profile -// @desc get all profiles +// @route GET /profiles +// @desc gets all profiles // @access Private exports.getAllProfiles = asyncHandler(async (req, res, next) => { const profiles = await Profile.find(); - res.status(200).json({ - profiles, - }); -}); -exports.uploadProfilePic = asyncHandler(async (req, res, next) => { - const { _id, file } = req.user; - const profile = await Profile.find({ user: _id }); - - if (!file) { - res.status(400); - throw new Error("Failed to upload photo, ensure that you have selected a valid file format") + if (!profiles) { + res.status(500); + throw new Error("0 results"); } - const { secure_url } = await cloudinary.uploader.upload(file.path, { - folder: "dogSittersAndOwnersPhotos" - }); - profile.addPhoto(secure_url, "profilePic"); - profile.save(); - - res.status(200).json({ - message: "Image uploaded successfully", - }); -}); + res.status(200).json({ + profiles, + }); +}); \ No newline at end of file From b942c38d7ca426923aa9fe88ee2c2bf7a9eb6c2c Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Thu, 14 Oct 2021 00:34:41 +0100 Subject: [PATCH 14/18] made some changes to cloudinary setup --- server/models/Profile.js | 4 ++-- server/routes/profile.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/models/Profile.js b/server/models/Profile.js index f39a677..4b6aeed 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -57,9 +57,9 @@ const profileSchema = new mongoose.Schema({ }, availability: [timeSchema], //we may need to store more images per profile - //profile pic will be saved in the photos array with 'profilePic' key + //profile pic will be saved in the photos object with 'profilePic' key photos: { - type: [{}], + type: {}, default: "", }, }); diff --git a/server/routes/profile.js b/server/routes/profile.js index 2f7ee23..d2d3516 100644 --- a/server/routes/profile.js +++ b/server/routes/profile.js @@ -19,7 +19,7 @@ router router.route("/").get(protect, getProfile); -router.route("/upload").post(upload.single("photo"), uploadProfilePic); +router.route("/upload").post(upload.single("profilePic"), uploadProfilePic); router.route("/profiles").get(protect, getAllProfiles); From d30d2a55224d18b52aa1106e3d2ceb8c3f00ff15 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Thu, 14 Oct 2021 00:50:38 +0100 Subject: [PATCH 15/18] Update Profile.js --- server/models/Profile.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/server/models/Profile.js b/server/models/Profile.js index 4b6aeed..0eb8a15 100644 --- a/server/models/Profile.js +++ b/server/models/Profile.js @@ -32,6 +32,9 @@ const profileSchema = new mongoose.Schema({ type: Date, required: false, }, + /*We may need to discard this email path in the future + as it is also available in the users model. We can simply + populate the profile model and retrieve user email*/ email: { type: String, required: true, @@ -57,15 +60,15 @@ const profileSchema = new mongoose.Schema({ }, availability: [timeSchema], //we may need to store more images per profile - //profile pic will be saved in the photos object with 'profilePic' key + //profile pic will be saved in the photos array with 'profilePic' key photos: { - type: {}, + type: [{}], default: "", }, }); - -profileSchema.methods.addPhoto = function (imgUrl, name) { - this.photos[name] = imgUrl; +profileSchema.methods.setProflePic = function (imgUrl) { + this.photos.profilePic = imgUrl; + this.save(); }; -module.exports = Profile = mongoose.model("profile", profileSchema); +module.exports = Profile = mongoose.model("profile", profileSchema); \ No newline at end of file From 3435cea742fe1c5ee4de159d8cfe212ad44a98e6 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Thu, 14 Oct 2021 00:53:25 +0100 Subject: [PATCH 16/18] Update package-lock.json --- server/package-lock.json | 165 ++------------------------------------- 1 file changed, 8 insertions(+), 157 deletions(-) diff --git a/server/package-lock.json b/server/package-lock.json index 03c065f..5b96c14 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -144,11 +144,6 @@ "picomatch": "^2.0.4" } }, - "append-field": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", - "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -298,43 +293,6 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "busboy": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", - "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", - "requires": { - "dicer": "0.2.5", - "readable-stream": "1.1.x" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -494,22 +452,6 @@ "mimic-response": "^1.0.0" } }, - "cloudinary": { - "version": "1.27.0", - "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.27.0.tgz", - "integrity": "sha512-3Slh8gTmEfaut+ZBIMByOXaD60QP5uw46zn3lyYYEA0mhTQ82FIrwfj98s0eZ6PciQJIJ+Ea4QPBl7Ji21TQEA==", - "requires": { - "cloudinary-core": "^2.10.2", - "core-js": "3.6.5", - "lodash": "^4.17.11", - "q": "^1.5.1" - } - }, - "cloudinary-core": { - "version": "2.11.4", - "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.11.4.tgz", - "integrity": "sha512-F1BZczD6f5mB73D0c8gl/iuacVQQO+UhckNZxeeS9ZIVeIHbsfqwWiAZMQmIvEb7Wti/9MLU0xVwaWOak2THHA==" - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -547,17 +489,6 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", @@ -609,11 +540,6 @@ "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", "dev": true }, - "core-js": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", - "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -695,38 +621,6 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, - "dicer": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", - "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", - "requires": { - "readable-stream": "1.1.x", - "streamsearch": "0.1.2" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -964,9 +858,9 @@ "dev": true }, "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" }, "fresh": { "version": "0.5.2", @@ -1502,14 +1396,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "mocha": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", @@ -1689,21 +1575,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "multer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz", - "integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==", - "requires": { - "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" - } - }, "nanoid": { "version": "3.1.20", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", @@ -1881,11 +1752,11 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "requires": { - "forwarded": "0.2.0", + "forwarded": "~0.1.2", "ipaddr.js": "1.9.1" } }, @@ -1911,11 +1782,6 @@ "escape-goat": "^2.0.0" } }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -2226,11 +2092,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", @@ -2381,11 +2242,6 @@ "mime-types": "~2.1.24" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -2576,11 +2432,6 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -2635,4 +2486,4 @@ "dev": true } } -} +} \ No newline at end of file From 2af457badd2a1e81afb0289d8b7aaef00ca38576 Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Thu, 14 Oct 2021 16:40:17 +0100 Subject: [PATCH 17/18] revert a temporary change --- server/package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/package-lock.json b/server/package-lock.json index 5b96c14..5b6afd7 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -2486,4 +2486,4 @@ "dev": true } } -} \ No newline at end of file +} From 3082dd4768a181b096b85abc0f250a7427ab933c Mon Sep 17 00:00:00 2001 From: Gamey001 Date: Fri, 15 Oct 2021 17:45:25 +0100 Subject: [PATCH 18/18] Update profile.js --- server/controllers/profile.js | 131 ++++++++++++++++------------------ 1 file changed, 62 insertions(+), 69 deletions(-) diff --git a/server/controllers/profile.js b/server/controllers/profile.js index b6b029c..492642f 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -5,45 +5,59 @@ const asyncHandler = require("express-async-handler"); // @desc Create new profile // @access Public exports.createProfile = asyncHandler(async (req, res, next) => { + const { + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + } = req.body; - const { - firstName, - lastName, - gender, - birthday, - email, - phoneNumber, - location, - profilePic, - description, - availability, - } = req.body; - - const profile = await Profile.create({ - firstName, - lastName, - gender, - birthday, - email, - phoneNumber, - location, - profilePic, - description, - availability, - }); + const profile = await Profile.create({ + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + }); - res.status(201).json({ - profile, - }); + res.status(201).json({ + profile, + }); }); // @route PUT /profile // @desc updates a profile with given ID // @access Private exports.updateProfile = asyncHandler(async (req, res, next) => { - const id = req.user._id; + const id = req.user._id; + + const { + firstName, + lastName, + gender, + birthday, + email, + phoneNumber, + location, + profilePic, + description, + availability, + } = req.body; - const { + const profile = await Profile.findOneAndUpdate( + { user: id }, + { firstName, lastName, gender, @@ -54,59 +68,38 @@ exports.updateProfile = asyncHandler(async (req, res, next) => { profilePic, description, availability, - } = req.body; + }, + { new: true } + ); - const profile = await Profile.findOneAndUpdate( - { user: id }, - { - firstName, - lastName, - gender, - birthday, - email, - phoneNumber, - location, - profilePic, - description, - availability, - }, - { new: true } - ); - - res.status(200).json({ - profile, - }); + res.status(200).json({ + profile, + }); }); // @route GET /profile // @desc gets a profile with the given ID // @access Private exports.getProfile = asyncHandler(async (req, res, next) => { - const id = req.user._id; - const profile = await Profile.findOne({ user: id }); + const id = req.user._id; + const profile = await Profile.findOne({ user: id }); - if (!profile) { - res.status(404); - throw new Error("The profile does not exist"); - } + if (!profile.length) return res.json({ profile }); - res.status(200).json({ - profile, - }); + res.status(200).json({ + profile, + }); }); // @route GET /profiles // @desc gets all profiles // @access Private exports.getAllProfiles = asyncHandler(async (req, res, next) => { - const profiles = await Profile.find(); + const profiles = await Profile.find(); - if (!profiles) { - res.status(500); - throw new Error("0 results"); - } + if (!profiles.length) return res.json({ profile }); - res.status(200).json({ - profiles, - }); -}); \ No newline at end of file + res.status(200).json({ + profiles, + }); +});