├── README.md ├── backend ├── .env ├── .gitignore ├── app.js ├── controllers │ ├── applicationController.js │ ├── jobController.js │ └── userController.js ├── database │ └── dbConnection.js ├── middlewares │ ├── auth.js │ ├── catchAsyncError.js │ └── error.js ├── models │ ├── applicationSchema.js │ ├── jobSchema.js │ └── userSchema.js ├── package-lock.json ├── package.json ├── routes │ ├── applicationRoutes.js │ ├── jobRoutes.js │ └── userRoutes.js ├── server.js └── utils │ └── jwtToken.js └── frontend ├── .eslintrc.cjs ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── public ├── CVs │ ├── cv1.jpg │ ├── cv2.jpg │ ├── cv3.jpg │ ├── cv4.jpg │ └── cv5.jpg ├── JobZee-logos__transparent.png ├── JobZee-logos__white.png ├── JobZeelogo.png ├── careerconnect-black.png ├── careerconnect-transparent.png ├── careerconnect-white.png ├── favicon.png ├── heroS.jpg ├── login.png ├── notfound.png ├── register.png └── vite.svg ├── src ├── App.css ├── App.jsx ├── components │ ├── Application │ │ ├── Application.jsx │ │ ├── MyApplications.jsx │ │ └── ResumeModal.jsx │ ├── Auth │ │ ├── Login.jsx │ │ └── Register.jsx │ ├── Home │ │ ├── HeroSection.jsx │ │ ├── Home.jsx │ │ ├── HowItWorks.jsx │ │ ├── PopularCategories.jsx │ │ └── PopularCompanies.jsx │ ├── Job │ │ ├── JobDetails.jsx │ │ ├── Jobs.jsx │ │ ├── MyJobs.jsx │ │ └── PostJob.jsx │ ├── Layout │ │ ├── Footer.jsx │ │ └── Navbar.jsx │ └── NotFound │ │ └── NotFound.jsx └── main.jsx └── vite.config.js /README.md: -------------------------------------------------------------------------------- 1 | # Job Portal App with MERN Stack 2 | 3 | A comprehensive job portal application built using the MERN (MongoDB, Express.js, React.js, Node.js) stack. This application allows users to browse job listings, apply for jobs, and manage their applications seamlessly. 4 | 5 | ## Features 6 | 7 | - **User Authentication:** Secure authentication using JWT (JSON Web Tokens) for both job seekers and employers. 8 | - **Job Listings:** Browse through a wide range of job listings fetched from MongoDB. 9 | - **Application Management:** Job seekers can manage their job applications, and employers can view and manage received applications. 10 | - **Responsive Design:** Ensures a seamless experience across all devices. 11 | 12 | ## Technologies Used 13 | 14 | - **Frontend:** React.js, React Router, Bootstrap 15 | - **Backend:** Node.js, Express.js, MongoDB 16 | - **Authentication:** JWT (JSON Web Tokens), Bcrypt (for password hash) 17 | - **Image Upload:** Cloudinary for storing and managing uploaded images 18 | - **Deployment:** Vercel (frontend), Render(backend), MongoDB Atlas (database) 19 | 20 | ## Getting Started 21 | 22 | To get a local copy up and running follow these simple steps. 23 | 24 | ### Prerequisites 25 | 26 | - Node.js installed on your machine with latest version or v22.2.0 above 27 | - MongoDB Atlas account (or local MongoDB server) 28 | - Cloudinary account for image storage 29 | 30 | ### Installation 31 | 32 | 1. Clone the repo: 33 | ```sh 34 | git clone https://github.com/exclusiveabhi/react-job-portal.git 35 | ``` 36 | 2. Install NPM packages: 37 | 38 | ```sh 39 | cd react-job-portal 40 | cd backend 41 | npm install 42 | cd.. 43 | cd frontend 44 | npm install 45 | ``` 46 | 47 | 3. ## If you don't want to change the`.env` credentials skip step 4 and move to step 5. 48 | 49 | 4. Set up environment variables: 50 | 51 | - Create a `config.env` file after creating a `config folder` in the backend directory, containing the following variables: 52 | 53 | ```env 54 | PORT= 55 | CLOUDINARY_API_KEY= 56 | CLOUDINARY_API_SECRET= 57 | CLOUDINARY_CLOUD_NAME= 58 | FRONTEND_URL= 59 | DB_URL= 60 | JWT_SECRET_KEY= 61 | JWT_EXPIRE= 62 | COOKIE_EXPIRE= 63 | ``` 64 | 65 | Replace each value with your specific configuration details. 66 | 67 | 5. Run the application backend (make sure you are in `/backend` directory) : 68 | 69 | ```sh 70 | node server.js 71 | ``` 72 | 73 | 6. Run the application frontend (make sure you are in `/frontend` directory) : 74 | ```sh 75 | npm run dev 76 | ``` 77 | 7. Open your browser and navigate to `http://localhost:5173` to view the app. 78 | 79 | ## Contributing 80 | 81 | Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 82 | 83 | 1. Fork the Project 84 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 85 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 86 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 87 | 5. Open a Pull Request (`we will merge within 24 hour`) 88 | 89 | ## Please give a star ⭐ to the repository if you like it. 90 | 91 | ## Contact 92 | 93 | Abhishek Rajput - [GitHub](https://github.com/exclusiveabhi) 94 | 95 | Project Link: [https://github.com/exclusiveabhi/react-job-portal.git](https://github.com/exclusiveabhi/react-job-portal.git) 96 | -------------------------------------------------------------------------------- /backend/.env: -------------------------------------------------------------------------------- 1 | PORT=4000 2 | CLOUDINARY_API_KEY=819224586478434 3 | CLOUDINARY_API_SECRET=yr_TbbT_JDG2Xfu4KcrrcykeJvA 4 | CLOUDINARY_CLOUD_NAME=dtgsdprcl 5 | FRONTEND_URL=http://localhost:5173 6 | DB_URL=mongodb+srv://exclusiveabhi:maCdjaRpoWvGczS5@cluster0.1vxqfqv.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0 7 | JWT_SECRET_KEY=fgjfgsudgfudnhfousidfnewuikfmlewf 8 | JWT_EXPIRE=7d 9 | COOKIE_EXPIRE=7 10 | NODE_ENV=development -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /backend/app.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import dbConnection from "./database/dbConnection.js"; 3 | import jobRouter from "./routes/jobRoutes.js"; 4 | import userRouter from "./routes/userRoutes.js"; 5 | import applicationRouter from "./routes/applicationRoutes.js"; 6 | import { config } from "dotenv"; 7 | import cors from "cors"; 8 | import { errorMiddleware } from "./middlewares/error.js"; 9 | import cookieParser from "cookie-parser"; 10 | import fileUpload from "express-fileupload"; 11 | 12 | const app = express(); 13 | config({ path: "./config/config.env" }); 14 | 15 | app.use( 16 | cors({ 17 | origin: [process.env.FRONTEND_URL], 18 | method: ["GET", "POST", "DELETE", "PUT"], 19 | credentials: true, 20 | }) 21 | ); 22 | 23 | app.use(cookieParser()); 24 | app.use(express.json()); 25 | app.use(express.urlencoded({ extended: true })); 26 | 27 | app.use( 28 | fileUpload({ 29 | useTempFiles: true, 30 | tempFileDir: "/tmp/", 31 | }) 32 | ); 33 | app.use("/api/v1/user", userRouter); 34 | app.use("/api/v1/job", jobRouter); 35 | app.use("/api/v1/application", applicationRouter); 36 | dbConnection(); 37 | 38 | app.use(errorMiddleware); 39 | export default app; 40 | -------------------------------------------------------------------------------- /backend/controllers/applicationController.js: -------------------------------------------------------------------------------- 1 | import { catchAsyncErrors } from "../middlewares/catchAsyncError.js"; 2 | import ErrorHandler from "../middlewares/error.js"; 3 | import { Application } from "../models/applicationSchema.js"; 4 | import { Job } from "../models/jobSchema.js"; 5 | import cloudinary from "cloudinary"; 6 | 7 | export const postApplication = catchAsyncErrors(async (req, res, next) => { 8 | const { role } = req.user; 9 | if (role === "Employer") { 10 | return next( 11 | new ErrorHandler("Employer not allowed to access this resource.", 400) 12 | ); 13 | } 14 | 15 | if (!req.files || Object.keys(req.files).length === 0) { 16 | return next(new ErrorHandler("Resume File Required!", 400)); 17 | } 18 | 19 | const { resume } = req.files; 20 | const allowedFormats = ["image/png", "image/jpeg", "image/webp"]; 21 | if (!allowedFormats.includes(resume.mimetype)) { 22 | return next( 23 | new ErrorHandler("Invalid file type. Please upload a PNG, JPEG, or WEBP file.", 400) 24 | ); 25 | } 26 | 27 | try { 28 | const cloudinaryResponse = await cloudinary.uploader.upload( 29 | resume.tempFilePath 30 | ); 31 | 32 | if (!cloudinaryResponse || cloudinaryResponse.error) { 33 | console.error( 34 | "Cloudinary Error:", 35 | cloudinaryResponse.error || "Unknown Cloudinary error" 36 | ); 37 | return next(new ErrorHandler("Failed to upload Resume to Cloudinary", 500)); 38 | } 39 | 40 | const { name, email, coverLetter, phone, address, jobId } = req.body; 41 | const applicantID = { 42 | user: req.user._id, 43 | role: "Job Seeker", 44 | }; 45 | 46 | if (!jobId) { 47 | return next(new ErrorHandler("Job not found!", 404)); 48 | } 49 | 50 | const jobDetails = await Job.findById(jobId); 51 | if (!jobDetails) { 52 | return next(new ErrorHandler("Job not found!", 404)); 53 | } 54 | 55 | const employerID = { 56 | user: jobDetails.postedBy, 57 | role: "Employer", 58 | }; 59 | 60 | if ( 61 | !name || 62 | !email || 63 | !coverLetter || 64 | !phone || 65 | !address || 66 | !applicantID || 67 | !employerID || 68 | !resume 69 | ) { 70 | return next(new ErrorHandler("Please fill all fields.", 400)); 71 | } 72 | 73 | const application = await Application.create({ 74 | name, 75 | email, 76 | coverLetter, 77 | phone, 78 | address, 79 | applicantID, 80 | employerID, 81 | resume: { 82 | public_id: cloudinaryResponse.public_id, 83 | url: cloudinaryResponse.secure_url, 84 | }, 85 | }); 86 | 87 | res.status(200).json({ 88 | success: true, 89 | message: "Application Submitted!", 90 | application, 91 | }); 92 | } catch (error) { 93 | // Handle Cloudinary specific errors 94 | if (error.message && error.message.includes("api_key")) { 95 | console.error("Cloudinary API key error:", error.message); 96 | return next(new ErrorHandler("File upload service configuration error", 500)); 97 | } 98 | 99 | // Handle any other errors 100 | return next(error); 101 | } 102 | }); 103 | 104 | export const employerGetAllApplications = catchAsyncErrors( 105 | async (req, res, next) => { 106 | const { role } = req.user; 107 | if (role === "Job Seeker") { 108 | return next( 109 | new ErrorHandler("Job Seeker not allowed to access this resource.", 400) 110 | ); 111 | } 112 | const { _id } = req.user; 113 | const applications = await Application.find({ "employerID.user": _id }); 114 | res.status(200).json({ 115 | success: true, 116 | applications, 117 | }); 118 | } 119 | ); 120 | 121 | export const jobseekerGetAllApplications = catchAsyncErrors( 122 | async (req, res, next) => { 123 | const { role } = req.user; 124 | if (role === "Employer") { 125 | return next( 126 | new ErrorHandler("Employer not allowed to access this resource.", 400) 127 | ); 128 | } 129 | const { _id } = req.user; 130 | const applications = await Application.find({ "applicantID.user": _id }); 131 | res.status(200).json({ 132 | success: true, 133 | applications, 134 | }); 135 | } 136 | ); 137 | 138 | export const jobseekerDeleteApplication = catchAsyncErrors( 139 | async (req, res, next) => { 140 | const { role } = req.user; 141 | if (role === "Employer") { 142 | return next( 143 | new ErrorHandler("Employer not allowed to access this resource.", 400) 144 | ); 145 | } 146 | const { id } = req.params; 147 | const application = await Application.findById(id); 148 | if (!application) { 149 | return next(new ErrorHandler("Application not found!", 404)); 150 | } 151 | await application.deleteOne(); 152 | res.status(200).json({ 153 | success: true, 154 | message: "Application Deleted!", 155 | }); 156 | } 157 | ); 158 | -------------------------------------------------------------------------------- /backend/controllers/jobController.js: -------------------------------------------------------------------------------- 1 | import { catchAsyncErrors } from "../middlewares/catchAsyncError.js"; 2 | import { Job } from "../models/jobSchema.js"; 3 | import ErrorHandler from "../middlewares/error.js"; 4 | 5 | export const getAllJobs = catchAsyncErrors(async (req, res, next) => { 6 | const jobs = await Job.find({ expired: false }); 7 | res.status(200).json({ 8 | success: true, 9 | jobs, 10 | }); 11 | }); 12 | 13 | export const postJob = catchAsyncErrors(async (req, res, next) => { 14 | const { role } = req.user; 15 | if (role === "Job Seeker") { 16 | return next( 17 | new ErrorHandler("Job Seeker not allowed to access this resource.", 400) 18 | ); 19 | } 20 | const { 21 | title, 22 | description, 23 | category, 24 | country, 25 | city, 26 | location, 27 | fixedSalary, 28 | salaryFrom, 29 | salaryTo, 30 | } = req.body; 31 | 32 | if (!title || !description || !category || !country || !city || !location) { 33 | return next(new ErrorHandler("Please provide full job details.", 400)); 34 | } 35 | 36 | if ((!salaryFrom || !salaryTo) && !fixedSalary) { 37 | return next( 38 | new ErrorHandler( 39 | "Please either provide fixed salary or ranged salary.", 40 | 400 41 | ) 42 | ); 43 | } 44 | 45 | if (salaryFrom && salaryTo && fixedSalary) { 46 | return next( 47 | new ErrorHandler("Cannot Enter Fixed and Ranged Salary together.", 400) 48 | ); 49 | } 50 | const postedBy = req.user._id; 51 | const job = await Job.create({ 52 | title, 53 | description, 54 | category, 55 | country, 56 | city, 57 | location, 58 | fixedSalary, 59 | salaryFrom, 60 | salaryTo, 61 | postedBy, 62 | }); 63 | res.status(200).json({ 64 | success: true, 65 | message: "Job Posted Successfully!", 66 | job, 67 | }); 68 | }); 69 | 70 | export const getMyJobs = catchAsyncErrors(async (req, res, next) => { 71 | const { role } = req.user; 72 | if (role === "Job Seeker") { 73 | return next( 74 | new ErrorHandler("Job Seeker not allowed to access this resource.", 400) 75 | ); 76 | } 77 | const myJobs = await Job.find({ postedBy: req.user._id }); 78 | res.status(200).json({ 79 | success: true, 80 | myJobs, 81 | }); 82 | }); 83 | 84 | export const updateJob = catchAsyncErrors(async (req, res, next) => { 85 | const { role } = req.user; 86 | if (role === "Job Seeker") { 87 | return next( 88 | new ErrorHandler("Job Seeker not allowed to access this resource.", 400) 89 | ); 90 | } 91 | const { id } = req.params; 92 | let job = await Job.findById(id); 93 | if (!job) { 94 | return next(new ErrorHandler("OOPS! Job not found.", 404)); 95 | } 96 | job = await Job.findByIdAndUpdate(id, req.body, { 97 | new: true, 98 | runValidators: true, 99 | useFindAndModify: false, 100 | }); 101 | res.status(200).json({ 102 | success: true, 103 | message: "Job Updated!", 104 | }); 105 | }); 106 | 107 | export const deleteJob = catchAsyncErrors(async (req, res, next) => { 108 | const { role } = req.user; 109 | if (role === "Job Seeker") { 110 | return next( 111 | new ErrorHandler("Job Seeker not allowed to access this resource.", 400) 112 | ); 113 | } 114 | const { id } = req.params; 115 | const job = await Job.findById(id); 116 | if (!job) { 117 | return next(new ErrorHandler("OOPS! Job not found.", 404)); 118 | } 119 | await job.deleteOne(); 120 | res.status(200).json({ 121 | success: true, 122 | message: "Job Deleted!", 123 | }); 124 | }); 125 | 126 | export const getSingleJob = catchAsyncErrors(async (req, res, next) => { 127 | const { id } = req.params; 128 | try { 129 | const job = await Job.findById(id); 130 | if (!job) { 131 | return next(new ErrorHandler("Job not found.", 404)); 132 | } 133 | res.status(200).json({ 134 | success: true, 135 | job, 136 | }); 137 | } catch (error) { 138 | return next(new ErrorHandler(`Invalid ID / CastError`, 404)); 139 | } 140 | }); 141 | -------------------------------------------------------------------------------- /backend/controllers/userController.js: -------------------------------------------------------------------------------- 1 | import { catchAsyncErrors } from "../middlewares/catchAsyncError.js"; 2 | import { User } from "../models/userSchema.js"; 3 | import ErrorHandler from "../middlewares/error.js"; 4 | import { sendToken } from "../utils/jwtToken.js"; 5 | 6 | export const register = catchAsyncErrors(async (req, res, next) => { 7 | const { name, email, phone, password, role } = req.body; 8 | if (!name || !email || !phone || !password || !role) { 9 | return next(new ErrorHandler("Please fill full form !")); 10 | } 11 | const isEmail = await User.findOne({ email }); 12 | if (isEmail) { 13 | return next(new ErrorHandler("Email already registered !")); 14 | } 15 | const user = await User.create({ 16 | name, 17 | email, 18 | phone, 19 | password, 20 | role, 21 | }); 22 | sendToken(user, 201, res, "User Registered Sucessfully !"); 23 | }); 24 | 25 | export const login = catchAsyncErrors(async (req, res, next) => { 26 | const { email, password, role } = req.body; 27 | if (!email || !password || !role) { 28 | return next(new ErrorHandler("Please provide email ,password and role !")); 29 | } 30 | const user = await User.findOne({ email }).select("+password"); 31 | if (!user) { 32 | return next(new ErrorHandler("Invalid Email Or Password.", 400)); 33 | } 34 | const isPasswordMatched = await user.comparePassword(password); 35 | if (!isPasswordMatched) { 36 | return next(new ErrorHandler("Invalid Email Or Password !", 400)); 37 | } 38 | if (user.role !== role) { 39 | return next( 40 | new ErrorHandler(`User with provided email and ${role} not found !`, 404) 41 | ); 42 | } 43 | sendToken(user, 201, res, "User Logged In Sucessfully !"); 44 | }); 45 | 46 | export const logout = catchAsyncErrors(async (req, res, next) => { 47 | res 48 | .status(201) 49 | .cookie("token", "", { 50 | httpOnly: true, 51 | expires: new Date(Date.now()), 52 | }) 53 | .json({ 54 | success: true, 55 | message: "Logged Out Successfully !", 56 | }); 57 | }); 58 | 59 | 60 | export const getUser = catchAsyncErrors((req, res, next) => { 61 | const user = req.user; 62 | res.status(200).json({ 63 | success: true, 64 | user, 65 | }); 66 | }); -------------------------------------------------------------------------------- /backend/database/dbConnection.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; //just mongoose import! 2 | import dotenv from "dotenv" 3 | dotenv.config() 4 | 5 | //Database connection here! 6 | const dbConnection = ()=>{ 7 | mongoose.connect(process.env.DB_URL,{ 8 | dbName: "Job_Portal" 9 | 10 | }).then(()=>{ //agar connect ho jaye toh! 11 | console.log("MongoDB Connected Sucessfully !") 12 | }).catch((error)=>{ 13 | console.log(`Failed to connect ${error}`) //warna error de do console me! 14 | }) 15 | 16 | } 17 | export default dbConnection; -------------------------------------------------------------------------------- /backend/middlewares/auth.js: -------------------------------------------------------------------------------- 1 | import { User } from "../models/userSchema.js"; 2 | import { catchAsyncErrors } from "./catchAsyncError.js"; 3 | import ErrorHandler from "./error.js"; 4 | import jwt from "jsonwebtoken"; 5 | 6 | export const isAuthenticated = catchAsyncErrors(async (req, res, next) => { 7 | const { token } = req.cookies; 8 | if (!token) { 9 | return next(new ErrorHandler("User Not Authorized", 401)); 10 | } 11 | const decoded = jwt.verify(token, process.env.JWT_SECRET_KEY); 12 | 13 | req.user = await User.findById(decoded.id); 14 | 15 | next(); 16 | }); 17 | -------------------------------------------------------------------------------- /backend/middlewares/catchAsyncError.js: -------------------------------------------------------------------------------- 1 | export const catchAsyncErrors = (theFunction) => { 2 | return (req, res, next) => { 3 | Promise.resolve(theFunction(req, res, next)).catch(next); 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /backend/middlewares/error.js: -------------------------------------------------------------------------------- 1 | class ErrorHandler extends Error { 2 | constructor(message, statusCode) { 3 | super(message); 4 | this.statusCode = statusCode; 5 | } 6 | } 7 | 8 | export const errorMiddleware = (err, req, res, next) => { 9 | if (typeof err === 'string') { 10 | return res.status(500).json({ 11 | success: false, 12 | message: err 13 | }); 14 | } 15 | 16 | let error = { ...err }; 17 | error.message = err.message || "Internal Server Error"; 18 | error.statusCode = err.statusCode || 500; 19 | 20 | if (err.name === "CastError") { 21 | const message = `Resource not found. Invalid ${err.path}`; 22 | error = new ErrorHandler(message, 400); 23 | } 24 | 25 | if (err.code === 11000) { 26 | const message = `Duplicate ${Object.keys(err.keyValue)} Entered`; 27 | error = new ErrorHandler(message, 400); 28 | } 29 | 30 | if (err.name === "JsonWebTokenError") { 31 | const message = `Json Web Token is invalid, Try again please!`; 32 | error = new ErrorHandler(message, 400); 33 | } 34 | 35 | if (err.name === "TokenExpiredError") { 36 | const message = `Json Web Token is expired, Try again please!`; 37 | error = new ErrorHandler(message, 400); 38 | } 39 | 40 | return res.status(error.statusCode).json({ 41 | success: false, 42 | message: error.message, 43 | }); 44 | }; 45 | 46 | export default ErrorHandler; 47 | -------------------------------------------------------------------------------- /backend/models/applicationSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import validator from "validator"; 3 | 4 | const applicationSchema = new mongoose.Schema({ 5 | name: { 6 | type: String, 7 | required: [true, "Please enter your Name!"], 8 | minLength: [3, "Name must contain at least 3 Characters!"], 9 | maxLength: [30, "Name cannot exceed 30 Characters!"], 10 | }, 11 | email: { 12 | type: String, 13 | required: [true, "Please enter your Email!"], 14 | validate: [validator.isEmail, "Please provide a valid Email!"], 15 | }, 16 | coverLetter: { 17 | type: String, 18 | required: [true, "Please provide a cover letter!"], 19 | }, 20 | phone: { 21 | type: Number, 22 | required: [true, "Please enter your Phone Number!"], 23 | }, 24 | address: { 25 | type: String, 26 | required: [true, "Please enter your Address!"], 27 | }, 28 | resume: { 29 | public_id: { 30 | type: String, 31 | required: true, 32 | }, 33 | url: { 34 | type: String, 35 | required: true, 36 | }, 37 | }, 38 | applicantID: { 39 | user: { 40 | type: mongoose.Schema.Types.ObjectId, 41 | ref: "User", 42 | required: true, 43 | }, 44 | role: { 45 | type: String, 46 | enum: ["Job Seeker"], 47 | required: true, 48 | }, 49 | }, 50 | employerID: { 51 | user: { 52 | type: mongoose.Schema.Types.ObjectId, 53 | ref: "User", 54 | required: true, 55 | }, 56 | role: { 57 | type: String, 58 | enum: ["Employer"], 59 | required: true, 60 | }, 61 | }, 62 | }); 63 | 64 | export const Application = mongoose.model("Application", applicationSchema); 65 | -------------------------------------------------------------------------------- /backend/models/jobSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const jobSchema = new mongoose.Schema({ 4 | title: { 5 | type: String, 6 | required: [true, "Please provide a title."], 7 | minLength: [3, "Title must contain at least 3 Characters!"], 8 | maxLength: [30, "Title cannot exceed 30 Characters!"], 9 | }, 10 | description: { 11 | type: String, 12 | required: [true, "Please provide decription."], 13 | minLength: [30, "Description must contain at least 30 Characters!"], 14 | maxLength: [500, "Description cannot exceed 500 Characters!"], 15 | }, 16 | category: { 17 | type: String, 18 | required: [true, "Please provide a category."], 19 | }, 20 | country: { 21 | type: String, 22 | required: [true, "Please provide a country name."], 23 | }, 24 | city: { 25 | type: String, 26 | required: [true, "Please provide a city name."], 27 | }, 28 | location: { 29 | type: String, 30 | required: [true, "Please provide location."], 31 | minLength: [20, "Location must contian at least 20 characters!"], 32 | }, 33 | fixedSalary: { 34 | type: Number, 35 | minLength: [4, "Salary must contain at least 4 digits"], 36 | maxLength: [9, "Salary cannot exceed 9 digits"], 37 | }, 38 | salaryFrom: { 39 | type: Number, 40 | minLength: [4, "Salary must contain at least 4 digits"], 41 | maxLength: [9, "Salary cannot exceed 9 digits"], 42 | }, 43 | salaryTo: { 44 | type: Number, 45 | minLength: [4, "Salary must contain at least 4 digits"], 46 | maxLength: [9, "Salary cannot exceed 9 digits"], 47 | }, 48 | expired: { 49 | type: Boolean, 50 | default: false, 51 | }, 52 | jobPostedOn: { 53 | type: Date, 54 | default: Date.now, 55 | }, 56 | postedBy: { 57 | type: mongoose.Schema.ObjectId, 58 | ref: "User", 59 | required: true, 60 | }, 61 | }); 62 | 63 | export const Job = mongoose.model("Job", jobSchema); 64 | -------------------------------------------------------------------------------- /backend/models/userSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import validator from "validator"; 3 | import bcrypt from "bcrypt"; 4 | import jwt from "jsonwebtoken"; 5 | const userSchema = new mongoose.Schema({ 6 | name: { 7 | type: String, 8 | required: [true, "Please enter your Name!"], 9 | minLength: [3, "Name must contain at least 3 Characters!"], 10 | maxLength: [30, "Name cannot exceed 30 Characters!"], 11 | }, 12 | email: { 13 | type: String, 14 | required: [true, "Please enter your Email!"], 15 | validate: [validator.isEmail, "Please provide a valid Email!"], 16 | }, 17 | phone: { 18 | type: Number, 19 | required: [true, "Please enter your Phone Number!"], 20 | }, 21 | password: { 22 | type: String, 23 | required: [true, "Please provide a Password!"], 24 | minLength: [8, "Password must contain at least 8 characters!"], 25 | maxLength: [32, "Password cannot exceed 32 characters!"], 26 | select: false, 27 | }, 28 | role: { 29 | type: String, 30 | required: [true, "Please select a role"], 31 | enum: ["Job Seeker", "Employer"], 32 | }, 33 | createdAt: { 34 | type: Date, 35 | default: Date.now, 36 | }, 37 | }); 38 | 39 | 40 | //ENCRYPTING THE PASSWORD WHEN THE USER REGISTERS OR MODIFIES HIS PASSWORD 41 | userSchema.pre("save", async function (next) { 42 | if (!this.isModified("password")) { 43 | next(); 44 | } 45 | this.password = await bcrypt.hash(this.password, 10); 46 | }); 47 | 48 | //COMPARING THE USER PASSWORD ENTERED BY USER WITH THE USER SAVED PASSWORD 49 | userSchema.methods.comparePassword = async function (enteredPassword) { 50 | return await bcrypt.compare(enteredPassword, this.password); 51 | }; 52 | 53 | //GENERATING A JWT TOKEN WHEN A USER REGISTERS OR LOGINS, IT DEPENDS ON OUR CODE THAT WHEN DO WE NEED TO GENERATE THE JWT TOKEN WHEN THE USER LOGIN OR REGISTER OR FOR BOTH. 54 | userSchema.methods.getJWTToken = function () { 55 | return jwt.sign({ id: this._id }, process.env.JWT_SECRET_KEY, { 56 | expiresIn: process.env.JWT_EXPIRE, 57 | }); 58 | }; 59 | 60 | export const User = mongoose.model("User", userSchema); 61 | -------------------------------------------------------------------------------- /backend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "backend", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bcrypt": "^5.1.1", 13 | "cloudinary": "^1.41.2", 14 | "cookie-parser": "^1.4.6", 15 | "cors": "^2.8.5", 16 | "dotenv": "^16.3.1", 17 | "express": "^4.18.2", 18 | "express-fileupload": "^1.4.3", 19 | "jsonwebtoken": "^9.0.2", 20 | "mongoose": "^8.0.3", 21 | "validator": "^13.11.0" 22 | }, 23 | "devDependencies": { 24 | "nodemon": "^3.1.7" 25 | } 26 | }, 27 | "node_modules/@mapbox/node-pre-gyp": { 28 | "version": "1.0.11", 29 | "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", 30 | "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", 31 | "dependencies": { 32 | "detect-libc": "^2.0.0", 33 | "https-proxy-agent": "^5.0.0", 34 | "make-dir": "^3.1.0", 35 | "node-fetch": "^2.6.7", 36 | "nopt": "^5.0.0", 37 | "npmlog": "^5.0.1", 38 | "rimraf": "^3.0.2", 39 | "semver": "^7.3.5", 40 | "tar": "^6.1.11" 41 | }, 42 | "bin": { 43 | "node-pre-gyp": "bin/node-pre-gyp" 44 | } 45 | }, 46 | "node_modules/@mongodb-js/saslprep": { 47 | "version": "1.1.1", 48 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", 49 | "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", 50 | "dependencies": { 51 | "sparse-bitfield": "^3.0.3" 52 | } 53 | }, 54 | "node_modules/@types/node": { 55 | "version": "20.10.6", 56 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz", 57 | "integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==", 58 | "dependencies": { 59 | "undici-types": "~5.26.4" 60 | } 61 | }, 62 | "node_modules/@types/webidl-conversions": { 63 | "version": "7.0.3", 64 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 65 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 66 | }, 67 | "node_modules/@types/whatwg-url": { 68 | "version": "8.2.2", 69 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", 70 | "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", 71 | "dependencies": { 72 | "@types/node": "*", 73 | "@types/webidl-conversions": "*" 74 | } 75 | }, 76 | "node_modules/abbrev": { 77 | "version": "1.1.1", 78 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 79 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 80 | }, 81 | "node_modules/accepts": { 82 | "version": "1.3.8", 83 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 84 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 85 | "dependencies": { 86 | "mime-types": "~2.1.34", 87 | "negotiator": "0.6.3" 88 | }, 89 | "engines": { 90 | "node": ">= 0.6" 91 | } 92 | }, 93 | "node_modules/agent-base": { 94 | "version": "6.0.2", 95 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", 96 | "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", 97 | "dependencies": { 98 | "debug": "4" 99 | }, 100 | "engines": { 101 | "node": ">= 6.0.0" 102 | } 103 | }, 104 | "node_modules/agent-base/node_modules/debug": { 105 | "version": "4.3.4", 106 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 107 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 108 | "dependencies": { 109 | "ms": "2.1.2" 110 | }, 111 | "engines": { 112 | "node": ">=6.0" 113 | }, 114 | "peerDependenciesMeta": { 115 | "supports-color": { 116 | "optional": true 117 | } 118 | } 119 | }, 120 | "node_modules/agent-base/node_modules/ms": { 121 | "version": "2.1.2", 122 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 123 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 124 | }, 125 | "node_modules/ansi-regex": { 126 | "version": "5.0.1", 127 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 128 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 129 | "engines": { 130 | "node": ">=8" 131 | } 132 | }, 133 | "node_modules/anymatch": { 134 | "version": "3.1.3", 135 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 136 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 137 | "dev": true, 138 | "license": "ISC", 139 | "dependencies": { 140 | "normalize-path": "^3.0.0", 141 | "picomatch": "^2.0.4" 142 | }, 143 | "engines": { 144 | "node": ">= 8" 145 | } 146 | }, 147 | "node_modules/aproba": { 148 | "version": "2.0.0", 149 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", 150 | "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" 151 | }, 152 | "node_modules/are-we-there-yet": { 153 | "version": "2.0.0", 154 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", 155 | "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", 156 | "dependencies": { 157 | "delegates": "^1.0.0", 158 | "readable-stream": "^3.6.0" 159 | }, 160 | "engines": { 161 | "node": ">=10" 162 | } 163 | }, 164 | "node_modules/array-flatten": { 165 | "version": "1.1.1", 166 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 167 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 168 | }, 169 | "node_modules/balanced-match": { 170 | "version": "1.0.2", 171 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 172 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 173 | }, 174 | "node_modules/bcrypt": { 175 | "version": "5.1.1", 176 | "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", 177 | "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", 178 | "hasInstallScript": true, 179 | "dependencies": { 180 | "@mapbox/node-pre-gyp": "^1.0.11", 181 | "node-addon-api": "^5.0.0" 182 | }, 183 | "engines": { 184 | "node": ">= 10.0.0" 185 | } 186 | }, 187 | "node_modules/binary-extensions": { 188 | "version": "2.3.0", 189 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 190 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 191 | "dev": true, 192 | "license": "MIT", 193 | "engines": { 194 | "node": ">=8" 195 | }, 196 | "funding": { 197 | "url": "https://github.com/sponsors/sindresorhus" 198 | } 199 | }, 200 | "node_modules/body-parser": { 201 | "version": "1.20.1", 202 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 203 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 204 | "dependencies": { 205 | "bytes": "3.1.2", 206 | "content-type": "~1.0.4", 207 | "debug": "2.6.9", 208 | "depd": "2.0.0", 209 | "destroy": "1.2.0", 210 | "http-errors": "2.0.0", 211 | "iconv-lite": "0.4.24", 212 | "on-finished": "2.4.1", 213 | "qs": "6.11.0", 214 | "raw-body": "2.5.1", 215 | "type-is": "~1.6.18", 216 | "unpipe": "1.0.0" 217 | }, 218 | "engines": { 219 | "node": ">= 0.8", 220 | "npm": "1.2.8000 || >= 1.4.16" 221 | } 222 | }, 223 | "node_modules/brace-expansion": { 224 | "version": "1.1.11", 225 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 226 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 227 | "dependencies": { 228 | "balanced-match": "^1.0.0", 229 | "concat-map": "0.0.1" 230 | } 231 | }, 232 | "node_modules/braces": { 233 | "version": "3.0.3", 234 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 235 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 236 | "dev": true, 237 | "license": "MIT", 238 | "dependencies": { 239 | "fill-range": "^7.1.1" 240 | }, 241 | "engines": { 242 | "node": ">=8" 243 | } 244 | }, 245 | "node_modules/bson": { 246 | "version": "6.2.0", 247 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", 248 | "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", 249 | "engines": { 250 | "node": ">=16.20.1" 251 | } 252 | }, 253 | "node_modules/buffer-equal-constant-time": { 254 | "version": "1.0.1", 255 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 256 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 257 | }, 258 | "node_modules/busboy": { 259 | "version": "1.6.0", 260 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", 261 | "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", 262 | "dependencies": { 263 | "streamsearch": "^1.1.0" 264 | }, 265 | "engines": { 266 | "node": ">=10.16.0" 267 | } 268 | }, 269 | "node_modules/bytes": { 270 | "version": "3.1.2", 271 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 272 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 273 | "engines": { 274 | "node": ">= 0.8" 275 | } 276 | }, 277 | "node_modules/call-bind": { 278 | "version": "1.0.5", 279 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", 280 | "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", 281 | "dependencies": { 282 | "function-bind": "^1.1.2", 283 | "get-intrinsic": "^1.2.1", 284 | "set-function-length": "^1.1.1" 285 | }, 286 | "funding": { 287 | "url": "https://github.com/sponsors/ljharb" 288 | } 289 | }, 290 | "node_modules/chokidar": { 291 | "version": "3.6.0", 292 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 293 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 294 | "dev": true, 295 | "license": "MIT", 296 | "dependencies": { 297 | "anymatch": "~3.1.2", 298 | "braces": "~3.0.2", 299 | "glob-parent": "~5.1.2", 300 | "is-binary-path": "~2.1.0", 301 | "is-glob": "~4.0.1", 302 | "normalize-path": "~3.0.0", 303 | "readdirp": "~3.6.0" 304 | }, 305 | "engines": { 306 | "node": ">= 8.10.0" 307 | }, 308 | "funding": { 309 | "url": "https://paulmillr.com/funding/" 310 | }, 311 | "optionalDependencies": { 312 | "fsevents": "~2.3.2" 313 | } 314 | }, 315 | "node_modules/chownr": { 316 | "version": "2.0.0", 317 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", 318 | "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", 319 | "engines": { 320 | "node": ">=10" 321 | } 322 | }, 323 | "node_modules/cloudinary": { 324 | "version": "1.41.2", 325 | "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.41.2.tgz", 326 | "integrity": "sha512-9gH6ofz+N8AzfjqtmTgB9lVxwWcroHFfMOOM6iiX/g1H+KYz+sArClXWtd0prRE6m/IoBBBbbaJ12yRdJNnMxA==", 327 | "dependencies": { 328 | "cloudinary-core": "^2.13.0", 329 | "core-js": "^3.30.1", 330 | "lodash": "^4.17.21", 331 | "q": "^1.5.1" 332 | }, 333 | "engines": { 334 | "node": ">=0.6" 335 | } 336 | }, 337 | "node_modules/cloudinary-core": { 338 | "version": "2.13.0", 339 | "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.13.0.tgz", 340 | "integrity": "sha512-Nt0Q5I2FtenmJghtC4YZ3MZZbGg1wLm84SsxcuVwZ83OyJqG9CNIGp86CiI6iDv3QobaqBUpOT7vg+HqY5HxEA==", 341 | "peerDependencies": { 342 | "lodash": ">=4.0" 343 | } 344 | }, 345 | "node_modules/color-support": { 346 | "version": "1.1.3", 347 | "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", 348 | "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", 349 | "bin": { 350 | "color-support": "bin.js" 351 | } 352 | }, 353 | "node_modules/concat-map": { 354 | "version": "0.0.1", 355 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 356 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 357 | }, 358 | "node_modules/console-control-strings": { 359 | "version": "1.1.0", 360 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 361 | "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" 362 | }, 363 | "node_modules/content-disposition": { 364 | "version": "0.5.4", 365 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 366 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 367 | "dependencies": { 368 | "safe-buffer": "5.2.1" 369 | }, 370 | "engines": { 371 | "node": ">= 0.6" 372 | } 373 | }, 374 | "node_modules/content-type": { 375 | "version": "1.0.5", 376 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 377 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 378 | "engines": { 379 | "node": ">= 0.6" 380 | } 381 | }, 382 | "node_modules/cookie": { 383 | "version": "0.5.0", 384 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 385 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 386 | "engines": { 387 | "node": ">= 0.6" 388 | } 389 | }, 390 | "node_modules/cookie-parser": { 391 | "version": "1.4.6", 392 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", 393 | "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", 394 | "dependencies": { 395 | "cookie": "0.4.1", 396 | "cookie-signature": "1.0.6" 397 | }, 398 | "engines": { 399 | "node": ">= 0.8.0" 400 | } 401 | }, 402 | "node_modules/cookie-parser/node_modules/cookie": { 403 | "version": "0.4.1", 404 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", 405 | "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", 406 | "engines": { 407 | "node": ">= 0.6" 408 | } 409 | }, 410 | "node_modules/cookie-signature": { 411 | "version": "1.0.6", 412 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 413 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 414 | }, 415 | "node_modules/core-js": { 416 | "version": "3.35.0", 417 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.35.0.tgz", 418 | "integrity": "sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==", 419 | "hasInstallScript": true, 420 | "funding": { 421 | "type": "opencollective", 422 | "url": "https://opencollective.com/core-js" 423 | } 424 | }, 425 | "node_modules/cors": { 426 | "version": "2.8.5", 427 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 428 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 429 | "dependencies": { 430 | "object-assign": "^4", 431 | "vary": "^1" 432 | }, 433 | "engines": { 434 | "node": ">= 0.10" 435 | } 436 | }, 437 | "node_modules/debug": { 438 | "version": "2.6.9", 439 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 440 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 441 | "dependencies": { 442 | "ms": "2.0.0" 443 | } 444 | }, 445 | "node_modules/define-data-property": { 446 | "version": "1.1.1", 447 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", 448 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", 449 | "dependencies": { 450 | "get-intrinsic": "^1.2.1", 451 | "gopd": "^1.0.1", 452 | "has-property-descriptors": "^1.0.0" 453 | }, 454 | "engines": { 455 | "node": ">= 0.4" 456 | } 457 | }, 458 | "node_modules/delegates": { 459 | "version": "1.0.0", 460 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 461 | "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" 462 | }, 463 | "node_modules/depd": { 464 | "version": "2.0.0", 465 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 466 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 467 | "engines": { 468 | "node": ">= 0.8" 469 | } 470 | }, 471 | "node_modules/destroy": { 472 | "version": "1.2.0", 473 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 474 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 475 | "engines": { 476 | "node": ">= 0.8", 477 | "npm": "1.2.8000 || >= 1.4.16" 478 | } 479 | }, 480 | "node_modules/detect-libc": { 481 | "version": "2.0.2", 482 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", 483 | "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", 484 | "engines": { 485 | "node": ">=8" 486 | } 487 | }, 488 | "node_modules/dotenv": { 489 | "version": "16.3.1", 490 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", 491 | "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", 492 | "engines": { 493 | "node": ">=12" 494 | }, 495 | "funding": { 496 | "url": "https://github.com/motdotla/dotenv?sponsor=1" 497 | } 498 | }, 499 | "node_modules/ecdsa-sig-formatter": { 500 | "version": "1.0.11", 501 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 502 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 503 | "dependencies": { 504 | "safe-buffer": "^5.0.1" 505 | } 506 | }, 507 | "node_modules/ee-first": { 508 | "version": "1.1.1", 509 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 510 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 511 | }, 512 | "node_modules/emoji-regex": { 513 | "version": "8.0.0", 514 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 515 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 516 | }, 517 | "node_modules/encodeurl": { 518 | "version": "1.0.2", 519 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 520 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 521 | "engines": { 522 | "node": ">= 0.8" 523 | } 524 | }, 525 | "node_modules/escape-html": { 526 | "version": "1.0.3", 527 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 528 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 529 | }, 530 | "node_modules/etag": { 531 | "version": "1.8.1", 532 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 533 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 534 | "engines": { 535 | "node": ">= 0.6" 536 | } 537 | }, 538 | "node_modules/express": { 539 | "version": "4.18.2", 540 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 541 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 542 | "dependencies": { 543 | "accepts": "~1.3.8", 544 | "array-flatten": "1.1.1", 545 | "body-parser": "1.20.1", 546 | "content-disposition": "0.5.4", 547 | "content-type": "~1.0.4", 548 | "cookie": "0.5.0", 549 | "cookie-signature": "1.0.6", 550 | "debug": "2.6.9", 551 | "depd": "2.0.0", 552 | "encodeurl": "~1.0.2", 553 | "escape-html": "~1.0.3", 554 | "etag": "~1.8.1", 555 | "finalhandler": "1.2.0", 556 | "fresh": "0.5.2", 557 | "http-errors": "2.0.0", 558 | "merge-descriptors": "1.0.1", 559 | "methods": "~1.1.2", 560 | "on-finished": "2.4.1", 561 | "parseurl": "~1.3.3", 562 | "path-to-regexp": "0.1.7", 563 | "proxy-addr": "~2.0.7", 564 | "qs": "6.11.0", 565 | "range-parser": "~1.2.1", 566 | "safe-buffer": "5.2.1", 567 | "send": "0.18.0", 568 | "serve-static": "1.15.0", 569 | "setprototypeof": "1.2.0", 570 | "statuses": "2.0.1", 571 | "type-is": "~1.6.18", 572 | "utils-merge": "1.0.1", 573 | "vary": "~1.1.2" 574 | }, 575 | "engines": { 576 | "node": ">= 0.10.0" 577 | } 578 | }, 579 | "node_modules/express-fileupload": { 580 | "version": "1.4.3", 581 | "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.4.3.tgz", 582 | "integrity": "sha512-vRzZo2YELm68DfR/CX8RMXgeK9BTAANxigrKACPjCXFGEzkCt/QWbqaIXP3W61uaX/hLj0CAo3/EVelpSQXkqA==", 583 | "dependencies": { 584 | "busboy": "^1.6.0" 585 | }, 586 | "engines": { 587 | "node": ">=12.0.0" 588 | } 589 | }, 590 | "node_modules/fill-range": { 591 | "version": "7.1.1", 592 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 593 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 594 | "dev": true, 595 | "license": "MIT", 596 | "dependencies": { 597 | "to-regex-range": "^5.0.1" 598 | }, 599 | "engines": { 600 | "node": ">=8" 601 | } 602 | }, 603 | "node_modules/finalhandler": { 604 | "version": "1.2.0", 605 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 606 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 607 | "dependencies": { 608 | "debug": "2.6.9", 609 | "encodeurl": "~1.0.2", 610 | "escape-html": "~1.0.3", 611 | "on-finished": "2.4.1", 612 | "parseurl": "~1.3.3", 613 | "statuses": "2.0.1", 614 | "unpipe": "~1.0.0" 615 | }, 616 | "engines": { 617 | "node": ">= 0.8" 618 | } 619 | }, 620 | "node_modules/forwarded": { 621 | "version": "0.2.0", 622 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 623 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 624 | "engines": { 625 | "node": ">= 0.6" 626 | } 627 | }, 628 | "node_modules/fresh": { 629 | "version": "0.5.2", 630 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 631 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 632 | "engines": { 633 | "node": ">= 0.6" 634 | } 635 | }, 636 | "node_modules/fs-minipass": { 637 | "version": "2.1.0", 638 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", 639 | "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", 640 | "dependencies": { 641 | "minipass": "^3.0.0" 642 | }, 643 | "engines": { 644 | "node": ">= 8" 645 | } 646 | }, 647 | "node_modules/fs-minipass/node_modules/minipass": { 648 | "version": "3.3.6", 649 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", 650 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", 651 | "dependencies": { 652 | "yallist": "^4.0.0" 653 | }, 654 | "engines": { 655 | "node": ">=8" 656 | } 657 | }, 658 | "node_modules/fs.realpath": { 659 | "version": "1.0.0", 660 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 661 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" 662 | }, 663 | "node_modules/fsevents": { 664 | "version": "2.3.3", 665 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 666 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 667 | "dev": true, 668 | "hasInstallScript": true, 669 | "license": "MIT", 670 | "optional": true, 671 | "os": [ 672 | "darwin" 673 | ], 674 | "engines": { 675 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 676 | } 677 | }, 678 | "node_modules/function-bind": { 679 | "version": "1.1.2", 680 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 681 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 682 | "funding": { 683 | "url": "https://github.com/sponsors/ljharb" 684 | } 685 | }, 686 | "node_modules/gauge": { 687 | "version": "3.0.2", 688 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", 689 | "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", 690 | "dependencies": { 691 | "aproba": "^1.0.3 || ^2.0.0", 692 | "color-support": "^1.1.2", 693 | "console-control-strings": "^1.0.0", 694 | "has-unicode": "^2.0.1", 695 | "object-assign": "^4.1.1", 696 | "signal-exit": "^3.0.0", 697 | "string-width": "^4.2.3", 698 | "strip-ansi": "^6.0.1", 699 | "wide-align": "^1.1.2" 700 | }, 701 | "engines": { 702 | "node": ">=10" 703 | } 704 | }, 705 | "node_modules/get-intrinsic": { 706 | "version": "1.2.2", 707 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", 708 | "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", 709 | "dependencies": { 710 | "function-bind": "^1.1.2", 711 | "has-proto": "^1.0.1", 712 | "has-symbols": "^1.0.3", 713 | "hasown": "^2.0.0" 714 | }, 715 | "funding": { 716 | "url": "https://github.com/sponsors/ljharb" 717 | } 718 | }, 719 | "node_modules/glob": { 720 | "version": "7.2.3", 721 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 722 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 723 | "dependencies": { 724 | "fs.realpath": "^1.0.0", 725 | "inflight": "^1.0.4", 726 | "inherits": "2", 727 | "minimatch": "^3.1.1", 728 | "once": "^1.3.0", 729 | "path-is-absolute": "^1.0.0" 730 | }, 731 | "engines": { 732 | "node": "*" 733 | }, 734 | "funding": { 735 | "url": "https://github.com/sponsors/isaacs" 736 | } 737 | }, 738 | "node_modules/glob-parent": { 739 | "version": "5.1.2", 740 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 741 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 742 | "dev": true, 743 | "license": "ISC", 744 | "dependencies": { 745 | "is-glob": "^4.0.1" 746 | }, 747 | "engines": { 748 | "node": ">= 6" 749 | } 750 | }, 751 | "node_modules/gopd": { 752 | "version": "1.0.1", 753 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 754 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 755 | "dependencies": { 756 | "get-intrinsic": "^1.1.3" 757 | }, 758 | "funding": { 759 | "url": "https://github.com/sponsors/ljharb" 760 | } 761 | }, 762 | "node_modules/has-flag": { 763 | "version": "3.0.0", 764 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 765 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 766 | "dev": true, 767 | "license": "MIT", 768 | "engines": { 769 | "node": ">=4" 770 | } 771 | }, 772 | "node_modules/has-property-descriptors": { 773 | "version": "1.0.1", 774 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", 775 | "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", 776 | "dependencies": { 777 | "get-intrinsic": "^1.2.2" 778 | }, 779 | "funding": { 780 | "url": "https://github.com/sponsors/ljharb" 781 | } 782 | }, 783 | "node_modules/has-proto": { 784 | "version": "1.0.1", 785 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 786 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 787 | "engines": { 788 | "node": ">= 0.4" 789 | }, 790 | "funding": { 791 | "url": "https://github.com/sponsors/ljharb" 792 | } 793 | }, 794 | "node_modules/has-symbols": { 795 | "version": "1.0.3", 796 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 797 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 798 | "engines": { 799 | "node": ">= 0.4" 800 | }, 801 | "funding": { 802 | "url": "https://github.com/sponsors/ljharb" 803 | } 804 | }, 805 | "node_modules/has-unicode": { 806 | "version": "2.0.1", 807 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 808 | "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" 809 | }, 810 | "node_modules/hasown": { 811 | "version": "2.0.0", 812 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", 813 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", 814 | "dependencies": { 815 | "function-bind": "^1.1.2" 816 | }, 817 | "engines": { 818 | "node": ">= 0.4" 819 | } 820 | }, 821 | "node_modules/http-errors": { 822 | "version": "2.0.0", 823 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 824 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 825 | "dependencies": { 826 | "depd": "2.0.0", 827 | "inherits": "2.0.4", 828 | "setprototypeof": "1.2.0", 829 | "statuses": "2.0.1", 830 | "toidentifier": "1.0.1" 831 | }, 832 | "engines": { 833 | "node": ">= 0.8" 834 | } 835 | }, 836 | "node_modules/https-proxy-agent": { 837 | "version": "5.0.1", 838 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", 839 | "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", 840 | "dependencies": { 841 | "agent-base": "6", 842 | "debug": "4" 843 | }, 844 | "engines": { 845 | "node": ">= 6" 846 | } 847 | }, 848 | "node_modules/https-proxy-agent/node_modules/debug": { 849 | "version": "4.3.4", 850 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 851 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 852 | "dependencies": { 853 | "ms": "2.1.2" 854 | }, 855 | "engines": { 856 | "node": ">=6.0" 857 | }, 858 | "peerDependenciesMeta": { 859 | "supports-color": { 860 | "optional": true 861 | } 862 | } 863 | }, 864 | "node_modules/https-proxy-agent/node_modules/ms": { 865 | "version": "2.1.2", 866 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 867 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 868 | }, 869 | "node_modules/iconv-lite": { 870 | "version": "0.4.24", 871 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 872 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 873 | "dependencies": { 874 | "safer-buffer": ">= 2.1.2 < 3" 875 | }, 876 | "engines": { 877 | "node": ">=0.10.0" 878 | } 879 | }, 880 | "node_modules/ignore-by-default": { 881 | "version": "1.0.1", 882 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 883 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", 884 | "dev": true, 885 | "license": "ISC" 886 | }, 887 | "node_modules/inflight": { 888 | "version": "1.0.6", 889 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 890 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 891 | "dependencies": { 892 | "once": "^1.3.0", 893 | "wrappy": "1" 894 | } 895 | }, 896 | "node_modules/inherits": { 897 | "version": "2.0.4", 898 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 899 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 900 | }, 901 | "node_modules/ipaddr.js": { 902 | "version": "1.9.1", 903 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 904 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 905 | "engines": { 906 | "node": ">= 0.10" 907 | } 908 | }, 909 | "node_modules/is-binary-path": { 910 | "version": "2.1.0", 911 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 912 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 913 | "dev": true, 914 | "license": "MIT", 915 | "dependencies": { 916 | "binary-extensions": "^2.0.0" 917 | }, 918 | "engines": { 919 | "node": ">=8" 920 | } 921 | }, 922 | "node_modules/is-extglob": { 923 | "version": "2.1.1", 924 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 925 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 926 | "dev": true, 927 | "license": "MIT", 928 | "engines": { 929 | "node": ">=0.10.0" 930 | } 931 | }, 932 | "node_modules/is-fullwidth-code-point": { 933 | "version": "3.0.0", 934 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 935 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 936 | "engines": { 937 | "node": ">=8" 938 | } 939 | }, 940 | "node_modules/is-glob": { 941 | "version": "4.0.3", 942 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 943 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 944 | "dev": true, 945 | "license": "MIT", 946 | "dependencies": { 947 | "is-extglob": "^2.1.1" 948 | }, 949 | "engines": { 950 | "node": ">=0.10.0" 951 | } 952 | }, 953 | "node_modules/is-number": { 954 | "version": "7.0.0", 955 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 956 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 957 | "dev": true, 958 | "license": "MIT", 959 | "engines": { 960 | "node": ">=0.12.0" 961 | } 962 | }, 963 | "node_modules/jsonwebtoken": { 964 | "version": "9.0.2", 965 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", 966 | "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 967 | "dependencies": { 968 | "jws": "^3.2.2", 969 | "lodash.includes": "^4.3.0", 970 | "lodash.isboolean": "^3.0.3", 971 | "lodash.isinteger": "^4.0.4", 972 | "lodash.isnumber": "^3.0.3", 973 | "lodash.isplainobject": "^4.0.6", 974 | "lodash.isstring": "^4.0.1", 975 | "lodash.once": "^4.0.0", 976 | "ms": "^2.1.1", 977 | "semver": "^7.5.4" 978 | }, 979 | "engines": { 980 | "node": ">=12", 981 | "npm": ">=6" 982 | } 983 | }, 984 | "node_modules/jsonwebtoken/node_modules/ms": { 985 | "version": "2.1.3", 986 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 987 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 988 | }, 989 | "node_modules/jwa": { 990 | "version": "1.4.1", 991 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 992 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 993 | "dependencies": { 994 | "buffer-equal-constant-time": "1.0.1", 995 | "ecdsa-sig-formatter": "1.0.11", 996 | "safe-buffer": "^5.0.1" 997 | } 998 | }, 999 | "node_modules/jws": { 1000 | "version": "3.2.2", 1001 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 1002 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 1003 | "dependencies": { 1004 | "jwa": "^1.4.1", 1005 | "safe-buffer": "^5.0.1" 1006 | } 1007 | }, 1008 | "node_modules/kareem": { 1009 | "version": "2.5.1", 1010 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", 1011 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", 1012 | "engines": { 1013 | "node": ">=12.0.0" 1014 | } 1015 | }, 1016 | "node_modules/lodash": { 1017 | "version": "4.17.21", 1018 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1019 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 1020 | }, 1021 | "node_modules/lodash.includes": { 1022 | "version": "4.3.0", 1023 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 1024 | "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 1025 | }, 1026 | "node_modules/lodash.isboolean": { 1027 | "version": "3.0.3", 1028 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 1029 | "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 1030 | }, 1031 | "node_modules/lodash.isinteger": { 1032 | "version": "4.0.4", 1033 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 1034 | "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 1035 | }, 1036 | "node_modules/lodash.isnumber": { 1037 | "version": "3.0.3", 1038 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 1039 | "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 1040 | }, 1041 | "node_modules/lodash.isplainobject": { 1042 | "version": "4.0.6", 1043 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 1044 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 1045 | }, 1046 | "node_modules/lodash.isstring": { 1047 | "version": "4.0.1", 1048 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 1049 | "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 1050 | }, 1051 | "node_modules/lodash.once": { 1052 | "version": "4.1.1", 1053 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 1054 | "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 1055 | }, 1056 | "node_modules/lru-cache": { 1057 | "version": "6.0.0", 1058 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1059 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1060 | "dependencies": { 1061 | "yallist": "^4.0.0" 1062 | }, 1063 | "engines": { 1064 | "node": ">=10" 1065 | } 1066 | }, 1067 | "node_modules/make-dir": { 1068 | "version": "3.1.0", 1069 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 1070 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 1071 | "dependencies": { 1072 | "semver": "^6.0.0" 1073 | }, 1074 | "engines": { 1075 | "node": ">=8" 1076 | }, 1077 | "funding": { 1078 | "url": "https://github.com/sponsors/sindresorhus" 1079 | } 1080 | }, 1081 | "node_modules/make-dir/node_modules/semver": { 1082 | "version": "6.3.1", 1083 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 1084 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 1085 | "bin": { 1086 | "semver": "bin/semver.js" 1087 | } 1088 | }, 1089 | "node_modules/media-typer": { 1090 | "version": "0.3.0", 1091 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1092 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 1093 | "engines": { 1094 | "node": ">= 0.6" 1095 | } 1096 | }, 1097 | "node_modules/memory-pager": { 1098 | "version": "1.5.0", 1099 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 1100 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 1101 | }, 1102 | "node_modules/merge-descriptors": { 1103 | "version": "1.0.1", 1104 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1105 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 1106 | }, 1107 | "node_modules/methods": { 1108 | "version": "1.1.2", 1109 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1110 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1111 | "engines": { 1112 | "node": ">= 0.6" 1113 | } 1114 | }, 1115 | "node_modules/mime": { 1116 | "version": "1.6.0", 1117 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1118 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 1119 | "bin": { 1120 | "mime": "cli.js" 1121 | }, 1122 | "engines": { 1123 | "node": ">=4" 1124 | } 1125 | }, 1126 | "node_modules/mime-db": { 1127 | "version": "1.52.0", 1128 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1129 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1130 | "engines": { 1131 | "node": ">= 0.6" 1132 | } 1133 | }, 1134 | "node_modules/mime-types": { 1135 | "version": "2.1.35", 1136 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1137 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1138 | "dependencies": { 1139 | "mime-db": "1.52.0" 1140 | }, 1141 | "engines": { 1142 | "node": ">= 0.6" 1143 | } 1144 | }, 1145 | "node_modules/minimatch": { 1146 | "version": "3.1.2", 1147 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1148 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1149 | "dependencies": { 1150 | "brace-expansion": "^1.1.7" 1151 | }, 1152 | "engines": { 1153 | "node": "*" 1154 | } 1155 | }, 1156 | "node_modules/minipass": { 1157 | "version": "5.0.0", 1158 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", 1159 | "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", 1160 | "engines": { 1161 | "node": ">=8" 1162 | } 1163 | }, 1164 | "node_modules/minizlib": { 1165 | "version": "2.1.2", 1166 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", 1167 | "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", 1168 | "dependencies": { 1169 | "minipass": "^3.0.0", 1170 | "yallist": "^4.0.0" 1171 | }, 1172 | "engines": { 1173 | "node": ">= 8" 1174 | } 1175 | }, 1176 | "node_modules/minizlib/node_modules/minipass": { 1177 | "version": "3.3.6", 1178 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", 1179 | "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", 1180 | "dependencies": { 1181 | "yallist": "^4.0.0" 1182 | }, 1183 | "engines": { 1184 | "node": ">=8" 1185 | } 1186 | }, 1187 | "node_modules/mkdirp": { 1188 | "version": "1.0.4", 1189 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 1190 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 1191 | "bin": { 1192 | "mkdirp": "bin/cmd.js" 1193 | }, 1194 | "engines": { 1195 | "node": ">=10" 1196 | } 1197 | }, 1198 | "node_modules/mongodb": { 1199 | "version": "6.2.0", 1200 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz", 1201 | "integrity": "sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA==", 1202 | "dependencies": { 1203 | "@mongodb-js/saslprep": "^1.1.0", 1204 | "bson": "^6.2.0", 1205 | "mongodb-connection-string-url": "^2.6.0" 1206 | }, 1207 | "engines": { 1208 | "node": ">=16.20.1" 1209 | }, 1210 | "peerDependencies": { 1211 | "@aws-sdk/credential-providers": "^3.188.0", 1212 | "@mongodb-js/zstd": "^1.1.0", 1213 | "gcp-metadata": "^5.2.0", 1214 | "kerberos": "^2.0.1", 1215 | "mongodb-client-encryption": ">=6.0.0 <7", 1216 | "snappy": "^7.2.2", 1217 | "socks": "^2.7.1" 1218 | }, 1219 | "peerDependenciesMeta": { 1220 | "@aws-sdk/credential-providers": { 1221 | "optional": true 1222 | }, 1223 | "@mongodb-js/zstd": { 1224 | "optional": true 1225 | }, 1226 | "gcp-metadata": { 1227 | "optional": true 1228 | }, 1229 | "kerberos": { 1230 | "optional": true 1231 | }, 1232 | "mongodb-client-encryption": { 1233 | "optional": true 1234 | }, 1235 | "snappy": { 1236 | "optional": true 1237 | }, 1238 | "socks": { 1239 | "optional": true 1240 | } 1241 | } 1242 | }, 1243 | "node_modules/mongodb-connection-string-url": { 1244 | "version": "2.6.0", 1245 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", 1246 | "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", 1247 | "dependencies": { 1248 | "@types/whatwg-url": "^8.2.1", 1249 | "whatwg-url": "^11.0.0" 1250 | } 1251 | }, 1252 | "node_modules/mongoose": { 1253 | "version": "8.0.3", 1254 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.0.3.tgz", 1255 | "integrity": "sha512-LJRT0yP4TW14HT4r2RkxqyvoTylMSzWpl5QOeVHTnRggCLQSpkoBdgbUtORFq/mSL2o9cLCPJz+6uzFj25qbHw==", 1256 | "dependencies": { 1257 | "bson": "^6.2.0", 1258 | "kareem": "2.5.1", 1259 | "mongodb": "6.2.0", 1260 | "mpath": "0.9.0", 1261 | "mquery": "5.0.0", 1262 | "ms": "2.1.3", 1263 | "sift": "16.0.1" 1264 | }, 1265 | "engines": { 1266 | "node": ">=16.20.1" 1267 | }, 1268 | "funding": { 1269 | "type": "opencollective", 1270 | "url": "https://opencollective.com/mongoose" 1271 | } 1272 | }, 1273 | "node_modules/mongoose/node_modules/ms": { 1274 | "version": "2.1.3", 1275 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1276 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1277 | }, 1278 | "node_modules/mpath": { 1279 | "version": "0.9.0", 1280 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", 1281 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", 1282 | "engines": { 1283 | "node": ">=4.0.0" 1284 | } 1285 | }, 1286 | "node_modules/mquery": { 1287 | "version": "5.0.0", 1288 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", 1289 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", 1290 | "dependencies": { 1291 | "debug": "4.x" 1292 | }, 1293 | "engines": { 1294 | "node": ">=14.0.0" 1295 | } 1296 | }, 1297 | "node_modules/mquery/node_modules/debug": { 1298 | "version": "4.3.4", 1299 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1300 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1301 | "dependencies": { 1302 | "ms": "2.1.2" 1303 | }, 1304 | "engines": { 1305 | "node": ">=6.0" 1306 | }, 1307 | "peerDependenciesMeta": { 1308 | "supports-color": { 1309 | "optional": true 1310 | } 1311 | } 1312 | }, 1313 | "node_modules/mquery/node_modules/ms": { 1314 | "version": "2.1.2", 1315 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1316 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1317 | }, 1318 | "node_modules/ms": { 1319 | "version": "2.0.0", 1320 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1321 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1322 | }, 1323 | "node_modules/negotiator": { 1324 | "version": "0.6.3", 1325 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1326 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1327 | "engines": { 1328 | "node": ">= 0.6" 1329 | } 1330 | }, 1331 | "node_modules/node-addon-api": { 1332 | "version": "5.1.0", 1333 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", 1334 | "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==" 1335 | }, 1336 | "node_modules/node-fetch": { 1337 | "version": "2.7.0", 1338 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 1339 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 1340 | "dependencies": { 1341 | "whatwg-url": "^5.0.0" 1342 | }, 1343 | "engines": { 1344 | "node": "4.x || >=6.0.0" 1345 | }, 1346 | "peerDependencies": { 1347 | "encoding": "^0.1.0" 1348 | }, 1349 | "peerDependenciesMeta": { 1350 | "encoding": { 1351 | "optional": true 1352 | } 1353 | } 1354 | }, 1355 | "node_modules/node-fetch/node_modules/tr46": { 1356 | "version": "0.0.3", 1357 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 1358 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 1359 | }, 1360 | "node_modules/node-fetch/node_modules/webidl-conversions": { 1361 | "version": "3.0.1", 1362 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 1363 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 1364 | }, 1365 | "node_modules/node-fetch/node_modules/whatwg-url": { 1366 | "version": "5.0.0", 1367 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 1368 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 1369 | "dependencies": { 1370 | "tr46": "~0.0.3", 1371 | "webidl-conversions": "^3.0.0" 1372 | } 1373 | }, 1374 | "node_modules/nodemon": { 1375 | "version": "3.1.7", 1376 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", 1377 | "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", 1378 | "dev": true, 1379 | "license": "MIT", 1380 | "dependencies": { 1381 | "chokidar": "^3.5.2", 1382 | "debug": "^4", 1383 | "ignore-by-default": "^1.0.1", 1384 | "minimatch": "^3.1.2", 1385 | "pstree.remy": "^1.1.8", 1386 | "semver": "^7.5.3", 1387 | "simple-update-notifier": "^2.0.0", 1388 | "supports-color": "^5.5.0", 1389 | "touch": "^3.1.0", 1390 | "undefsafe": "^2.0.5" 1391 | }, 1392 | "bin": { 1393 | "nodemon": "bin/nodemon.js" 1394 | }, 1395 | "engines": { 1396 | "node": ">=10" 1397 | }, 1398 | "funding": { 1399 | "type": "opencollective", 1400 | "url": "https://opencollective.com/nodemon" 1401 | } 1402 | }, 1403 | "node_modules/nodemon/node_modules/debug": { 1404 | "version": "4.3.7", 1405 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 1406 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 1407 | "dev": true, 1408 | "license": "MIT", 1409 | "dependencies": { 1410 | "ms": "^2.1.3" 1411 | }, 1412 | "engines": { 1413 | "node": ">=6.0" 1414 | }, 1415 | "peerDependenciesMeta": { 1416 | "supports-color": { 1417 | "optional": true 1418 | } 1419 | } 1420 | }, 1421 | "node_modules/nodemon/node_modules/ms": { 1422 | "version": "2.1.3", 1423 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1424 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1425 | "dev": true, 1426 | "license": "MIT" 1427 | }, 1428 | "node_modules/nopt": { 1429 | "version": "5.0.0", 1430 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", 1431 | "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", 1432 | "dependencies": { 1433 | "abbrev": "1" 1434 | }, 1435 | "bin": { 1436 | "nopt": "bin/nopt.js" 1437 | }, 1438 | "engines": { 1439 | "node": ">=6" 1440 | } 1441 | }, 1442 | "node_modules/normalize-path": { 1443 | "version": "3.0.0", 1444 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1445 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1446 | "dev": true, 1447 | "license": "MIT", 1448 | "engines": { 1449 | "node": ">=0.10.0" 1450 | } 1451 | }, 1452 | "node_modules/npmlog": { 1453 | "version": "5.0.1", 1454 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", 1455 | "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", 1456 | "dependencies": { 1457 | "are-we-there-yet": "^2.0.0", 1458 | "console-control-strings": "^1.1.0", 1459 | "gauge": "^3.0.0", 1460 | "set-blocking": "^2.0.0" 1461 | } 1462 | }, 1463 | "node_modules/object-assign": { 1464 | "version": "4.1.1", 1465 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1466 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1467 | "engines": { 1468 | "node": ">=0.10.0" 1469 | } 1470 | }, 1471 | "node_modules/object-inspect": { 1472 | "version": "1.13.1", 1473 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", 1474 | "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", 1475 | "funding": { 1476 | "url": "https://github.com/sponsors/ljharb" 1477 | } 1478 | }, 1479 | "node_modules/on-finished": { 1480 | "version": "2.4.1", 1481 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1482 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1483 | "dependencies": { 1484 | "ee-first": "1.1.1" 1485 | }, 1486 | "engines": { 1487 | "node": ">= 0.8" 1488 | } 1489 | }, 1490 | "node_modules/once": { 1491 | "version": "1.4.0", 1492 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1493 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1494 | "dependencies": { 1495 | "wrappy": "1" 1496 | } 1497 | }, 1498 | "node_modules/parseurl": { 1499 | "version": "1.3.3", 1500 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1501 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1502 | "engines": { 1503 | "node": ">= 0.8" 1504 | } 1505 | }, 1506 | "node_modules/path-is-absolute": { 1507 | "version": "1.0.1", 1508 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1509 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1510 | "engines": { 1511 | "node": ">=0.10.0" 1512 | } 1513 | }, 1514 | "node_modules/path-to-regexp": { 1515 | "version": "0.1.7", 1516 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1517 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1518 | }, 1519 | "node_modules/picomatch": { 1520 | "version": "2.3.1", 1521 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1522 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1523 | "dev": true, 1524 | "license": "MIT", 1525 | "engines": { 1526 | "node": ">=8.6" 1527 | }, 1528 | "funding": { 1529 | "url": "https://github.com/sponsors/jonschlinkert" 1530 | } 1531 | }, 1532 | "node_modules/proxy-addr": { 1533 | "version": "2.0.7", 1534 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1535 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1536 | "dependencies": { 1537 | "forwarded": "0.2.0", 1538 | "ipaddr.js": "1.9.1" 1539 | }, 1540 | "engines": { 1541 | "node": ">= 0.10" 1542 | } 1543 | }, 1544 | "node_modules/pstree.remy": { 1545 | "version": "1.1.8", 1546 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", 1547 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", 1548 | "dev": true, 1549 | "license": "MIT" 1550 | }, 1551 | "node_modules/punycode": { 1552 | "version": "2.3.1", 1553 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1554 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1555 | "engines": { 1556 | "node": ">=6" 1557 | } 1558 | }, 1559 | "node_modules/q": { 1560 | "version": "1.5.1", 1561 | "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", 1562 | "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", 1563 | "engines": { 1564 | "node": ">=0.6.0", 1565 | "teleport": ">=0.2.0" 1566 | } 1567 | }, 1568 | "node_modules/qs": { 1569 | "version": "6.11.0", 1570 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 1571 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 1572 | "dependencies": { 1573 | "side-channel": "^1.0.4" 1574 | }, 1575 | "engines": { 1576 | "node": ">=0.6" 1577 | }, 1578 | "funding": { 1579 | "url": "https://github.com/sponsors/ljharb" 1580 | } 1581 | }, 1582 | "node_modules/range-parser": { 1583 | "version": "1.2.1", 1584 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1585 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1586 | "engines": { 1587 | "node": ">= 0.6" 1588 | } 1589 | }, 1590 | "node_modules/raw-body": { 1591 | "version": "2.5.1", 1592 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 1593 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 1594 | "dependencies": { 1595 | "bytes": "3.1.2", 1596 | "http-errors": "2.0.0", 1597 | "iconv-lite": "0.4.24", 1598 | "unpipe": "1.0.0" 1599 | }, 1600 | "engines": { 1601 | "node": ">= 0.8" 1602 | } 1603 | }, 1604 | "node_modules/readable-stream": { 1605 | "version": "3.6.2", 1606 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1607 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1608 | "dependencies": { 1609 | "inherits": "^2.0.3", 1610 | "string_decoder": "^1.1.1", 1611 | "util-deprecate": "^1.0.1" 1612 | }, 1613 | "engines": { 1614 | "node": ">= 6" 1615 | } 1616 | }, 1617 | "node_modules/readdirp": { 1618 | "version": "3.6.0", 1619 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1620 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1621 | "dev": true, 1622 | "license": "MIT", 1623 | "dependencies": { 1624 | "picomatch": "^2.2.1" 1625 | }, 1626 | "engines": { 1627 | "node": ">=8.10.0" 1628 | } 1629 | }, 1630 | "node_modules/rimraf": { 1631 | "version": "3.0.2", 1632 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1633 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1634 | "dependencies": { 1635 | "glob": "^7.1.3" 1636 | }, 1637 | "bin": { 1638 | "rimraf": "bin.js" 1639 | }, 1640 | "funding": { 1641 | "url": "https://github.com/sponsors/isaacs" 1642 | } 1643 | }, 1644 | "node_modules/safe-buffer": { 1645 | "version": "5.2.1", 1646 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1647 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1648 | "funding": [ 1649 | { 1650 | "type": "github", 1651 | "url": "https://github.com/sponsors/feross" 1652 | }, 1653 | { 1654 | "type": "patreon", 1655 | "url": "https://www.patreon.com/feross" 1656 | }, 1657 | { 1658 | "type": "consulting", 1659 | "url": "https://feross.org/support" 1660 | } 1661 | ] 1662 | }, 1663 | "node_modules/safer-buffer": { 1664 | "version": "2.1.2", 1665 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1666 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1667 | }, 1668 | "node_modules/semver": { 1669 | "version": "7.5.4", 1670 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1671 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1672 | "dependencies": { 1673 | "lru-cache": "^6.0.0" 1674 | }, 1675 | "bin": { 1676 | "semver": "bin/semver.js" 1677 | }, 1678 | "engines": { 1679 | "node": ">=10" 1680 | } 1681 | }, 1682 | "node_modules/send": { 1683 | "version": "0.18.0", 1684 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1685 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1686 | "dependencies": { 1687 | "debug": "2.6.9", 1688 | "depd": "2.0.0", 1689 | "destroy": "1.2.0", 1690 | "encodeurl": "~1.0.2", 1691 | "escape-html": "~1.0.3", 1692 | "etag": "~1.8.1", 1693 | "fresh": "0.5.2", 1694 | "http-errors": "2.0.0", 1695 | "mime": "1.6.0", 1696 | "ms": "2.1.3", 1697 | "on-finished": "2.4.1", 1698 | "range-parser": "~1.2.1", 1699 | "statuses": "2.0.1" 1700 | }, 1701 | "engines": { 1702 | "node": ">= 0.8.0" 1703 | } 1704 | }, 1705 | "node_modules/send/node_modules/ms": { 1706 | "version": "2.1.3", 1707 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1708 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1709 | }, 1710 | "node_modules/serve-static": { 1711 | "version": "1.15.0", 1712 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 1713 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 1714 | "dependencies": { 1715 | "encodeurl": "~1.0.2", 1716 | "escape-html": "~1.0.3", 1717 | "parseurl": "~1.3.3", 1718 | "send": "0.18.0" 1719 | }, 1720 | "engines": { 1721 | "node": ">= 0.8.0" 1722 | } 1723 | }, 1724 | "node_modules/set-blocking": { 1725 | "version": "2.0.0", 1726 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1727 | "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" 1728 | }, 1729 | "node_modules/set-function-length": { 1730 | "version": "1.1.1", 1731 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", 1732 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", 1733 | "dependencies": { 1734 | "define-data-property": "^1.1.1", 1735 | "get-intrinsic": "^1.2.1", 1736 | "gopd": "^1.0.1", 1737 | "has-property-descriptors": "^1.0.0" 1738 | }, 1739 | "engines": { 1740 | "node": ">= 0.4" 1741 | } 1742 | }, 1743 | "node_modules/setprototypeof": { 1744 | "version": "1.2.0", 1745 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1746 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1747 | }, 1748 | "node_modules/side-channel": { 1749 | "version": "1.0.4", 1750 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1751 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1752 | "dependencies": { 1753 | "call-bind": "^1.0.0", 1754 | "get-intrinsic": "^1.0.2", 1755 | "object-inspect": "^1.9.0" 1756 | }, 1757 | "funding": { 1758 | "url": "https://github.com/sponsors/ljharb" 1759 | } 1760 | }, 1761 | "node_modules/sift": { 1762 | "version": "16.0.1", 1763 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", 1764 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" 1765 | }, 1766 | "node_modules/signal-exit": { 1767 | "version": "3.0.7", 1768 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 1769 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" 1770 | }, 1771 | "node_modules/simple-update-notifier": { 1772 | "version": "2.0.0", 1773 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", 1774 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", 1775 | "dev": true, 1776 | "license": "MIT", 1777 | "dependencies": { 1778 | "semver": "^7.5.3" 1779 | }, 1780 | "engines": { 1781 | "node": ">=10" 1782 | } 1783 | }, 1784 | "node_modules/sparse-bitfield": { 1785 | "version": "3.0.3", 1786 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 1787 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 1788 | "dependencies": { 1789 | "memory-pager": "^1.0.2" 1790 | } 1791 | }, 1792 | "node_modules/statuses": { 1793 | "version": "2.0.1", 1794 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1795 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1796 | "engines": { 1797 | "node": ">= 0.8" 1798 | } 1799 | }, 1800 | "node_modules/streamsearch": { 1801 | "version": "1.1.0", 1802 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", 1803 | "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", 1804 | "engines": { 1805 | "node": ">=10.0.0" 1806 | } 1807 | }, 1808 | "node_modules/string_decoder": { 1809 | "version": "1.3.0", 1810 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1811 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1812 | "dependencies": { 1813 | "safe-buffer": "~5.2.0" 1814 | } 1815 | }, 1816 | "node_modules/string-width": { 1817 | "version": "4.2.3", 1818 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1819 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1820 | "dependencies": { 1821 | "emoji-regex": "^8.0.0", 1822 | "is-fullwidth-code-point": "^3.0.0", 1823 | "strip-ansi": "^6.0.1" 1824 | }, 1825 | "engines": { 1826 | "node": ">=8" 1827 | } 1828 | }, 1829 | "node_modules/strip-ansi": { 1830 | "version": "6.0.1", 1831 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1832 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1833 | "dependencies": { 1834 | "ansi-regex": "^5.0.1" 1835 | }, 1836 | "engines": { 1837 | "node": ">=8" 1838 | } 1839 | }, 1840 | "node_modules/supports-color": { 1841 | "version": "5.5.0", 1842 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1843 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1844 | "dev": true, 1845 | "license": "MIT", 1846 | "dependencies": { 1847 | "has-flag": "^3.0.0" 1848 | }, 1849 | "engines": { 1850 | "node": ">=4" 1851 | } 1852 | }, 1853 | "node_modules/tar": { 1854 | "version": "6.2.0", 1855 | "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", 1856 | "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", 1857 | "dependencies": { 1858 | "chownr": "^2.0.0", 1859 | "fs-minipass": "^2.0.0", 1860 | "minipass": "^5.0.0", 1861 | "minizlib": "^2.1.1", 1862 | "mkdirp": "^1.0.3", 1863 | "yallist": "^4.0.0" 1864 | }, 1865 | "engines": { 1866 | "node": ">=10" 1867 | } 1868 | }, 1869 | "node_modules/to-regex-range": { 1870 | "version": "5.0.1", 1871 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1872 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1873 | "dev": true, 1874 | "license": "MIT", 1875 | "dependencies": { 1876 | "is-number": "^7.0.0" 1877 | }, 1878 | "engines": { 1879 | "node": ">=8.0" 1880 | } 1881 | }, 1882 | "node_modules/toidentifier": { 1883 | "version": "1.0.1", 1884 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1885 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1886 | "engines": { 1887 | "node": ">=0.6" 1888 | } 1889 | }, 1890 | "node_modules/touch": { 1891 | "version": "3.1.1", 1892 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", 1893 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", 1894 | "dev": true, 1895 | "license": "ISC", 1896 | "bin": { 1897 | "nodetouch": "bin/nodetouch.js" 1898 | } 1899 | }, 1900 | "node_modules/tr46": { 1901 | "version": "3.0.0", 1902 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", 1903 | "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", 1904 | "dependencies": { 1905 | "punycode": "^2.1.1" 1906 | }, 1907 | "engines": { 1908 | "node": ">=12" 1909 | } 1910 | }, 1911 | "node_modules/type-is": { 1912 | "version": "1.6.18", 1913 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1914 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1915 | "dependencies": { 1916 | "media-typer": "0.3.0", 1917 | "mime-types": "~2.1.24" 1918 | }, 1919 | "engines": { 1920 | "node": ">= 0.6" 1921 | } 1922 | }, 1923 | "node_modules/undefsafe": { 1924 | "version": "2.0.5", 1925 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", 1926 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", 1927 | "dev": true, 1928 | "license": "MIT" 1929 | }, 1930 | "node_modules/undici-types": { 1931 | "version": "5.26.5", 1932 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1933 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 1934 | }, 1935 | "node_modules/unpipe": { 1936 | "version": "1.0.0", 1937 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1938 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1939 | "engines": { 1940 | "node": ">= 0.8" 1941 | } 1942 | }, 1943 | "node_modules/util-deprecate": { 1944 | "version": "1.0.2", 1945 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1946 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 1947 | }, 1948 | "node_modules/utils-merge": { 1949 | "version": "1.0.1", 1950 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1951 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 1952 | "engines": { 1953 | "node": ">= 0.4.0" 1954 | } 1955 | }, 1956 | "node_modules/validator": { 1957 | "version": "13.11.0", 1958 | "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", 1959 | "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", 1960 | "engines": { 1961 | "node": ">= 0.10" 1962 | } 1963 | }, 1964 | "node_modules/vary": { 1965 | "version": "1.1.2", 1966 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1967 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 1968 | "engines": { 1969 | "node": ">= 0.8" 1970 | } 1971 | }, 1972 | "node_modules/webidl-conversions": { 1973 | "version": "7.0.0", 1974 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 1975 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 1976 | "engines": { 1977 | "node": ">=12" 1978 | } 1979 | }, 1980 | "node_modules/whatwg-url": { 1981 | "version": "11.0.0", 1982 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", 1983 | "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", 1984 | "dependencies": { 1985 | "tr46": "^3.0.0", 1986 | "webidl-conversions": "^7.0.0" 1987 | }, 1988 | "engines": { 1989 | "node": ">=12" 1990 | } 1991 | }, 1992 | "node_modules/wide-align": { 1993 | "version": "1.1.5", 1994 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", 1995 | "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", 1996 | "dependencies": { 1997 | "string-width": "^1.0.2 || 2 || 3 || 4" 1998 | } 1999 | }, 2000 | "node_modules/wrappy": { 2001 | "version": "1.0.2", 2002 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2003 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 2004 | }, 2005 | "node_modules/yallist": { 2006 | "version": "4.0.0", 2007 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2008 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" 2009 | } 2010 | } 2011 | } 2012 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "node server.js", 9 | "dev": "node server.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "bcrypt": "^5.1.1", 15 | "cloudinary": "^1.41.2", 16 | "cookie-parser": "^1.4.6", 17 | "cors": "^2.8.5", 18 | "dotenv": "^16.3.1", 19 | "express": "^4.18.2", 20 | "express-fileupload": "^1.4.3", 21 | "jsonwebtoken": "^9.0.2", 22 | "mongoose": "^8.0.3", 23 | "validator": "^13.11.0" 24 | }, 25 | "devDependencies": { 26 | "nodemon": "^3.1.7" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /backend/routes/applicationRoutes.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | employerGetAllApplications, 4 | jobseekerDeleteApplication, 5 | jobseekerGetAllApplications, 6 | postApplication, 7 | } from "../controllers/applicationController.js"; 8 | import { isAuthenticated } from "../middlewares/auth.js"; 9 | 10 | const router = express.Router(); 11 | 12 | router.post("/post", isAuthenticated, postApplication); 13 | router.get("/employer/getall", isAuthenticated, employerGetAllApplications); 14 | router.get("/jobseeker/getall", isAuthenticated, jobseekerGetAllApplications); 15 | router.delete("/delete/:id", isAuthenticated, jobseekerDeleteApplication); 16 | 17 | export default router; 18 | -------------------------------------------------------------------------------- /backend/routes/jobRoutes.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | deleteJob, 4 | getAllJobs, 5 | getMyJobs, 6 | getSingleJob, 7 | postJob, 8 | updateJob, 9 | } from "../controllers/jobController.js"; 10 | import { isAuthenticated } from "../middlewares/auth.js"; 11 | 12 | const router = express.Router(); 13 | 14 | router.get("/getall", getAllJobs); 15 | router.post("/post", isAuthenticated, postJob); 16 | router.get("/getmyjobs", isAuthenticated, getMyJobs); 17 | router.put("/update/:id", isAuthenticated, updateJob); 18 | router.delete("/delete/:id", isAuthenticated, deleteJob); 19 | router.get("/:id", isAuthenticated, getSingleJob); 20 | 21 | export default router; 22 | -------------------------------------------------------------------------------- /backend/routes/userRoutes.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { login, register, logout, getUser } from "../controllers/userController.js"; 3 | import { isAuthenticated } from "../middlewares/auth.js"; 4 | 5 | const router = express.Router(); 6 | 7 | router.post("/register", register); 8 | router.post("/login", login); 9 | router.get("/logout", isAuthenticated, logout); 10 | router.get("/getuser", isAuthenticated, getUser); 11 | 12 | export default router; 13 | -------------------------------------------------------------------------------- /backend/server.js: -------------------------------------------------------------------------------- 1 | import app from "./app.js"; 2 | import cloudinary from "cloudinary"; 3 | 4 | cloudinary.v2.config({ 5 | cloud_name: process.env.CLOUDINARY_CLOUD_NAME, // CLOUDINARY_CLIENT_NAME 6 | api_key: process.env.CLOUDINARY_API_KEY, // CLOUDINARY_CLIENT_API 7 | api_secret: process.env.CLOUDINARY_API_SECRET, // CLOUDINARY_CLIENT_SECRET 8 | }); 9 | 10 | app.listen(process.env.PORT, () => { 11 | console.log(`Server running at port ${process.env.PORT}`); 12 | }); 13 | -------------------------------------------------------------------------------- /backend/utils/jwtToken.js: -------------------------------------------------------------------------------- 1 | export const sendToken = (user, statusCode, res, message) => { 2 | const token = user.getJWTToken(); 3 | const options = { 4 | expires: new Date( 5 | Date.now() + process.env.COOKIE_EXPIRE * 24 * 60 * 60 * 1000 6 | ), 7 | httpOnly: true, // Set httpOnly to true 8 | }; 9 | 10 | res.status(statusCode).cookie("token", token, options).json({ 11 | success: true, 12 | user, 13 | message, 14 | token, 15 | }); 16 | }; 17 | -------------------------------------------------------------------------------- /frontend/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | CareerConnect: Find Top Talent and Hire the Best 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.6.5", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "react-hot-toast": "^2.4.1", 17 | "react-icons": "^4.12.0", 18 | "react-router-dom": "^6.21.1" 19 | }, 20 | "devDependencies": { 21 | "@types/react": "^18.2.43", 22 | "@types/react-dom": "^18.2.17", 23 | "@vitejs/plugin-react-swc": "^3.5.0", 24 | "eslint": "^8.55.0", 25 | "eslint-plugin-react": "^7.33.2", 26 | "eslint-plugin-react-hooks": "^4.6.0", 27 | "eslint-plugin-react-refresh": "^0.4.5", 28 | "vite": "^5.0.8" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /frontend/public/CVs/cv1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/CVs/cv1.jpg -------------------------------------------------------------------------------- /frontend/public/CVs/cv2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/CVs/cv2.jpg -------------------------------------------------------------------------------- /frontend/public/CVs/cv3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/CVs/cv3.jpg -------------------------------------------------------------------------------- /frontend/public/CVs/cv4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/CVs/cv4.jpg -------------------------------------------------------------------------------- /frontend/public/CVs/cv5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/CVs/cv5.jpg -------------------------------------------------------------------------------- /frontend/public/JobZee-logos__transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/JobZee-logos__transparent.png -------------------------------------------------------------------------------- /frontend/public/JobZee-logos__white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/JobZee-logos__white.png -------------------------------------------------------------------------------- /frontend/public/JobZeelogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/JobZeelogo.png -------------------------------------------------------------------------------- /frontend/public/careerconnect-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/careerconnect-black.png -------------------------------------------------------------------------------- /frontend/public/careerconnect-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/careerconnect-transparent.png -------------------------------------------------------------------------------- /frontend/public/careerconnect-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/careerconnect-white.png -------------------------------------------------------------------------------- /frontend/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/favicon.png -------------------------------------------------------------------------------- /frontend/public/heroS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/heroS.jpg -------------------------------------------------------------------------------- /frontend/public/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/login.png -------------------------------------------------------------------------------- /frontend/public/notfound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/notfound.png -------------------------------------------------------------------------------- /frontend/public/register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/exclusiveabhi/react-job-portal/e9aac2ad1ce96c550841bddebe2468e1c5340de3/frontend/public/register.png -------------------------------------------------------------------------------- /frontend/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | overflow-x: hidden; 8 | font-family: "Roboto", sans-serif; 9 | } 10 | ::-webkit-scrollbar { 11 | display: none; 12 | } 13 | h1 { 14 | font-size: 4rem; 15 | } 16 | h2 { 17 | font-size: 3.4rem; 18 | } 19 | h3 { 20 | font-size: 2.7rem; 21 | } 22 | h4 { 23 | font-size: 2.2rem; 24 | } 25 | h5 { 26 | font-size: 2rem; 27 | } 28 | h6 { 29 | font-size: 1.5rem; 30 | } 31 | p { 32 | font-size: 20px; 33 | } 34 | @media (max-width: 1520px) { 35 | h1 { 36 | font-size: 3.4rem; 37 | } 38 | h2 { 39 | font-size: 3rem; 40 | } 41 | h3 { 42 | font-size: 2.5rem; 43 | } 44 | h4 { 45 | font-size: 2rem; 46 | } 47 | h5 { 48 | font-size: 1.7rem; 49 | } 50 | h6 { 51 | font-size: 1.3rem; 52 | } 53 | } 54 | @media (max-width: 768px) { 55 | h1 { 56 | font-size: 2.6rem; 57 | } 58 | h2 { 59 | font-size: 2.3rem; 60 | } 61 | h3 { 62 | font-size: 2rem; 63 | } 64 | h4 { 65 | font-size: 1.8rem; 66 | } 67 | h5 { 68 | font-size: 1.45rem; 69 | } 70 | h6 { 71 | font-size: 1.15rem; 72 | } 73 | } 74 | 75 | .authPage { 76 | display: flex; 77 | min-width: 1500px; 78 | max-width: 1500px; 79 | margin: 0 auto; 80 | min-height: 100vh; 81 | } 82 | .authPage .container { 83 | flex: 1; 84 | display: flex; 85 | flex-direction: column; 86 | justify-content: center; 87 | background: #fff; 88 | padding: 20px 20px; 89 | } 90 | .authPage .container .header { 91 | display: flex; 92 | gap: 15px; 93 | flex-direction: column; 94 | } 95 | .authPage .container .header h3 { 96 | font-size: 1.6rem; 97 | } 98 | .authPage .container .header img { 99 | width: 190px; 100 | height: 120px; 101 | margin: 0 auto; 102 | } 103 | .authPage .container .header { 104 | text-align: center; 105 | margin-bottom: 30px; 106 | } 107 | .authPage .container form { 108 | display: flex; 109 | flex-direction: column; 110 | gap: 20px; 111 | } 112 | .authPage .container form .inputTag { 113 | display: flex; 114 | flex-direction: column; 115 | gap: 10px; 116 | } 117 | .authPage .container form .inputTag div { 118 | display: flex; 119 | align-items: center; 120 | border-radius: 7px; 121 | } 122 | .authPage .container form .inputTag div input, 123 | .authPage .container form .inputTag div select { 124 | background: #87878778; 125 | padding: 8px; 126 | border: none; 127 | width: 100%; 128 | height: 100%; 129 | } 130 | .authPage .container form .inputTag div input:focus, 131 | .authPage .container form .inputTag div select:focus { 132 | outline: none; 133 | } 134 | .authPage .container form .inputTag div svg { 135 | width: 10%; 136 | font-size: 1.5rem; 137 | background: #2d5649; 138 | height: 100%; 139 | padding: 8px; 140 | color: #fff; 141 | } 142 | .authPage .container form button { 143 | padding: 12px; 144 | text-align: center; 145 | border: none; 146 | margin-top: 25px; 147 | font-weight: 700; 148 | color: #fff; 149 | background: #2d5649; 150 | font-size: 1.2rem; 151 | border-radius: 7px; 152 | } 153 | .authPage .container form a { 154 | padding: 12px; 155 | text-align: center; 156 | border: 1px solid #2d5649; 157 | margin-top: 25px; 158 | font-weight: 700; 159 | color: #2d5649; 160 | font-size: 1.2rem; 161 | text-decoration: none; 162 | border-radius: 7px; 163 | } 164 | .authPage .banner { 165 | flex: 2; 166 | display: flex; 167 | justify-content: center; 168 | align-items: center; 169 | overflow-y: hidden; 170 | } 171 | .authPage .banner img { 172 | width: 100%; 173 | width: 550px; 174 | height: 550px; 175 | } 176 | @media (max-width: 1520px) { 177 | .authPage { 178 | min-width: 100%; 179 | } 180 | } 181 | @media (max-width: 830px) { 182 | .authPage { 183 | min-height: 100vh; 184 | height: auto; 185 | } 186 | .authPage .container { 187 | flex: none; 188 | width: 100%; 189 | justify-content: flex-start; 190 | padding: 40px 20px; 191 | } 192 | .authPage .banner { 193 | flex: none; 194 | display: none; 195 | } 196 | } 197 | 198 | .footerShow { 199 | background: #18191c; 200 | display: flex; 201 | justify-content: space-between; 202 | padding: 30px 120px; 203 | align-items: center; 204 | } 205 | .footerShow div { 206 | display: flex; 207 | gap: 12px; 208 | font-size: 16px; 209 | color: #f1f3f6; 210 | } 211 | .footerShow div a { 212 | font-size: 20px; 213 | text-decoration: none; 214 | color: #f1f3f6; 215 | } 216 | .footerShow div a:hover { 217 | color: #2d5649; 218 | transform: scale(1.2); 219 | transition: all 0.3s; 220 | } 221 | .footerHide { 222 | display: none; 223 | } 224 | @media (max-width: 830px) { 225 | .footerShow { 226 | padding: 25px 45px; 227 | } 228 | } 229 | @media (max-width: 550px) { 230 | .footerShow { 231 | flex-direction: column-reverse; 232 | gap: 25px; 233 | text-align: center; 234 | } 235 | } 236 | .navbarHide { 237 | display: none; 238 | } 239 | 240 | .heroSection { 241 | display: flex; 242 | flex-direction: column; 243 | padding: 75px 0 50px 0; 244 | } 245 | .heroSection .container, 246 | .heroSection .details { 247 | min-width: 1500px; 248 | max-width: 1500px; 249 | margin: 0 auto; 250 | } 251 | .heroSection .container { 252 | display: flex; 253 | height: 450px; 254 | margin-bottom: 1.75rem; 255 | } 256 | .heroSection .container .title, 257 | .heroSection .container .image { 258 | flex: 1; 259 | } 260 | .heroSection .container .title { 261 | display: flex; 262 | flex-direction: column; 263 | justify-content: center; 264 | } 265 | .heroSection .container .title h1 { 266 | max-width: 600px; 267 | } 268 | .heroSection .container .title p { 269 | margin-top: 1.5rem; 270 | max-width: 600px; 271 | } 272 | .heroSection .container .image { 273 | overflow: hidden; 274 | } 275 | .heroSection .container .image img { 276 | width: 100%; 277 | height: 100%; 278 | } 279 | .heroSection .details { 280 | display: flex; 281 | justify-content: space-between; 282 | padding: 50px 0; 283 | } 284 | .heroSection .details .card { 285 | display: flex; 286 | gap: 20px; 287 | align-items: center; 288 | background: #f1f3f6; 289 | width: 220px; 290 | padding: 10px 20px; 291 | } 292 | .heroSection .details .card .icon { 293 | font-size: 24px; 294 | background: rgb(233, 249, 255); 295 | display: flex; 296 | align-items: center; 297 | justify-content: center; 298 | padding: 10px; 299 | color: #2d5649; 300 | } 301 | .heroSection .details .card .content p:first-child { 302 | font-weight: bold; 303 | } 304 | .heroSection .details .card .content p:nth-child(2) { 305 | font-size: 14px; 306 | color: gray; 307 | margin-top: 5px; 308 | } 309 | .heroSection .details .card:hover { 310 | transition: all 0.3s; 311 | box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 312 | -webkit-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 313 | -moz-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 314 | } 315 | @media (max-width: 1520px) { 316 | .heroSection .container, 317 | .heroSection .details { 318 | min-width: 100%; 319 | padding: 20px; 320 | } 321 | } 322 | @media (max-width: 1000px) { 323 | .heroSection .container { 324 | flex-direction: column-reverse; 325 | position: relative; 326 | min-height: 600px; 327 | } 328 | .heroSection .container .title { 329 | z-index: 1; 330 | text-align: center; 331 | } 332 | .heroSection .container .title h1, 333 | .heroSection .container .title p { 334 | max-width: 100%; 335 | } 336 | .heroSection .container .image { 337 | position: absolute; 338 | top: 0; 339 | left: 0; 340 | opacity: 0.6; 341 | width: 100%; 342 | height: 100%; 343 | } 344 | } 345 | @media (max-width: 950px) { 346 | .heroSection .details { 347 | flex-wrap: wrap; 348 | gap: 30px; 349 | justify-content: space-evenly; 350 | } 351 | .heroSection .details .card { 352 | width: 300px; 353 | flex: none; 354 | } 355 | } 356 | @media (max-width: 670px) { 357 | .heroSection .details .card { 358 | max-width: 350px; 359 | min-width: 350px; 360 | } 361 | } 362 | @media (max-width: 400px) { 363 | .heroSection .details .card { 364 | min-width: 100%; 365 | max-width: 100%; 366 | } 367 | } 368 | .howitworks { 369 | background: #f1f3f6; 370 | } 371 | .howitworks .container { 372 | max-width: 1500px; 373 | min-width: 1500px; 374 | display: flex; 375 | flex-direction: column; 376 | margin: 0 auto; 377 | align-items: center; 378 | padding: 50px 0; 379 | gap: 50px; 380 | } 381 | .howitworks .container .banner { 382 | display: flex; 383 | justify-content: space-between; 384 | gap: 25px; 385 | } 386 | .howitworks .container .banner .card { 387 | background: #fff; 388 | display: flex; 389 | text-align: center; 390 | flex-direction: column; 391 | align-items: center; 392 | flex: 1; 393 | height: 350px; 394 | padding: 30px 50px; 395 | gap: 12px; 396 | justify-content: center; 397 | } 398 | .howitworks .container .banner .card:nth-child(2) { 399 | background: #18191c; 400 | color: #fff; 401 | } 402 | .howitworks .container .banner .card svg { 403 | font-size: 30px; 404 | color: #2d5649; 405 | } 406 | .howitworks .container .banner .card p:last-child { 407 | font-size: 14px; 408 | color: gray; 409 | } 410 | @media (max-width: 1520px) { 411 | .howitworks .container { 412 | min-width: 100%; 413 | padding: 50px 20px; 414 | } 415 | } 416 | @media (max-width: 850px) { 417 | .howitworks .container .banner { 418 | flex-wrap: wrap; 419 | justify-content: center; 420 | } 421 | .howitworks .container .banner .card { 422 | flex: none; 423 | width: 400px; 424 | height: 320px; 425 | } 426 | } 427 | @media (max-width: 480px) { 428 | .howitworks .container .banner .card { 429 | width: 100%; 430 | } 431 | } 432 | 433 | .categories { 434 | min-width: 1500px; 435 | max-width: 1500px; 436 | display: flex; 437 | flex-direction: column; 438 | margin: 0 auto; 439 | padding: 50px 0; 440 | gap: 35px; 441 | } 442 | .categories .banner { 443 | display: flex; 444 | flex-wrap: wrap; 445 | justify-content: space-between; 446 | gap: 35px; 447 | padding: 20px 0; 448 | } 449 | .categories .banner .card { 450 | width: 320px; 451 | background: red; 452 | padding: 20px; 453 | display: flex; 454 | align-items: center; 455 | gap: 12px; 456 | background: #f1f3f6; 457 | } 458 | .categories .banner .card:hover { 459 | transition: all 0.3s; 460 | box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 461 | -webkit-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 462 | -moz-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 463 | } 464 | .categories .banner .card .icon { 465 | font-size: 24px; 466 | padding: 10px; 467 | background: rgb(233, 249, 255); 468 | color: #2d5649; 469 | display: flex; 470 | align-items: center; 471 | justify-content: center; 472 | } 473 | .categories .banner .card .text p:nth-child(1) { 474 | font-size: 16px; 475 | font-weight: bold; 476 | } 477 | .categories .banner .card .text p:nth-child(2) { 478 | font-size: 14px; 479 | font-weight: 300; 480 | color: gray; 481 | } 482 | @media (max-width: 1520px) { 483 | .categories { 484 | min-width: 100%; 485 | padding: 50px 20px; 486 | } 487 | } 488 | @media (max-width: 714px) { 489 | .categories { 490 | align-items: center; 491 | } 492 | .categories .banner { 493 | justify-content: center; 494 | } 495 | } 496 | @media (max-width: 350px) { 497 | .categories .banner .card { 498 | width: 100%; 499 | } 500 | } 501 | 502 | .companies { 503 | background: #f1f3f6; 504 | padding: 50px 0; 505 | } 506 | .companies .container { 507 | min-width: 1500px; 508 | max-width: 1500px; 509 | margin: 0 auto; 510 | display: flex; 511 | flex-direction: column; 512 | align-items: center; 513 | gap: 35px; 514 | } 515 | .companies .container .banner { 516 | display: flex; 517 | justify-content: space-between; 518 | width: 100%; 519 | padding: 20px 0; 520 | } 521 | .companies .container .banner .card { 522 | width: 340px; 523 | display: flex; 524 | flex-direction: column; 525 | background: #fff; 526 | padding: 20px; 527 | gap: 15px; 528 | } 529 | .companies .container .banner .card:hover { 530 | transition: all 0.3s; 531 | box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 532 | -webkit-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 533 | -moz-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 534 | } 535 | .companies .container .banner .card .content { 536 | display: flex; 537 | align-items: center; 538 | gap: 15px; 539 | } 540 | .companies .container .banner .card .content .icon { 541 | padding: 10px; 542 | font-size: 24px; 543 | color: #2d5649; 544 | background: rgb(233, 249, 255); 545 | display: flex; 546 | justify-content: center; 547 | align-items: center; 548 | } 549 | .companies .container .banner .card .content .text p:first-child { 550 | font-weight: bold; 551 | margin-bottom: 5px; 552 | } 553 | .companies .container .banner .card .content .text p:last-child { 554 | font-size: 15px; 555 | color: gray; 556 | } 557 | .companies .container .banner .card button { 558 | color: #2d5649; 559 | background: rgb(233, 249, 255); 560 | font-weight: bold; 561 | font-size: 20px; 562 | border: none; 563 | padding: 7px 0; 564 | margin-top: 10px; 565 | } 566 | @media (max-width: 1520px) { 567 | .companies .container { 568 | min-width: 100%; 569 | padding: 0 20px; 570 | } 571 | } 572 | @media (max-width: 1100px) { 573 | .companies .container .banner { 574 | flex-direction: column; 575 | gap: 30px; 576 | align-items: center; 577 | } 578 | .companies .container .banner .card { 579 | width: 420px; 580 | } 581 | } 582 | @media (max-width: 470px) { 583 | .companies .container .banner .card { 584 | width: 100%; 585 | } 586 | } 587 | .jobs { 588 | background: #f1f3f6; 589 | min-height: 100vh; 590 | padding: 50px 20px; 591 | } 592 | .jobs .container { 593 | display: flex; 594 | flex-direction: column; 595 | align-items: center; 596 | min-width: 1500px; 597 | max-width: 1500px; 598 | margin: 0 auto; 599 | gap: 35px; 600 | } 601 | .jobs .container .banner { 602 | display: flex; 603 | flex-wrap: wrap; 604 | width: 100%; 605 | gap: 30px; 606 | justify-content: center; 607 | padding: 30px 0; 608 | } 609 | .jobs .container .banner .card { 610 | background: #fff; 611 | text-decoration: none; 612 | width: 320px; 613 | height: 220px; 614 | padding: 20px 20px; 615 | display: flex; 616 | flex-direction: column; 617 | gap: 10px; 618 | justify-content: center; 619 | } 620 | .jobs .container .banner .card:hover { 621 | transition: all 0.3s; 622 | box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 623 | -webkit-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 624 | -moz-box-shadow: 2px 10px 10px -1px rgba(0, 0, 0, 0.17); 625 | } 626 | .jobs .container .banner .card p:first-child { 627 | font-weight: bold; 628 | font-size: 1.6rem; 629 | } 630 | .jobs .container .banner .card p:nth-child(2) { 631 | font-size: 1.3rem; 632 | color: gray; 633 | } 634 | .jobs .container .banner .card p:last-child { 635 | font-size: 1rem; 636 | color: gray; 637 | } 638 | .jobs .container .banner .card a { 639 | text-decoration: none; 640 | padding: 7px; 641 | font-size: 20px; 642 | color: #2d5649; 643 | background: rgb(233, 249, 255); 644 | width: 100%; 645 | display: block; 646 | text-align: center; 647 | } 648 | @media (max-width: 1520px) { 649 | .jobs .container { 650 | min-width: 100%; 651 | } 652 | } 653 | @media (max-width: 1060px) { 654 | .jobs .container .banner .card { 655 | width: 360px; 656 | } 657 | } 658 | @media (max-width: 795px) { 659 | .jobs .container .banner .card { 660 | width: 100%; 661 | } 662 | } 663 | 664 | .jobDetail { 665 | background: #f1f3f6; 666 | padding: 50px 20px; 667 | } 668 | .jobDetail .container { 669 | max-width: 1500px; 670 | min-width: 1500px; 671 | margin: 0 auto; 672 | display: flex; 673 | flex-direction: column; 674 | align-items: center; 675 | } 676 | .jobDetail .container .banner { 677 | width: 100%; 678 | min-height: 767px; 679 | padding: 0px 25px; 680 | display: flex; 681 | flex-direction: column; 682 | gap: 25px; 683 | justify-content: center; 684 | } 685 | .jobDetail .container .banner p { 686 | font-weight: bold; 687 | color: #2d5649; 688 | } 689 | .jobDetail .container .banner p span { 690 | color: #18191c; 691 | font-weight: 400; 692 | } 693 | .jobDetail .container .banner a { 694 | background-color: #2d5649; 695 | color: rgb(233, 249, 255); 696 | font-size: 20px; 697 | font-weight: 400; 698 | border: none; 699 | padding: 12px 30px; 700 | text-decoration: none; 701 | margin-top: 10px; 702 | width: fit-content; 703 | } 704 | @media (max-width: 1520px) { 705 | .jobDetail .container { 706 | min-width: 100%; 707 | } 708 | } 709 | .application { 710 | display: flex; 711 | flex-direction: column; 712 | } 713 | .application .container { 714 | min-width: 1500px; 715 | max-width: 1500px; 716 | margin: 0 auto; 717 | display: flex; 718 | flex-direction: column; 719 | text-align: center; 720 | padding: 50px 20px; 721 | } 722 | .application .container form { 723 | display: flex; 724 | flex-direction: column; 725 | width: 550px; 726 | padding: 40px 20px; 727 | gap: 25px; 728 | margin: 0 auto; 729 | margin-top: 35px; 730 | } 731 | .application .container form input { 732 | border: none; 733 | font-size: 20px; 734 | border-bottom: 1px solid black; 735 | padding: 12px 4px; 736 | } 737 | .application .container form textarea { 738 | width: 100%; 739 | height: 200px; 740 | font-size: 20px; 741 | padding: 12px 4px; 742 | } 743 | .application .container form input:focus, 744 | .application .container form textarea:focus { 745 | outline: none; 746 | } 747 | .application .container form button { 748 | background-color: #2d5649; 749 | color: rgb(233, 249, 255); 750 | font-size: 20px; 751 | font-weight: 400; 752 | border: none; 753 | padding: 12px 30px; 754 | text-decoration: none; 755 | width: 100%; 756 | } 757 | .application .container form button:hover { 758 | background-color: #184235; 759 | transition: all 0.3s; 760 | cursor: pointer; 761 | } 762 | @media (max-width: 1520px) { 763 | .application .container { 764 | min-width: 100%; 765 | } 766 | .application .container form { 767 | width: 100%; 768 | } 769 | } 770 | .my_applications { 771 | background: #f1f3f6; 772 | padding: 50px 20px; 773 | min-height: 885px; 774 | } 775 | .my_applications .container { 776 | max-width: 1500px; 777 | min-width: 1500px; 778 | margin: 0 auto; 779 | display: flex; 780 | flex-direction: column; 781 | gap: 35px; 782 | } 783 | .job_seeker_card { 784 | display: flex; 785 | align-items: center; 786 | border-bottom: 1px solid gainsboro; 787 | padding: 20px 0; 788 | } 789 | .job_seeker_card .detail { 790 | flex: 3; 791 | display: flex; 792 | flex-direction: column; 793 | gap: 5px; 794 | } 795 | .job_seeker_card .detail { 796 | flex: 2; 797 | } 798 | .job_seeker_card .detail span { 799 | font-weight: bold; 800 | } 801 | .job_seeker_card .resume { 802 | flex: 1; 803 | display: flex; 804 | flex-direction: column; 805 | } 806 | .job_seeker_card .resume { 807 | position: relative; 808 | height: 250px; 809 | } 810 | .job_seeker_card .resume img { 811 | width: auto; 812 | height: 100%; 813 | position: absolute; 814 | top: 0; 815 | left: 0; 816 | } 817 | .job_seeker_card .btn_area { 818 | flex: 1; 819 | display: flex; 820 | align-items: center; 821 | justify-content: center; 822 | } 823 | .job_seeker_card .btn_area button { 824 | background: #d9534f; 825 | color: #fff; 826 | border: none; 827 | padding: 10px 30px; 828 | font-size: 20px; 829 | font-weight: 500; 830 | } 831 | @media (max-width: 1520px) { 832 | .my_applications .container { 833 | min-width: 100%; 834 | } 835 | } 836 | @media (max-width: 1150px) { 837 | .job_seeker_card .detail { 838 | flex: 1; 839 | } 840 | .job_seeker_card .resume { 841 | flex: 1; 842 | } 843 | .job_seeker_card .btn_area { 844 | flex: 1; 845 | } 846 | } 847 | @media (max-width: 850px) { 848 | .job_seeker_card { 849 | flex-direction: column; 850 | align-items: flex-start; 851 | } 852 | .job_seeker_card .detail { 853 | flex: none; 854 | } 855 | .job_seeker_card .resume { 856 | flex: none; 857 | width: 320px; 858 | margin: 30px 0; 859 | } 860 | .job_seeker_card .btn_area { 861 | flex: none; 862 | } 863 | } 864 | @media (max-width: 360px) { 865 | .job_seeker_card, 866 | .job_seeker_card .resume { 867 | width: 100%; 868 | } 869 | } 870 | 871 | .job_post { 872 | background: #f1f3f6; 873 | padding: 50px 20px; 874 | min-height: 870px; 875 | display: flex; 876 | align-items: center; 877 | } 878 | .job_post .container { 879 | max-width: 1500px; 880 | min-width: 1500px; 881 | display: flex; 882 | flex-direction: column; 883 | gap: 35px; 884 | align-items: center; 885 | margin: 0 auto; 886 | } 887 | .job_post .container form { 888 | width: 100%; 889 | display: flex; 890 | flex-direction: column; 891 | gap: 25px; 892 | } 893 | .job_post .container form .wrapper { 894 | display: flex; 895 | gap: 5vw; 896 | } 897 | .job_post .container form .wrapper input, 898 | .job_post .container form .wrapper select { 899 | flex: 1; 900 | font-size: 20px; 901 | padding: 7px 4px; 902 | border: none; 903 | background: transparent; 904 | border-bottom: 1px solid gray; 905 | } 906 | .job_post .container form input, 907 | .job_post .container form textarea { 908 | font-size: 20px; 909 | padding: 7px 4px; 910 | width: 100%; 911 | background: transparent; 912 | border: none; 913 | border-bottom: 1px solid gray; 914 | } 915 | .job_post .container form input:focus, 916 | .job_post .container form .wrapper input:focus, 917 | .job_post .container form .wrapper select:focus, 918 | .job_post .container form textarea:focus, 919 | .job_post .container form .salary_wrapper select:focus { 920 | outline: none; 921 | } 922 | .job_post .container form .salary_wrapper { 923 | display: flex; 924 | flex-direction: column; 925 | gap: 10px; 926 | } 927 | .job_post .container form .salary_wrapper p { 928 | color: #d9534f; 929 | font-size: 14px; 930 | font-weight: 300; 931 | } 932 | .job_post .container form .salary_wrapper select { 933 | width: fit-content; 934 | font-size: 20px; 935 | padding: 7px 4px; 936 | background: transparent; 937 | border: none; 938 | border-bottom: 1px solid gray; 939 | } 940 | .job_post .container form .salary_wrapper .ranged_salary { 941 | display: flex; 942 | gap: 5vw; 943 | } 944 | .job_post .container form button { 945 | width: 100%; 946 | background: #2d5649; 947 | font-size: 20px; 948 | padding: 10px 30px; 949 | border: none; 950 | color: #fff; 951 | text-transform: uppercase; 952 | font-weight: 600; 953 | letter-spacing: 2px; 954 | } 955 | @media (max-width: 1520px) { 956 | .job_post .container { 957 | min-width: 100%; 958 | } 959 | } 960 | @media (max-width: 630px) { 961 | .job_post .container { 962 | min-width: 100%; 963 | } 964 | .job_post .container form .wrapper, 965 | .job_post .container form .salary_wrapper, 966 | .job_post .container form .salary_wrapper .ranged_salary { 967 | flex-direction: column; 968 | gap: 20px; 969 | } 970 | .job_post .container form .salary_wrapper select { 971 | width: 100%; 972 | } 973 | } 974 | .myJobs { 975 | background: #f1f3f6; 976 | padding: 50px 20px; 977 | min-height: 870px; 978 | } 979 | .myJobs .container { 980 | min-width: 1500px; 981 | max-width: 1500px; 982 | /* margin-top: 50px; */ 983 | margin: 0 auto; 984 | align-items: center; 985 | display: flex; 986 | flex-direction: column; 987 | gap: 35px; 988 | } 989 | .myJobs .container .banner { 990 | width: 100%; 991 | display: flex; 992 | flex-wrap: wrap; 993 | gap: 20px; 994 | flex-direction: column; 995 | } 996 | .myJobs .container .banner .card { 997 | width: 100%; 998 | display: flex; 999 | gap: 20px; 1000 | border-bottom: 1px solid #18191c; 1001 | padding: 10px 0; 1002 | } 1003 | .myJobs .container .banner .card .content { 1004 | flex: 3; 1005 | display: flex; 1006 | gap: 20px; 1007 | } 1008 | .myJobs .container .banner .card .content span { 1009 | font-size: 20px; 1010 | margin-right: 6px; 1011 | font-weight: bold; 1012 | } 1013 | .myJobs .container .banner .card .content input, 1014 | .myJobs .container .banner .card .content select { 1015 | background: transparent; 1016 | font-size: 16px; 1017 | border: none; 1018 | color: #18191c; 1019 | padding: 7px 4px; 1020 | } 1021 | .myJobs .container .banner .card .content input:enabled, 1022 | .myJobs .container .banner .card .content select:enabled { 1023 | border-bottom: 1px solid gainsboro; 1024 | } 1025 | .myJobs .container .banner .card .content input:disabled, 1026 | .myJobs .container .banner .card .content select:disabled { 1027 | color: gray; 1028 | } 1029 | .myJobs .container .banner .card .content .short_fields { 1030 | flex: 1; 1031 | display: flex; 1032 | flex-direction: column; 1033 | gap: 20px; 1034 | } 1035 | .myJobs .container .banner .card .content .long_field { 1036 | flex: 2; 1037 | display: flex; 1038 | flex-direction: column; 1039 | gap: 20px; 1040 | } 1041 | .myJobs .container .banner .card .content .short_fields div, 1042 | .myJobs .container .banner .card .content .long_field div { 1043 | display: flex; 1044 | flex-direction: column; 1045 | gap: 10px; 1046 | } 1047 | .myJobs .container .banner .card .content .short_fields div div { 1048 | display: flex; 1049 | gap: 12px; 1050 | flex-direction: row; 1051 | } 1052 | .myJobs .container .banner .card .content .long_field textarea { 1053 | background: transparent; 1054 | font-size: 16px; 1055 | color: #18191c; 1056 | border: none; 1057 | padding: 7px 4px; 1058 | height: fit-content; 1059 | } 1060 | .myJobs .container .banner .card .content .long_field textarea:disabled { 1061 | color: gray; 1062 | } 1063 | .myJobs .container .banner .card .content .long_field textarea:enabled { 1064 | border-bottom: 1px solid gainsboro; 1065 | } 1066 | .myJobs .container .banner .card .content .long_field textarea:focus, 1067 | .myJobs .container .banner .card .content input:focus { 1068 | outline: none; 1069 | } 1070 | .myJobs .container .banner .card .button_wrapper { 1071 | flex: 1; 1072 | display: flex; 1073 | flex-direction: column; 1074 | gap: 20px; 1075 | align-items: center; 1076 | justify-content: center; 1077 | } 1078 | .myJobs .container .banner .card .button_wrapper .edit_btn, 1079 | .myJobs .container .banner .card .button_wrapper .delete_btn { 1080 | width: 120px; 1081 | color: #18191c; 1082 | font-size: 16px; 1083 | font-weight: 500; 1084 | text-transform: uppercase; 1085 | padding: 7px; 1086 | border: none; 1087 | background: #ffc107; 1088 | } 1089 | .myJobs .container .banner .card .button_wrapper .delete_btn { 1090 | background: #d9534f; 1091 | color: #f1f3f6; 1092 | } 1093 | .myJobs .container .banner .card .button_wrapper .check_btn { 1094 | background: transparent; 1095 | color: #184235; 1096 | border: 1px solid #184235; 1097 | border-radius: 7px; 1098 | width: 50px; 1099 | padding: 8px; 1100 | display: flex; 1101 | justify-content: center; 1102 | align-items: center; 1103 | font-size: 20px; 1104 | } 1105 | .myJobs .container .banner .card .button_wrapper .check_btn:hover { 1106 | transition: all 0.3s; 1107 | background: #184235; 1108 | color: #f1f3f6; 1109 | } 1110 | .myJobs .container .banner .card .button_wrapper .cross_btn { 1111 | background: transparent; 1112 | color: #d9534f; 1113 | border: 1px solid #d9534f; 1114 | border-radius: 7px; 1115 | width: 50px; 1116 | padding: 8px; 1117 | display: flex; 1118 | justify-content: center; 1119 | align-items: center; 1120 | font-size: 20px; 1121 | } 1122 | .myJobs .container .banner .card .button_wrapper .cross_btn:hover { 1123 | transition: all 0.3s; 1124 | background: #d9534f; 1125 | color: #f1f3f6; 1126 | } 1127 | .myJobs .container .banner .card .button_wrapper .edit_btn_wrapper { 1128 | gap: 20px; 1129 | display: flex; 1130 | } 1131 | @media (max-width: 1520px) { 1132 | .myJobs .container { 1133 | min-width: 100%; 1134 | margin-top: 50px; 1135 | } 1136 | } 1137 | @media (max-width: 830px) { 1138 | .myJobs .container .banner .card { 1139 | flex-direction: column; 1140 | } 1141 | .myJobs .container .banner .card .content { 1142 | flex-direction: column; 1143 | } 1144 | .myJobs .container .banner .card .content .long_field, 1145 | .myJobs .container .banner .card .content .short_fields { 1146 | gap: 8px; 1147 | } 1148 | .myJobs .container .banner .card .content .short_fields div, 1149 | .myJobs .container .banner .card .content .long_fields div { 1150 | gap: 8px; 1151 | } 1152 | } 1153 | nav { 1154 | background: #18191c; 1155 | padding: 0 20px; 1156 | } 1157 | nav .container { 1158 | max-width: 1500px; 1159 | min-width: 1500px; 1160 | margin: 0 auto; 1161 | display: flex; 1162 | justify-content: space-between; 1163 | } 1164 | nav .container .logo { 1165 | width: 120px; 1166 | height: 115px; 1167 | } 1168 | nav .container .logo img { 1169 | width: 100%; 1170 | height: 100%; 1171 | /* margin-left: 0px; */ 1172 | } 1173 | nav .menu { 1174 | display: flex; 1175 | gap: 25px; 1176 | align-items: center; 1177 | } 1178 | nav .menu button { 1179 | height: fit-content; 1180 | padding: 7px; 1181 | border: 1px solid #f1f3f6; 1182 | color: #f1f3f6; 1183 | background: transparent; 1184 | font-size: 20px; 1185 | font-weight: 300; 1186 | } 1187 | nav .menu button:hover { 1188 | color: #f1f3f6; 1189 | background: #184235; 1190 | transition: all 0.3s; 1191 | cursor: pointer; 1192 | font-weight: 500; 1193 | border: 1px solid #184235; 1194 | } 1195 | nav .menu li a { 1196 | color: #f1f3f6; 1197 | text-decoration: none; 1198 | font-weight: 300; 1199 | font-size: 20px; 1200 | position: relative; 1201 | } 1202 | nav .menu li a:hover { 1203 | color: #2d5649; 1204 | transition: all 0.3s; 1205 | } 1206 | nav .menu li a::before { 1207 | content: ""; 1208 | position: absolute; 1209 | background: #184235; 1210 | height: 1px; 1211 | width: 100%; 1212 | left: -100%; 1213 | bottom: 0; 1214 | transition: all 0.3s; 1215 | } 1216 | nav .menu li a:hover::before { 1217 | transition: all 0.3s; 1218 | left: 0; 1219 | } 1220 | nav .hamburger { 1221 | display: none; 1222 | } 1223 | @media (max-width: 1520px) { 1224 | nav .container { 1225 | min-width: 100%; 1226 | } 1227 | } 1228 | @media (max-width: 1130px) { 1229 | .page { 1230 | padding-top: 120px; 1231 | } 1232 | nav { 1233 | position: fixed; 1234 | width: 100%; 1235 | left: 0; 1236 | top: 0; 1237 | z-index: 10; 1238 | } 1239 | nav .hamburger { 1240 | display: block; 1241 | font-size: 35px; 1242 | color: #f1f3f6; 1243 | } 1244 | nav .container { 1245 | align-items: center; 1246 | } 1247 | .menu { 1248 | position: fixed; 1249 | top: 120px; 1250 | background: #f1f3f6; 1251 | left: -100%; 1252 | transition: all 0.3s; 1253 | width: 400px; 1254 | flex-direction: column; 1255 | height: 100%; 1256 | justify-content: center; 1257 | gap: 30px; 1258 | align-items: flex-start; 1259 | padding-left: 25px; 1260 | } 1261 | nav .show-menu { 1262 | position: fixed; 1263 | top: 120px; 1264 | background: #f1f3f6; 1265 | transition: all 0.3s; 1266 | left: 0; 1267 | width: 400px; 1268 | flex-direction: column; 1269 | height: 100%; 1270 | justify-content: center; 1271 | gap: 30px; 1272 | align-items: flex-start; 1273 | padding-left: 25px; 1274 | box-shadow: 9px 0px 16px 0px rgba(0, 0, 0, 0.75); 1275 | -webkit-box-shadow: 9px 0px 16px 0px rgba(0, 0, 0, 0.75); 1276 | -moz-box-shadow: 9px 0px 16px 0px rgba(0, 0, 0, 0.75); 1277 | } 1278 | nav .show-menu li a { 1279 | color: #184235; 1280 | font-weight: 600; 1281 | } 1282 | nav .show-menu button { 1283 | color: #184235; 1284 | border: 1px solid #184235; 1285 | font-weight: 600; 1286 | } 1287 | nav .show-menu button:hover { 1288 | background: #18191c; 1289 | color: #f1f3f6; 1290 | } 1291 | } 1292 | @media (max-width: 490px) { 1293 | nav .menu { 1294 | width: 100%; 1295 | } 1296 | } 1297 | .notfound { 1298 | min-height: 750px; 1299 | } 1300 | .notfound .content { 1301 | display: flex; 1302 | flex-direction: column; 1303 | align-items: center; 1304 | } 1305 | .notfound .content a { 1306 | font-size: 20px; 1307 | font-weight: 500; 1308 | padding: 7px 30px; 1309 | background: transparent; 1310 | border: 1px solid #184235; 1311 | color: #184235; 1312 | text-decoration: none; 1313 | } 1314 | .notfound .content a:hover { 1315 | background: #184235; 1316 | transition: all 0.3s; 1317 | color: #f1f3f6; 1318 | } 1319 | .resume-modal { 1320 | width: 100%; 1321 | display: flex; 1322 | background: #00000085; 1323 | height: 100%; 1324 | position: fixed; 1325 | top: 0; 1326 | left: 0; 1327 | } 1328 | .resume-modal .modal-content { 1329 | width: 100%; 1330 | height: 100%; 1331 | display: flex; 1332 | align-items: center; 1333 | justify-content: center; 1334 | position: relative; 1335 | } 1336 | .resume-modal .modal-content .close { 1337 | position: absolute; 1338 | right: 36px; 1339 | top: 35px; 1340 | font-size: 50px; 1341 | color: #d9534f; 1342 | } 1343 | .resume-modal .modal-content .close:hover { 1344 | cursor: pointer; 1345 | } 1346 | .resume-modal .modal-content img { 1347 | max-width: 550px; 1348 | height: auto; 1349 | } 1350 | @media (max-width: 1130px) { 1351 | .resume-modal { 1352 | z-index: 11; 1353 | } 1354 | } -------------------------------------------------------------------------------- /frontend/src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useEffect } from "react"; 2 | import "./App.css"; 3 | import { Context } from "./main"; 4 | import { BrowserRouter, Route, Routes } from "react-router-dom"; 5 | import Login from "./components/Auth/Login"; 6 | import Register from "./components/Auth/Register"; 7 | import { Toaster } from "react-hot-toast"; 8 | import axios from "axios"; 9 | import Navbar from "./components/Layout/Navbar"; 10 | import Footer from "./components/Layout/Footer"; 11 | import Home from "./components/Home/Home"; 12 | import Jobs from "./components/Job/Jobs"; 13 | import JobDetails from "./components/Job/JobDetails"; 14 | import Application from "./components/Application/Application"; 15 | import MyApplications from "./components/Application/MyApplications"; 16 | import PostJob from "./components/Job/PostJob"; 17 | import NotFound from "./components/NotFound/NotFound"; 18 | import MyJobs from "./components/Job/MyJobs"; 19 | 20 | const App = () => { 21 | const { isAuthorized, setIsAuthorized, setUser } = useContext(Context); 22 | useEffect(() => { 23 | const fetchUser = async () => { 24 | try { 25 | const response = await axios.get( 26 | "http://localhost:4000/api/v1/user/getuser", 27 | { 28 | withCredentials: true, 29 | } 30 | ); 31 | setUser(response.data.user); 32 | setIsAuthorized(true); 33 | } catch (error) { 34 | setIsAuthorized(false); 35 | } 36 | }; 37 | fetchUser(); 38 | }, [isAuthorized]); 39 | 40 | return ( 41 | <> 42 | 43 | 44 | 45 | } /> 46 | } /> 47 | } /> 48 | } /> 49 | } /> 50 | } /> 51 | } /> 52 | } /> 53 | } /> 54 | } /> 55 | 56 |