diff --git a/Project/.DS_Store b/Project/.DS_Store new file mode 100644 index 0000000..175ed52 Binary files /dev/null and b/Project/.DS_Store differ diff --git a/Project/app.js b/Project/app.js index 470991a..74c548c 100644 --- a/Project/app.js +++ b/Project/app.js @@ -19,16 +19,17 @@ const app = express(); require("./config")(app); const capitalize = require("./utils/capitalize"); -const projectName = "project2"; +const projectName = "AIRBNVAN"; -app.locals.appTitle = `${capitalize(projectName)} created with IronLauncher`; +app.locals.appTitle = `${(projectName)}`; // 👇 Start handling routes here const indexRoutes = require("./routes/index.routes"); app.use("/", indexRoutes); const authRoutes = require("./routes/auth.routes"); -app.use("/auth", authRoutes); +app.use("/", authRoutes); + // ❗ To handle errors. Routes that don't exist or errors that you handle in specific routes require("./error-handling")(app); diff --git a/Project/bin/seeds.js b/Project/bin/seeds.js deleted file mode 100644 index 608043c..0000000 --- a/Project/bin/seeds.js +++ /dev/null @@ -1,23 +0,0 @@ -const mongoose = require("mongoose") - -// Require the models, Example: (-- const Book = require("../models/Book.model") --) - -const MONGO_URI = "mongodb://localhost:27017/project2" - - -const createSeeds = async function () { - try { - const connect = await mongoose.connect(MONGO_URI) - console.log(`Connected to database: ${connect.connections[0].name}`) - - // Clear DB, Example: (-- const deleteAll = await Book.deleteMany() --) - // console.log("Db clean") - - const dbClose = await mongoose.connection.close() - console.log("Seeds created") - } catch (err) { - console.log(`Error creating the seeds: ${err}`) - } -} - -createSeeds() diff --git a/Project/config/cloudinary.config.js b/Project/config/cloudinary.config.js new file mode 100644 index 0000000..27ec326 --- /dev/null +++ b/Project/config/cloudinary.config.js @@ -0,0 +1,22 @@ +const cloudinary = require('cloudinary').v2; +const { CloudinaryStorage } = require('multer-storage-cloudinary'); +const multer = require('multer'); + +cloudinary.config({ + cloud_name: process.env.CLOUDINARY_NAME, + api_key: process.env.CLOUDINARY_KEY, + api_secret: process.env.CLOUDINARY_SECRET +}); + +const storage = new CloudinaryStorage({ + // cloudinary: cloudinary, + cloudinary, + params: { + allowed_formats: ['jpg', 'png'], + folder: 'AIRBnvan' // The name of the folder in cloudinary + // resource_type: 'raw' => this is in case you want to upload other type of files, not just images + } +}); + +// storage: storage +module.exports = multer({ storage }); \ No newline at end of file diff --git a/Project/config/session.config.js b/Project/config/session.config.js new file mode 100644 index 0000000..e69de29 diff --git a/Project/db/index.js b/Project/db/index.js index 25345b6..aee28ef 100644 --- a/Project/db/index.js +++ b/Project/db/index.js @@ -6,7 +6,7 @@ const mongoose = require("mongoose"); // If no env has been set, we dynamically set it to whatever the folder name was upon the creation of the app const MONGO_URI = - process.env.MONGODB_URI || "mongodb://localhost:27017/project2"; + process.env.MONGODB_URI || "mongodb://localhost:27017/Project_park4night"; mongoose .connect(MONGO_URI) diff --git a/Project/middleware/isLoggedIn.js b/Project/middleware/isLoggedIn.js index f2b6982..c25c9ed 100644 --- a/Project/middleware/isLoggedIn.js +++ b/Project/middleware/isLoggedIn.js @@ -1,8 +1,6 @@ module.exports = (req, res, next) => { // checks if the user is logged in when trying to access a specific page - if (!req.session.currentUser) { - return res.redirect("/auth/login"); - } + if (!req.session.currentUser) return res.redirect("/login") next(); }; diff --git a/Project/models/Comment.model.js b/Project/models/Comment.model.js new file mode 100644 index 0000000..d5e4fca --- /dev/null +++ b/Project/models/Comment.model.js @@ -0,0 +1,21 @@ +const { Schema, model } = require("mongoose"); +const commentSchema = new Schema( + { + description: { + type: String, + required: true, + trim: true, + }, + author:{ type: Schema.Types.ObjectId, ref: 'User' }, + commentLike: [{ type: Schema.Types.ObjectId, ref: 'CommentLike' }], + spot:{ type: Schema.Types.ObjectId, ref: 'Spot' }, + }, + { + timestamps: true, + } +); + + const Comment = model("Comment", commentSchema); + + module.exports = Comment; + \ No newline at end of file diff --git a/Project/models/CommentLike.model.js b/Project/models/CommentLike.model.js new file mode 100644 index 0000000..90cf076 --- /dev/null +++ b/Project/models/CommentLike.model.js @@ -0,0 +1,15 @@ +const { Schema, model } = require("mongoose"); +const commentLikeSchema = new Schema( + { + comment: { type: Schema.Types.ObjectId, ref: 'Comment' }, + user: { type: Schema.Types.ObjectId, ref: 'User' }, + }, + { + timestamps: true, + } +); + + const CommentLike = model("CommentLike", commentLikeSchema); + + module.exports = CommentLike; + \ No newline at end of file diff --git a/Project/models/Spot.model.js b/Project/models/Spot.model.js new file mode 100644 index 0000000..7ff6214 --- /dev/null +++ b/Project/models/Spot.model.js @@ -0,0 +1,68 @@ +const { Schema, model } = require("mongoose"); +const spotSchema = new Schema( + { + name: { + type: String, + // required: true, + unique: true, + trim: true, + }, + coordinates: { + type: String, + // required: true, + unique: true, + trim: true, + }, + address: { + type: String, + required: false, + trim: true, + }, + province: { + type: String, + required: false, + }, + rating: { + type: Number, min: 0, max: 10, + // required: true, + }, + amenities: { + type: Object, + required: false, + Toilet : {type: Boolean}, + BBQ : {type: Boolean}, + Electricity : {type: Boolean}, + Drinking_water: {type: Boolean}, + Trash_can: {type:Boolean}, + Shower: {type:Boolean}, + }, + webpage: { + type: String, + }, + UserSpot: { type: Schema.Types.ObjectId, ref: 'UserSpot' }, + comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }], + description: { + type: String, + // required: true, + }, + price : { + type: Number, + required: false, + }, + images: { + imagesUrl: [String], + }, + Number_parking_spots: { + type: Number, + required: false, + } +}, + { + timestamps: true, + } +); + + const Spot = model("Spot", spotSchema); + + module.exports = Spot; + \ No newline at end of file diff --git a/Project/models/User.model.js b/Project/models/User.model.js index 0dacd5d..85c68f4 100644 --- a/Project/models/User.model.js +++ b/Project/models/User.model.js @@ -1,11 +1,15 @@ const { Schema, model } = require("mongoose"); -// TODO: Please make sure you edit the User model to whatever makes sense in this case const userSchema = new Schema( { + fullName: { + type: String, + required: true, + trim:true, + }, username: { type: String, - required: false, + required: true, unique: true, trim: true, }, @@ -20,9 +24,11 @@ const userSchema = new Schema( type: String, required: true, }, + UserSpot: [{ type: Schema.Types.ObjectId, ref: 'UserSpot' }], + comments: [{ type: Schema.Types.ObjectId, ref: 'Comment' }], + commentLike: [{ type: Schema.Types.ObjectId, ref: 'CommentLike' }] }, - { - // this second object adds extra properties: `createdAt` and `updatedAt` + { timestamps: true, } ); diff --git a/Project/models/UserSpot.model.js b/Project/models/UserSpot.model.js new file mode 100644 index 0000000..8aef710 --- /dev/null +++ b/Project/models/UserSpot.model.js @@ -0,0 +1,14 @@ +const { Schema, model } = require("mongoose"); +const UserSpotSchema = new Schema( + { + spot: { type: Schema.Types.ObjectId, ref: 'Spot' }, + user: { type: Schema.Types.ObjectId, ref: 'User' }, + }, + { + timestamps: true, + } +); + + const UserSpot = model("UserSpot", UserSpotSchema); + + module.exports = UserSpot; diff --git a/Project/package-lock.json b/Project/package-lock.json index 364240f..1d019dd 100644 --- a/Project/package-lock.json +++ b/Project/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "bcrypt": "^5.1.0", + "cloudinary": "^1.32.0", "connect-mongo": "^4.6.0", "cookie-parser": "^1.4.6", "dotenv": "^16.0.3", @@ -17,6 +18,8 @@ "hbs": "^4.2.0", "mongoose": "^6.7.1", "morgan": "^1.10.0", + "multer": "^1.4.5-lts.1", + "multer-storage-cloudinary": "^4.0.0", "serve-favicon": "^2.5.0" }, "devDependencies": { @@ -1038,6 +1041,15 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/@types/node": { "version": "18.11.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", @@ -1074,6 +1086,27 @@ "node": ">= 0.6" } }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "optional": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "optional": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -1106,6 +1139,11 @@ "node": ">= 8" } }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -1139,6 +1177,18 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "optional": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1303,6 +1353,22 @@ "ieee754": "^1.1.13" } }, + "node_modules/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==" + }, + "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/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1358,6 +1424,31 @@ "node": ">=10" } }, + "node_modules/cloudinary": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.32.0.tgz", + "integrity": "sha512-hbc5/ilOkwD49+Lucqze3z+2Tejc3YdH4tkI+y1Ciabi9Qh9MYcy4M3rYeDAYiMS/jIz5FfHOzx+JjVnPJxNAQ==", + "dependencies": { + "cloudinary-core": "^2.10.2", + "core-js": "^3.6.5", + "lodash": "^4.17.21", + "q": "^1.5.1" + }, + "engines": { + "node": ">=0.6" + }, + "optionalDependencies": { + "proxy-agent": "^5.0.0" + } + }, + "node_modules/cloudinary-core": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.13.0.tgz", + "integrity": "sha512-Nt0Q5I2FtenmJghtC4YZ3MZZbGg1wLm84SsxcuVwZ83OyJqG9CNIGp86CiI6iDv3QobaqBUpOT7vg+HqY5HxEA==", + "peerDependencies": { + "lodash": ">=4.0" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -1371,6 +1462,47 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/connect-mongo": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-4.6.0.tgz", @@ -1435,6 +1567,30 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/core-js": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", + "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1451,6 +1607,27 @@ } } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "optional": true + }, + "node_modules/degenerator": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.2.tgz", + "integrity": "sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==", + "optional": true, + "dependencies": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0", + "vm2": "^3.9.8" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -1520,6 +1697,59 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "optional": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "optional": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "optional": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -1629,6 +1859,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "optional": true + }, "node_modules/fast-xml-parser": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", @@ -1645,6 +1881,15 @@ "url": "https://paypal.me/naturalintelligence" } }, + "node_modules/file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "optional": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1708,6 +1953,20 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "optional": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, "node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -1738,6 +1997,43 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", + "optional": true, + "dependencies": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ftp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true + }, + "node_modules/ftp/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/ftp/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -1775,6 +2071,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1806,6 +2119,12 @@ "node": ">= 6" } }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "optional": true + }, "node_modules/handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -1890,6 +2209,20 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -2015,6 +2348,20 @@ "node": ">=0.12.0" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optional": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/kareem": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz", @@ -2031,6 +2378,24 @@ "node": ">8" } }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "optional": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2295,6 +2660,42 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "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/multer-storage-cloudinary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz", + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", + "peerDependencies": { + "cloudinary": "^1.21.0" + } + }, + "node_modules/multer/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -2308,6 +2709,15 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "optional": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/node-addon-api": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", @@ -2474,6 +2884,63 @@ "wrappy": "1" } }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "optional": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pac-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", + "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", + "optional": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^5.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/pac-resolver": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", + "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", + "optional": true, + "dependencies": { + "degenerator": "^3.0.2", + "ip": "^1.1.5", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/pac-resolver/node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "optional": true + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -2507,6 +2974,20 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "optional": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2519,6 +3000,46 @@ "node": ">= 0.10" } }, + "node_modules/proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", + "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", + "optional": true, + "dependencies": { + "agent-base": "^6.0.0", + "debug": "4", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^5.0.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^5.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "optional": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/proxy-agent/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "optional": true + }, "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -2533,6 +3054,15 @@ "node": ">=6" } }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -2822,6 +3352,20 @@ "npm": ">= 3.0.0" } }, + "node_modules/socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "optional": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2847,6 +3391,14 @@ "node": ">= 0.8" } }, + "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/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -2977,6 +3529,18 @@ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", "optional": true }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "optional": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -2989,6 +3553,11 @@ "node": ">= 0.6" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -3018,6 +3587,15 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -3056,6 +3634,22 @@ "node": ">= 0.8" } }, + "node_modules/vm2": { + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", + "integrity": "sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==", + "optional": true, + "dependencies": { + "acorn": "^8.7.0", + "acorn-walk": "^8.2.0" + }, + "bin": { + "vm2": "bin/vm2" + }, + "engines": { + "node": ">=6.0" + } + }, "node_modules/walk": { "version": "2.3.15", "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.15.tgz", @@ -3092,6 +3686,15 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -3102,6 +3705,23 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==", + "optional": true, + "engines": { + "node": "*" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -3970,6 +4590,12 @@ "tar": "^6.1.11" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "optional": true + }, "@types/node": { "version": "18.11.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz", @@ -4003,6 +4629,18 @@ "negotiator": "0.6.3" } }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "optional": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "optional": true + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -4026,6 +4664,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": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==" + }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -4056,6 +4699,15 @@ "safer-buffer": "^2.1.0" } }, + "ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "optional": true, + "requires": { + "tslib": "^2.0.1" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -4176,6 +4828,19 @@ "ieee754": "^1.1.13" } }, + "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": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "requires": { + "streamsearch": "^1.1.0" + } + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -4211,6 +4876,24 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, + "cloudinary": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.32.0.tgz", + "integrity": "sha512-hbc5/ilOkwD49+Lucqze3z+2Tejc3YdH4tkI+y1Ciabi9Qh9MYcy4M3rYeDAYiMS/jIz5FfHOzx+JjVnPJxNAQ==", + "requires": { + "cloudinary-core": "^2.10.2", + "core-js": "^3.6.5", + "lodash": "^4.17.21", + "proxy-agent": "^5.0.0", + "q": "^1.5.1" + } + }, + "cloudinary-core": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.13.0.tgz", + "integrity": "sha512-Nt0Q5I2FtenmJghtC4YZ3MZZbGg1wLm84SsxcuVwZ83OyJqG9CNIGp86CiI6iDv3QobaqBUpOT7vg+HqY5HxEA==", + "requires": {} + }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -4221,6 +4904,46 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "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" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "connect-mongo": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-4.6.0.tgz", @@ -4267,6 +4990,22 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "core-js": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", + "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==", + "optional": true + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -4275,6 +5014,24 @@ "ms": "2.1.2" } }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "optional": true + }, + "degenerator": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.2.tgz", + "integrity": "sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==", + "optional": true, + "requires": { + "ast-types": "^0.13.2", + "escodegen": "^1.8.1", + "esprima": "^4.0.0", + "vm2": "^3.9.8" + } + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", @@ -4325,6 +5082,37 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "optional": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "optional": true + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "optional": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "optional": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -4423,6 +5211,12 @@ } } }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "optional": true + }, "fast-xml-parser": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.11.tgz", @@ -4432,6 +5226,12 @@ "strnum": "^1.0.5" } }, + "file-uri-to-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz", + "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==", + "optional": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -4485,6 +5285,17 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "optional": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -4505,6 +5316,42 @@ "dev": true, "optional": true }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==", + "optional": true, + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "optional": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "optional": true, + "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": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "optional": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4536,6 +5383,20 @@ "has-symbols": "^1.0.3" } }, + "get-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz", + "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==", + "optional": true, + "requires": { + "@tootallnate/once": "1", + "data-uri-to-buffer": "3", + "debug": "4", + "file-uri-to-path": "2", + "fs-extra": "^8.1.0", + "ftp": "^0.3.10" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -4558,6 +5419,12 @@ "is-glob": "^4.0.1" } }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "optional": true + }, "handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -4615,6 +5482,17 @@ "toidentifier": "1.0.1" } }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "optional": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -4702,6 +5580,20 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "optional": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "kareem": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.4.1.tgz", @@ -4715,6 +5607,21 @@ "asn1.js": "^5.4.1" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "optional": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -4913,6 +5820,36 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "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==", + "requires": { + "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" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "requires": { + "minimist": "^1.2.6" + } + } + } + }, + "multer-storage-cloudinary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz", + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", + "requires": {} + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -4923,6 +5860,12 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "optional": true + }, "node-addon-api": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz", @@ -5048,6 +5991,56 @@ "wrappy": "1" } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "optional": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "pac-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz", + "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==", + "optional": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4", + "get-uri": "3", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "5", + "pac-resolver": "^5.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "5" + } + }, + "pac-resolver": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz", + "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==", + "optional": true, + "requires": { + "degenerator": "^3.0.2", + "ip": "^1.1.5", + "netmask": "^2.0.2" + }, + "dependencies": { + "ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==", + "optional": true + } + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -5069,6 +6062,17 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "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", @@ -5078,6 +6082,45 @@ "ipaddr.js": "1.9.1" } }, + "proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz", + "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==", + "optional": true, + "requires": { + "agent-base": "^6.0.0", + "debug": "4", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^5.0.0", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^5.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "optional": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "optional": true + } + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "optional": true + }, "pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", @@ -5089,6 +6132,11 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" + }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -5310,6 +6358,17 @@ "smart-buffer": "^4.2.0" } }, + "socks-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz", + "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==", + "optional": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "4", + "socks": "^2.3.3" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5329,6 +6388,11 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -5431,6 +6495,15 @@ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==", "optional": true }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "optional": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -5440,6 +6513,11 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -5460,6 +6538,12 @@ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "dev": true }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "optional": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -5486,6 +6570,16 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, + "vm2": { + "version": "3.9.11", + "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.11.tgz", + "integrity": "sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==", + "optional": true, + "requires": { + "acorn": "^8.7.0", + "acorn-walk": "^8.2.0" + } + }, "walk": { "version": "2.3.15", "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.15.tgz", @@ -5516,6 +6610,12 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "optional": true + }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -5526,6 +6626,17 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==", + "optional": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/Project/package.json b/Project/package.json index 7eec43e..9618086 100644 --- a/Project/package.json +++ b/Project/package.json @@ -8,6 +8,7 @@ }, "dependencies": { "bcrypt": "^5.1.0", + "cloudinary": "^1.32.0", "connect-mongo": "^4.6.0", "cookie-parser": "^1.4.6", "dotenv": "^16.0.3", @@ -16,6 +17,8 @@ "hbs": "^4.2.0", "mongoose": "^6.7.1", "morgan": "^1.10.0", + "multer": "^1.4.5-lts.1", + "multer-storage-cloudinary": "^4.0.0", "serve-favicon": "^2.5.0" }, "devDependencies": { diff --git a/Project/public/.DS_Store b/Project/public/.DS_Store new file mode 100644 index 0000000..cd3a2cf Binary files /dev/null and b/Project/public/.DS_Store differ diff --git a/Project/public/images/.DS_Store b/Project/public/images/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/Project/public/images/.DS_Store differ diff --git a/Project/public/images/Alex.jpg b/Project/public/images/Alex.jpg new file mode 100644 index 0000000..a9bab10 Binary files /dev/null and b/Project/public/images/Alex.jpg differ diff --git a/Project/public/images/VAN.png b/Project/public/images/VAN.png new file mode 100644 index 0000000..ed072ce Binary files /dev/null and b/Project/public/images/VAN.png differ diff --git a/Project/public/images/add-logo.png b/Project/public/images/add-logo.png new file mode 100644 index 0000000..d2774fe Binary files /dev/null and b/Project/public/images/add-logo.png differ diff --git a/Project/public/images/background.jpeg b/Project/public/images/background.jpeg new file mode 100644 index 0000000..63ef186 Binary files /dev/null and b/Project/public/images/background.jpeg differ diff --git a/Project/public/images/background2.jpeg b/Project/public/images/background2.jpeg new file mode 100644 index 0000000..7ce8e61 Binary files /dev/null and b/Project/public/images/background2.jpeg differ diff --git a/Project/public/images/bariloche.webp b/Project/public/images/bariloche.webp new file mode 100644 index 0000000..ab71e80 Binary files /dev/null and b/Project/public/images/bariloche.webp differ diff --git a/Project/public/images/edit.png b/Project/public/images/edit.png new file mode 100644 index 0000000..3226632 Binary files /dev/null and b/Project/public/images/edit.png differ diff --git a/Project/public/images/home.png b/Project/public/images/home.png new file mode 100644 index 0000000..df2db9f Binary files /dev/null and b/Project/public/images/home.png differ diff --git a/Project/public/images/like.png b/Project/public/images/like.png new file mode 100644 index 0000000..d583356 Binary files /dev/null and b/Project/public/images/like.png differ diff --git a/Project/public/images/map-logo.png b/Project/public/images/map-logo.png new file mode 100644 index 0000000..1d2f6cc Binary files /dev/null and b/Project/public/images/map-logo.png differ diff --git a/Project/public/images/messi balones.jpg b/Project/public/images/messi balones.jpg new file mode 100644 index 0000000..89ab860 Binary files /dev/null and b/Project/public/images/messi balones.jpg differ diff --git a/Project/public/images/profile-logo.png b/Project/public/images/profile-logo.png new file mode 100644 index 0000000..900e204 Binary files /dev/null and b/Project/public/images/profile-logo.png differ diff --git a/Project/public/images/profile.png b/Project/public/images/profile.png new file mode 100644 index 0000000..298371c Binary files /dev/null and b/Project/public/images/profile.png differ diff --git a/Project/public/images/van-logo.png b/Project/public/images/van-logo.png new file mode 100644 index 0000000..26f0916 Binary files /dev/null and b/Project/public/images/van-logo.png differ diff --git a/Project/public/js/script.js b/Project/public/js/script.js index 60f5e84..6e688d6 100644 --- a/Project/public/js/script.js +++ b/Project/public/js/script.js @@ -1,4 +1,50 @@ // https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event document.addEventListener("DOMContentLoaded", () => { - console.log("project2 JS imported successfully!"); + console.log("Mapbox JS file imported successfully!"); + + // Select the elements that store the info about the display of the map + const mapCenter = document.querySelector(".map-center").innerHTML.split(",") + const mapZoom = document.querySelector(".map-zoom").innerHTML + + // Select the elements that store the info about the locatinos and markers + const popupDivs = document.querySelectorAll(".popup") + const posDivs = document.querySelectorAll(".pos") + const markerDivs = document.querySelectorAll(".marker") + + console.log("connecting to mapbox") + // Create an array to store all the popups (one for each location) + const popups = [] + mapboxgl.accessToken = 'pk.eyJ1IjoiY2FybGVzcHVuYSIsImEiOiJjbGExNTNhMmIwNGJnM3Ftbzdjb21rbTR3In0.w6aVfjk2ZJCyzRVl1-cCGA'; + + // Generating the map + const map = new mapboxgl.Map({ + container: 'map', + // Choose from Mapbox's core styles, or make your own style with Mapbox Studio + style: "mapbox://styles/mapbox/streets-v11", + center: mapCenter, + zoom: (mapZoom) + }); + + // Create the popus for each location and store them into the popus array + popupDivs.forEach((popupDiv) => { + const popup = popupDiv.innerHTML + popups.push(new mapboxgl.Popup({ offset: 5 }).setHTML( + `${popup}` + )) + }) + + // Create a marker for every position + posDivs.forEach((posDiv, i) => { + console.log("marker pitstop") + const posS = posDiv.innerText.split(",") + const pos = [posS[1], posS[0]] + new mapboxgl.Marker(markerDivs[i]) + .setLngLat(pos) + .setPopup(popups[i]) // sets a popup on this marker + .addTo(map) + }) }); + + + + diff --git a/Project/public/stylesheets/style.css b/Project/public/stylesheets/style.css index 225ae16..2200be5 100644 --- a/Project/public/stylesheets/style.css +++ b/Project/public/stylesheets/style.css @@ -1,12 +1,575 @@ + + body { - padding: 50px; + /* padding: 50px; */ + margin: 0px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; + width: 100vw; } +section{ + position: absolute; + top: 70px; + bottom: 100px; + left: 0px; + right: 0px; + overflow: auto; +} +span{ + margin:10px; + padding: 5px; +} a { color: #00b7ff; + + margin: 12px; + font-size: 20px; } h1 { color: 15px; } + +#to-left{ + display: flex; +} + +#to-center{ + display: flex; + align-items: center; +} + +#to-rigth{ + display: flex; + align-items: center; +} + +.nav-bar { + display: flex; + justify-content: space-around; + align-items: center; + width: 350px; + height: 40px; + margin-top: 15px; +} + +#logout-form{ + display: flex; + justify-content: center; +} + +button{ + display: flex; + align-items: center; + cursor: pointer; + border-style: none; + background-color: transparent; +} + +a{ + color: inherit; + text-decoration: none; +} + +ul{ + display: flex; + margin: 0px; + margin-left: -42px; + align-content: flex-start; + justify-content: space-evenly; + flex-direction: row; + flex-wrap: wrap; + padding: 0px; +} + + +li{ + display: flex; + padding: 1px; +} +nav{ + display: flex; + justify-content: space-around; + background-color: #5EBE90; + color: black; + position: absolute; + height: 70px; + right: 0px; + left: 0px; + top: 0px; + overflow: hidden; +} + +footer{ + display: flex; + justify-content: space-around; + width: 390px; + height: 100px; + align-items: center; + background-color: #5EBE90; + position: absolute; + bottom: 0px; + left: 0px; + right: 0px; + overflow: hidden; +} + +#background{ + height: 100%; + background-position: center; + background-repeat: no-repeat; + background-size: cover; + background-image: url("/images/background.jpeg");; +} + +#image_label{ + background-color: white; +} + +img{ + width: 80px; +} + +.van-logo{ + width: 76px; + object-fit: cover; + margin-top: -46px; + margin-left: -22px; + position: absolute; +} + + +#form{ + display: flex; + flex-direction: column; + margin-top: 60px; +} + +#form h2{ + display: flex; + flex-direction: column; + align-items: center; + font-size: 27px; + padding: 5px; + margin-top: 40px; +} + +#form form{ + display: flex; + flex-direction: column; + margin-left: 20px; + font-size: 24px; + margin-top: 30px; +} + +#form button{ + border: solid; + display: flex; + /* justify-content: center; */ + margin-top: 40px; + font-size: 26px; + color: white; + background-color: black; + width: fit-content; + align-items: center; + padding: 10px; + border-end-start-radius: 10px; +} + + +#form input{ + border-radius: 5px; + border-width: thin; + height: 34px; + font-size: 18px; +} + +#form label{ + margin-top: 30px !important; + display: flex; + flex-direction: column; + margin-right: 20px; +} + +#login-form{ + display: flex; + flex-direction: column; + margin-top: 60px; +} + +#login-form h2{ + display: flex; + flex-direction: column; + align-items: center; + font-size: 40px; + margin-top: 58px; +} + +#login-form form{ + display: flex; + flex-direction: column; + margin-top: 40px; + margin-left: 20px; + font-size: 24px; +} + +#login-form button{ + border: solid; + display: flex; + /* justify-content: center; */ + margin-top: 40px; + font-size: 26px; + color: white; + background-color: black; + width: fit-content; + align-items: center; + padding: 10px; + border-end-start-radius: 10px; +} + +#login-form label{ + margin-top: 15px; +} + +#login-form input{ + border-radius: 5px; + border-width: thin; + height: 34px; + font-size: 18px; + width: 247px; +} + +#form-spot{ + display: flex; + flex-direction: column; + margin-top: 20px; +} + +#form-spot h2{ + display: flex; + flex-direction: column; + align-items: center; + font-size: 40px; +} + +#ratinginput input{ + height: 20px; + width: 20px; +} +#form-spot form{ + display: flex; + flex-direction: column; + font-size: 24px; + margin-left: 10px; + margin-right: 10px; +} + +#form-spot button{ + display: flex; + justify-content: center; + margin-top: 40px; + font-size: 21px; + width: fit-content; + padding: 12px; + align-self: center; + border-bottom-right-radius: 17px; +} + +#form-spot label{ + margin-top: 15px; +} + +#form-spot input{ + border-radius: 5px; + border-width: thin; + height: 30px; +} + +.description-spot{ + display: flex; +} + +.amenities-spot{ + display: flex; + list-style-type: none; + width: 100%; + flex-direction: column; +} + +ul{ + display: flex; + margin: 0px; +} + + +#profile { + display: flex; + flex-direction: column; +} + +.profilePic img{ + width: 390px; + height: 262px; + object-fit: cover; +} + +.profilePic { + position: relative; +} + +.editPic { + position: absolute; + object-fit: cover; + top: 3px; + right: 5px; +} + +.editpic img{ + width: 30px !important; +} + +#profile{ + margin-bottom: 15px; + align-items: center; +} + +#profile p{ + display: flex; + font-size: 22px; + margin-left: 15px; + margin-right: 15px; + background-color: #D9D9D9; + align-items: center; + padding: 4px; +} +isLoggedIn + +.webLink{ + display: flex; + font-size: 25px; + margin-top: 15px; + margin-left: 15px; + margin-right: 15px; + background-color: #D9D9D9; + height: 40px; + align-items: center; +} + +.spotPic img{ + width: 390px; + height: 262px; + object-fit: cover; +} + +.spotPic{ + position: relative; +} + +.likePic{ + position: absolute; + top: 10px; + right: 10px; + width: 35px; +} + +.nameSpot{ + position: absolute; + top: 0px; + left: 10px; + font-size: 25px; +} + +.addressSpot { + display: flex; + align-items: center; + background-color: #D9D9D9; + margin-left: 5px; + margin-right: 5px; + height: 50px; + font-size: 30px; +} + +.descriptionSpot { + display: flex; + align-items: center; + background-color: #D9D9D9; + margin-left: 5px; + margin-right: 5px; + font-size: 15px; +} + +.aboutSpot{ + font-size: 30px; + margin-bottom: 0px; + margin-top: 5px; + margin-left: 5px; +} + +.webLinkSpot { + display: flex; + align-items: center; + background-color: #D9D9D9; + margin-left: 5px; + margin-right: 5px; + height: 50px; + font-size: 30px; +} + + +#spot{ + display: flex; + width: 100vw; +} + +#list_spots{ + display: flex; + flex-direction: column; + align-items: center; + width: 100vw; + height: 100vh; +} + +#description{ + display: flex; + margin-left: 9px; + margin-bottom: 20px; + margin-top: 16px; +} + + + +.scroll-container { + display: block; + margin: 0 auto; + text-align: center; + width: 100vw; +} + +.scroll-container { + width: 100vw; + + overflow-y: hidden; + overflow-x: scroll; + scroll-behavior: smooth; + display: flex; +} +.scroll-page { + display: flex; + flex-wrap: no-wrap; + /* align-items: center; + justify-content: center; */ + height: 100%; + font-size: 5em; +} + +#pages{ + font-size: 14px; + +} + +h3{ + display: flex; + text-align: center; + +} +h2{ + color: black; + font-size: 16px; + text-decoration: underline; +} +h8{ + width: 200px; + margin: 30px; + font-size: 18; +} + +#spotDetails{ + font-size: 19px; + margin: 16px; +} + +#spot-details{ + display: flex; + flex-direction: column; + align-items: center; + width: 100vw; + height: 100vh; +} + + +#map{ + width: 100vw; + height: 100vh; +} + +.marker{ + width: 20px; + height: 20px; + border-radius: 50%; + background-color: red; +} + +#button_2{ +background-color: #5EBE90; +margin-bottom: 30px; +margin-top: 20px; +font-size: 17px; +padding: 8px; +border-bottom-right-radius: 12px; +} + +#description-comment{ + display: flex; + align-content: center; +} + +#form-comment{ + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + height: 100%; +} + + +p3{ + margin: 20px; + margin-left: 211px; +} +p1{ + display: flex; + background-color: rgb(133, 201, 240); + border-radius: 5px; + font-size: 20px; + padding: 11px; + margin: 28px; + +} + +#button_3{ + background-color: #5EBE90; + width: fit-content; + align-content: center; + margin: 20px; + font-size: 22px; + padding: 8px; + border-bottom-right-radius: 20px; + margin: -5px; + align-items: flex-end; + margin-right: 236px; +} + +h5{ + font-size: 16px; +} + +h7 { + font-size: 18px; + margin-right: 4px; +} + +#logout_button{ + font-size: 24px; + margin-top: 6px; +} + diff --git a/Project/routes/auth.routes.js b/Project/routes/auth.routes.js index 474cb56..af7b5f6 100644 --- a/Project/routes/auth.routes.js +++ b/Project/routes/auth.routes.js @@ -1,6 +1,6 @@ const express = require("express"); const router = express.Router(); - +const fileUploader = require('../config/cloudinary.config'); // ℹ️ Handles password encryption const bcrypt = require("bcrypt"); const mongoose = require("mongoose"); @@ -15,20 +15,29 @@ const User = require("../models/User.model"); const isLoggedOut = require("../middleware/isLoggedOut"); const isLoggedIn = require("../middleware/isLoggedIn"); +// Require the Spot & UserSpot model in order to interact with the database +const Spot = require("../models/Spot.model") +const UserSpot = require("../models/UserSpot.model") +const Comment = require("../models/Comment.model") +const CommentLike = require("../models/CommentLike.model") + + // GET /auth/signup router.get("/signup", isLoggedOut, (req, res) => { - res.render("auth/signup"); + res.render("auth/signup", {layout:false}); }); // POST /auth/signup router.post("/signup", isLoggedOut, (req, res) => { - const { username, email, password } = req.body; + const {fullName, username, email, password } = req.body; + console.log(req.body) // Check that username, email, and password are provided if (username === "" || email === "" || password === "") { res.status(400).render("auth/signup", { errorMessage: "All fields are mandatory. Please provide your username, email and password.", + layout: false }); return; @@ -37,23 +46,22 @@ router.post("/signup", isLoggedOut, (req, res) => { if (password.length < 6) { res.status(400).render("auth/signup", { errorMessage: "Your password needs to be at least 6 characters long.", + layout: false }); return; } - // ! This regular expression checks password for special characters and minimum length - /* const regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/; if (!regex.test(password)) { res .status(400) .render("auth/signup", { - errorMessage: "Password needs to have at least 6 chars and must contain at least one number, one lowercase and one uppercase letter." - }); + errorMessage: "Password needs to have at least 6 chars and must contain at least one number, one lowercase and one uppercase letter.", + layout: false}); return; } - */ + // Create a new user - start by hashing the password bcrypt @@ -61,28 +69,31 @@ router.post("/signup", isLoggedOut, (req, res) => { .then((salt) => bcrypt.hash(password, salt)) .then((hashedPassword) => { // Create a user and save it in the database - return User.create({ username, email, password: hashedPassword }); + return User.create({ fullName, username, email, password: hashedPassword }); }) .then((user) => { - res.redirect("/auth/login"); + res.redirect("/profile"); }) + .catch((error) => { if (error instanceof mongoose.Error.ValidationError) { - res.status(500).render("auth/signup", { errorMessage: error.message }); + res.status(500).render("auth/signup", { errorMessage: error.message, layout: false }); } else if (error.code === 11000) { res.status(500).render("auth/signup", { errorMessage: "Username and email need to be unique. Provide a valid username or email.", + layout: false }); } else { next(error); } }); + }); // GET /auth/login router.get("/login", isLoggedOut, (req, res) => { - res.render("auth/login"); + res.render("auth/login", {layout:false}); }); // POST /auth/login @@ -94,6 +105,7 @@ router.post("/login", isLoggedOut, (req, res, next) => { res.status(400).render("auth/login", { errorMessage: "All fields are mandatory. Please provide username, email and password.", + layout: false }); return; @@ -104,6 +116,7 @@ router.post("/login", isLoggedOut, (req, res, next) => { if (password.length < 6) { return res.status(400).render("auth/login", { errorMessage: "Your password needs to be at least 6 characters long.", + layout: false }); } @@ -114,7 +127,7 @@ router.post("/login", isLoggedOut, (req, res, next) => { if (!user) { res .status(400) - .render("auth/login", { errorMessage: "Wrong credentials." }); + .render("auth/login", { errorMessage: "Wrong credentials.", layout: false }); return; } @@ -125,7 +138,7 @@ router.post("/login", isLoggedOut, (req, res, next) => { if (!isSamePassword) { res .status(400) - .render("auth/login", { errorMessage: "Wrong credentials." }); + .render("auth/login", { errorMessage: "Wrong credentials.", layout: false }); return; } @@ -134,7 +147,7 @@ router.post("/login", isLoggedOut, (req, res, next) => { // Remove the password field delete req.session.currentUser.password; - res.redirect("/"); + res.redirect("/map"); }) .catch((err) => next(err)); // In this case, we send error handling to the error handling middleware. }) @@ -142,10 +155,10 @@ router.post("/login", isLoggedOut, (req, res, next) => { }); // GET /auth/logout -router.get("/logout", isLoggedIn, (req, res) => { +router.post("/logout", isLoggedIn, (req, res) => { req.session.destroy((err) => { if (err) { - res.status(500).render("auth/logout", { errorMessage: err.message }); + res.status(500).redirect("/") return; } @@ -153,4 +166,140 @@ router.get("/logout", isLoggedIn, (req, res) => { }); }); + + +//GET /users/user-profile +router.get("/profile", isLoggedIn, (req, res) => { + res.render("users/user-profile", req.session.currentUser ); + +}); + + +//GET /spots/addSpot +router.get("/addSpot", (req, res) => { + res.render("spots/addSpot"); +}); + +router.post("/addSpot", fileUploader.array('images'), async (req, res) => { + const {name, coordinates, address, description, province, rating, webpage, BBQ, Toilet, Electricity, Trash_can, Drinking_water, Shower} = req.body; + console.log(req) + const images = {imagesUrl: []} + if (req.file) { + images.imagesUrl.push(req.file.path) + } else if (req.files) { + req.files.forEach((file) =>{ + images.imagesUrl.push(file.path) + }) + } + + const amenities = {} + if (BBQ) {amenities.BBQ = true} + if (Toilet) {amenities.Toilet = true} + if (Electricity) {amenities.Electricity = true} + if (Trash_can) {amenities.Trash_can = true} + if (Drinking_water) {amenities.Drinking_water = true} + if (Shower) {amenities.Shower = true} + + try{ + const newSpot = await Spot.create({name, coordinates, address, images, description, province, amenities, rating, webpage }) + console.log("Spot Created") + res.redirect("/map") + } catch(err){ + console.log(err) + } +}) + +router.get("/savedSpots" ,async (req, res) => { + console.log("hola") +// console.log(req.session.currentUser) + const UserSaved = await User.findById(req.session.currentUser._id).populate("UserSpot").populate({ + path: "UserSpot", + populate: { + path: "spot", + model: "Spot", + populate: { + path: "comments", + model: "Comment", + populate: { + path: "author", + model: "User", + populate: { + path: "commentLike", + model: "CommentLike" + } + } + } + } + }) + + // console.log(UserSaved.UserSpot[0].spot.comments[0].author) + // const result = await UserSpot.findById(UserSaved.UserSpot._id).populate("spot") + //console.log(UserSaved) + // console.log(UserSaved.UserSpot[0].spot.images) + + res.render("spots/list-saved-spots", UserSaved); +}); + +//GET /spots/spot +router.get("/spot/:spotId", async (req, res) => { + const spotId = req.params.spotId + try { + const dbSpot = await Spot.findById(spotId).populate("comments").populate({ + path: "comments", + populate: { + path: "author", + model: "User", + } + }) + + console.log(dbSpot) + res.render("spots/spot-details", dbSpot) + }catch (err) { + console.log(err) + } +}) + +//GET +router.get("/map", isLoggedIn, async (req, res) => { + try{ + const spotsDb = await Spot.find() + const mapCenter = [-3.703339, 40.416729] + const mapZoom = 5 + res.render("map", {layout:false, user: req.session.currentUser, spotsDb, mapCenter, mapZoom}); + }catch(err){ + console.log(err) + } +}); + + + +router.get("/addComment/:spotID", (req, res) => { + console.log(req.body) + + res.render("comments/addComment", {spotID: req.params.spotID}); + +}); + +router.post("/publishComment/:spotID", async (req, res) => { + + try{ + const authorSaved = await User.findById(req.session.currentUser._id) + const spotSaved = await Spot.findById(req.params.spotID) + const comment = { + spot: spotSaved, + author: authorSaved, + description: req.body.description + } + + const newComment = await Comment.create(comment) + await Spot.findByIdAndUpdate(req.params.spotID, { $push: { comments: newComment._id } }); + await User.findByIdAndUpdate(req.session.currentUser._id, { $push: { comments: newComment._id } }); + + console.log("Comment Created") + res.redirect("/map") + } catch(err){ + console.log(err) + } + }) + module.exports = router; diff --git a/Project/routes/index.routes.js b/Project/routes/index.routes.js index f538ffe..34435e4 100644 --- a/Project/routes/index.routes.js +++ b/Project/routes/index.routes.js @@ -1,9 +1,18 @@ const express = require('express'); +const isLoggedOut = require('../middleware/isLoggedOut'); const router = express.Router(); +const Spot = require("../models/Spot.model") /* GET home page */ -router.get("/", (req, res, next) => { - res.render("index"); +router.get("/", async (req, res, next) => { + try{ + const spotsDb = await Spot.find() + const mapCenter = [-3.703339, 40.416729] + const mapZoom = 5 + res.render("index", {layout:false, user: req.session.currentUser, spotsDb, mapCenter, mapZoom}); + }catch(err){ + console.log(err) + } }); module.exports = router; diff --git a/Project/seeds/spots.seed.js b/Project/seeds/spots.seed.js new file mode 100644 index 0000000..97b0f1e --- /dev/null +++ b/Project/seeds/spots.seed.js @@ -0,0 +1,226 @@ +// Iteration #1 +const mongoose = require("mongoose") +const Spot = require("../models/Spot.model") +const Comment = require("../models/Comment.model") +const User = require("../models/User.model") +const CommentLike = require("../models/CommentLike.model") +const UserSpot = require("../models/UserSpot.model") +const bcrypt = require("bcrypt"); + +const MONGO_URI = "mongodb://localhost:27017/Project_park4night"; + + + + +const createObjects = async function() { + try { + const connect = await mongoose.connect(MONGO_URI) + console.log(`Connected to database: ${connect.connections[0].name}`) + + const deleteAll = await CommentLike.deleteMany() + const deleteAll1 = await Comment.deleteMany() + const deleteAll2 = await User.deleteMany() + const deleteAll3 = await Spot.deleteMany() + const deleteAll4 = await UserSpot.deleteMany() + + console.log("Db clean") + + + const users = [ + { + fullName: "Laura Cruzado", + username: "Lcruzado92", + email: "laura.bcn_upc@gmail.com", + password:"$2b$10$ZZSbVKPa7S8YnIpEsF1BFOlCkHZt9CL3k81RZCJxtYtB7CH5UcO92", + // savedSpots: [dbSpots[1]._id], + }, + { + fullName: "Jessica Cobo", + username: "Jess_CF", + email: "jess.cobo@gmail.com", + password:"$2b$10$ZZSbVKPa7S8YnIpEsF1BFOlCkHZt9CL3k81RZCJxtYtB7CH5UcO92", + // savedSpots: [dbSpots[0]._id,dbSpots[3]._id] + }, + { + fullName: "Pablo Fernández", + username: "Ferna92", + email: "pablito.ferna_92@gmail.com", + password:"$2b$10$ZZSbVKPa7S8YnIpEsF1BFOlCkHZt9CL3k81RZCJxtYtB7CH5UcO92" + } + ] + const dbUser = await User.create(users) + + const comments = [ + { + description: "Great spot! Really quiet. You can buy food in the village and you will find electricity there as well.", + author: dbUser[0]._id, + }, + { + description: "It was a bit crowded when we arrived (evening), but we could find space finally. There are restaurants near the spot, which is great!", + author: dbUser[1]._id, + + }, + { + description: "A bit noisy in the mornings when everyone goes to the beach. Though, it is worth it. Bolonia beach is just great", + author: dbUser[0]._id, + }, + { + description: "Everything perfect! I would strongly recommend this place.", + author: dbUser[1]._id, + + }, + { + description: "Amenities really close to the parking. We appreciated the picnic area. There is also a playground", + author: dbUser[0]._id, + + }, + { + description: "A bit disappointing. The place was really crowded", + author: dbUser[2]._id, + } + + ] + const dbComment = await Comment.create(comments) + + dbComment.forEach(async (comment) => { + + const userUpdate = await User.findByIdAndUpdate(comment.author,{ $push: { comments: comment._id } } ) + }) + + + dbComment.forEach(async (comment) => { + const randNum = Math.floor(Math.random() * 3) + userRand = dbUser[randNum] + + const commentLikecr = await CommentLike.create({user: userRand._id, comment: comment._id}) + const commentUpdated = await Comment.findByIdAndUpdate(comment._id,{ $push: { commentLike: commentLikecr._id } } ) + + + }) + + const allLikes = await CommentLike.find() + + allLikes.forEach(async (commentLike) => { + + const userUpdate = await User.findByIdAndUpdate(commentLike.user,{ $push: { commentLike: commentLike._id } } ) + }) + + + const spots = [ + { + name: "Molló, Passeig del Vallespir", + coordinates: "42.348099, 2.405770", + address: "Passeig del Vallespir, 17868 Molló Spain", + province: "Girona", + rating: 7, + amenities: { + Trash_can: true, + + }, + images: { + imagesUrl: ["https://res.cloudinary.com/dfajfbnkr/image/upload/v1667818518/AIRBnvan/Mollo_spot3_l7kims.jpg", "https://res.cloudinary.com/dfajfbnkr/image/upload/v1667818518/AIRBnvan/Mollo_spot2_aoziwr.jpg", "https://res.cloudinary.com/dfajfbnkr/image/upload/v1667818518/AIRBnvan/Mollo_spot1_fwesbu.jpg"] + }, + description: "Free parking for vans in a quiet zone. Perfect spot for hiking! You can find drinking water close to the parking (in the village main square)", + Number_parking_spots: 20, + comments: [dbComment[0]._id, dbComment[3]._id] + }, + { + name: "Tarifa, Pista Vereda de la Reginosa", + coordinates: "6.087044, -5.769359", + address: "Pista Vereda de la Reginosa, 11391 Tarifa Spain", + province: "Cádiz", + rating: 8, + amenities: { + Trash_can: true, + Shower: true, + Toilet: false, + }, + images: { + imagesUrl: ["https://res.cloudinary.com/dfajfbnkr/image/upload/v1667819217/AIRBnvan/tarifa_spot1_dqubzu.jpg","https://res.cloudinary.com/dfajfbnkr/image/upload/v1667819112/AIRBnvan/tarifa_spot2_ydwvkl.jpg"], + }, + description: "Free parking for vans next to Bolonia beach.", + Number_parking_spots: 20, + comments: [dbComment[1]._id, dbComment[2]._id] + }, + { + name: "Gijón, Camin de Peñarrubia", + coordinates: "43.549198, -5.623890", + address: "Camin de Peñarrubia, 33203 Gijón Spain", + province: "Asturias", + rating: 6, + amenities: { + Trash_can: true, + }, + images: { + imagesUrl: ["https://res.cloudinary.com/dfajfbnkr/image/upload/v1667820422/AIRBnvan/guijon_spot1_erlhmg.jpg","https://res.cloudinary.com/dfajfbnkr/image/upload/v1667820422/AIRBnvan/guijon_spot2_wrdqm8.jpg"], + }, + description: "Parking close to Penurubbia beach. No drinking water, no toilets and no showers, but beautiful views of the seacost!", + Number_parking_spots: 50, + comments: [dbComment[5]._id] + }, + { + name: "Es Mercadal parking spot", + coordinates: "40.032512, 4.192128", + address: "34 Urbanització Punta Grossa, Polígon II, 07740 Es Mercadal", + province: "Menorca", + rating: 7, + images: { + imagesUrl: ["https://res.cloudinary.com/dfajfbnkr/image/upload/v1667821338/AIRBnvan/menorca_spot3_dcff3w.jpg","https://res.cloudinary.com/dfajfbnkr/image/upload/v1667821338/AIRBnvan/menorca_spot2_ncjy5m.jpg"], + }, + description: "No amenities. Cliffs with amazing sea views. Easy access accross an unpaved road", + comments: [dbComment[3]._id] + }, + { + name: "Bentabarri Kalea parking", + coordinates: "42.957370, -2.591214", + address: "1 Bentabarri Kalea, 01520 Spain", + province: "Bizcaia", + rating: 9, + images: { + imagesUrl: ["https://res.cloudinary.com/dfajfbnkr/image/upload/v1667821041/AIRBnvan/euskadi_spot1_lb0wun.jpg","https://res.cloudinary.com/dfajfbnkr/image/upload/v1667821041/AIRBnvan/euskadi_spot2_d58m6c.jpg","https://res.cloudinary.com/dfajfbnkr/image/upload/v1667821041/AIRBnvan/euskadi_spot3_g1ncz8.jpg"], + }, + description: "Perfect spot! A lot of amenities next to the parking. The best part was the picnic area.", + amenities: { + Trash_can: true, + Shower: true, + Drinking_water: true, + Toilet: true, + }, + Number_parking_spots: 25, + comments: [dbComment[4]._id] + } + ]; + const dbSpots = await Spot.create(spots) + + + const userSpot = await UserSpot.create({user: dbUser[0]._id, spot: dbSpots[0]._id }) + const userSpot2 = await UserSpot.create({user: dbUser[1]._id, spot: dbSpots[1]._id }) + const userSpot3 = await UserSpot.create({user: dbUser[1]._id, spot: dbSpots[3]._id }) + const userSpot4 = await UserSpot.create({user: dbUser[2]._id, spot: dbSpots[2]._id}) + + const userUpdate1 = await User.findByIdAndUpdate(dbUser[0]._id,{ $push: { UserSpot: userSpot._id } } ) + const userUpdate2 = await User.findByIdAndUpdate(dbUser[1]._id,{ $push: { UserSpot: userSpot2._id } } ) + const userUpdate3 = await User.findByIdAndUpdate(dbUser[1]._id,{ $push: { UserSpot: userSpot3._id } } ) + const userUpdate4 = await User.findByIdAndUpdate(dbUser[2]._id,{ $push: { UserSpot: userSpot4._id } } ) + + const spotUpdate1 = await Spot.findByIdAndUpdate(dbSpots[0]._id,{ $push: { UserSpot: userSpot._id } } ) + const spotUpdate2 = await Spot.findByIdAndUpdate(dbSpots[1]._id,{ $push: { UserSpot: userSpot2._id } } ) + const spotUpdate3 = await Spot.findByIdAndUpdate(dbSpots[2]._id,{ $push: { UserSpot: userSpot4._id } } ) + const spotUpdate4 = await Spot.findByIdAndUpdate(dbSpots[3]._id,{ $push: { UserSpot: userSpot3._id } } ) + + const dbClose = await mongoose.connection.close() + console.log("Connection closed") + + }catch (err) { + console.log(`Error creating the seeds: ${err}`) + } +} + +createObjects() + + + + + + + diff --git a/Project/views/auth/login.hbs b/Project/views/auth/login.hbs index 0d33b08..1f5f3a2 100644 --- a/Project/views/auth/login.hbs +++ b/Project/views/auth/login.hbs @@ -1,10 +1,19 @@ + +
+ + + +