diff --git a/controller/adminController.js b/controller/adminController.js index 38cb6a1..61a0ebd 100644 --- a/controller/adminController.js +++ b/controller/adminController.js @@ -1,349 +1,414 @@ const { ErrorHandler } = require("../middleware/errors"); -const {User,Admin,Item} = require('../models'); -const bcrypt = require('bcrypt'); -const jwt = require('jsonwebtoken'); -const allstatus = require('../utils/allstatus'); -require('dotenv').config(); - - +const { User, Admin, Item } = require("../models"); +const bcrypt = require("bcrypt"); +const jwt = require("jsonwebtoken"); +const allstatus = require("../utils/allstatus"); +require("dotenv").config(); const createAccessToken = (user) => { - return jwt.sign(user, process.env.ADMIN_JWT_ACCESS_KEY, { expiresIn: process.env.ADMIN_JWT_ACCESS_EXP }); + return jwt.sign(user, process.env.ADMIN_JWT_ACCESS_KEY, { + expiresIn: process.env.ADMIN_JWT_ACCESS_EXP, + }); }; -const refreshToken = (req, res,next) => { - try { - const rf_token = req.body.refreshtoken; - if (!rf_token) - return next(new ErrorHandler(400,"Please Login or Register")); +const refreshToken = (req, res, next) => { + try { + const rf_token = req.body.refreshtoken; + if (!rf_token) + return next(new ErrorHandler(400, "Please Login or Register")); - jwt.verify(rf_token, process.env.ADMIN_JWT_REFRESH_KEY, (err, user) => { - if (err) return next(new ErrorHandler(401,"Invalid Authentication")); + jwt.verify(rf_token, process.env.ADMIN_JWT_REFRESH_KEY, (err, user) => { + if (err) return next(new ErrorHandler(401, "Invalid Authentication")); - const accesstoken = createAccessToken({ id: user._id }); + const accesstoken = createAccessToken({ id: user._id }); - return res.status(200).json({ accesstoken }); - }); - } catch (err) { - next(err); - } -} + return res.status(200).json({ accesstoken }); + }); + } catch (err) { + next(err); + } +}; -const login = async (req,res,next) => { - try { - const {uname,password} = req.body; +const login = async (req, res, next) => { + try { + const { uname, password } = req.body; - if(!uname||!password) - return next(new ErrorHandler(406,"uname and password input required")); - - const admin = await Admin.findOne({ uname }); - if (!admin) - return next(new ErrorHandler(404,"User Not Found")); - - const result = await bcrypt.compare(password, admin.password); - if (!result) return next(new ErrorHandler(400,"Invalid Credentials")); - - const accessToken = createAccessToken({ id: admin._id }); - - const refreshToken = jwt.sign({ - id: admin._id, - }, process.env.ADMIN_JWT_REFRESH_KEY, { expiresIn: process.env.ADMIN_JWT_REFRESH_EXP }); - return res.status(200).json({success:true, accessToken , refreshToken}); + if (!uname || !password) + return next(new ErrorHandler(406, "uname and password input required")); - } catch (err) { - return next(err); - } -} + const admin = await Admin.findOne({ uname }); + if (!admin) return next(new ErrorHandler(404, "User Not Found")); -const itemlist = async (req,res,next) => { - try { - const status = req.query.status || 'ALL'; - let page = parseInt(req.query.page) || 1; - let limit = parseInt(req.query.limit) || 10; - if(page<=0) page = 1; - page = page - 1; - if(limit<0) limit = 0; - if(!allstatus.includes(status)) - return next(new ErrorHandler(406,'Invalid status value')); - let items = (status!=='ALL') ? await Item.aggregate([ - { - $match: { - status: status - } - }, - { - $facet: { - count: [ - { $count: "total" } - ], - results: [ - { $skip: page * limit }, - { $limit: limit }, - { $lookup: { from: "users", localField: "user", foreignField: "_id", as: "user" } }, - { $unwind: "$user" }, - { $project: { "user.password": 0, "user.items": 0 } } - ] - } - }, - { - $unwind: "$count" - }, - { - $project: { - results: 1, - count: "$count.total" - } - } - ]) - : await Item.aggregate([ - { - $facet: { - count: [ - { $count: "total" } - ], - results: [ - { $skip: page * limit }, - { $limit: limit }, - { $lookup: { from: "users", localField: "user", foreignField: "_id", as: "user" } }, - { $unwind: "$user" }, - { $project: { "user.password": 0, "user.items": 0 } } - ] - } - }, - { - $unwind: "$count" - }, - { - $project: { - results: 1, - count: "$count.total" - } - } - ]); + const result = await bcrypt.compare(password, admin.password); + if (!result) return next(new ErrorHandler(400, "Invalid Credentials")); - const totalCount = items.length > 0 ? items[0].count : 0; - const paginatedResults = items.length > 0 ? items[0].results : []; - return res.status(200).json({success:true,pages:Math.ceil(totalCount/limit)||0,items:paginatedResults}); - - } catch (err) { - return next(err); - } -} - -const changeStatus = async (req,res,next) => { - try { - const {itemId} = req.params; - const {status} = req.body; - if(!status) - return next(new ErrorHandler(400,"Input required -> status")); - if(allstatus.includes(status)===false && status!='ALL') - return next(new ErrorHandler(406,`Invalid status value : can only be ${[...allstatus]}`)); - const updateStatus = await Item.findByIdAndUpdate(itemId,{ - status - }); - if(!updateStatus) - return next(new ErrorHandler(404,'Item not found')); - return res.status(200).json({success:true,msg:`Updated item status to ${status}`}); - } catch (err) { - return next(err); - } -} -const toggleCollector = async (req,res,next) => { - try{ - const {email} = req.body; - if(!email) - return next(new ErrorHandler(400,"Input required -> email")); - const user = await User.findOne({email:email}); - if(!user) - return next(new ErrorHandler(400,"User Does Not Exist")); - if(user.role==='COLLECTOR'){ - user.role='USER'; - await user.save(); - return res.status(200).json({success:true,msg:'Converted to USER role'}); - } - else{ - user.role='COLLECTOR'; - await user.save(); - return res.status(200).json({success:true,msg:'Converted to COLLECTOR role'}); - } - - } catch(err) { - return next(err); - } -} + const accessToken = createAccessToken({ id: admin._id }); -const seeAllUsers = async (req,res,next) => { - try { - const role = req.query.role || 'ALL'; - - if(role!='USER'&&role!='COLLECTOR'&&role!='ALL') - return next(new ErrorHandler(400,"Invalid role must be -> USER or COLLECTOR or ALL")); - - let page = parseInt(req.query.page) || 1; - let limit = parseInt(req.query.limit) || 10; - if(page<=0) page = 1; - page = page - 1; - if(limit<0) limit = 0; + const refreshToken = jwt.sign( + { + id: admin._id, + }, + process.env.ADMIN_JWT_REFRESH_KEY, + { expiresIn: process.env.ADMIN_JWT_REFRESH_EXP } + ); + return res.status(200).json({ success: true, accessToken, refreshToken }); + } catch (err) { + return next(err); + } +}; - let users = (role==='ALL')? - await User.aggregate([ +const itemlist = async (req, res, next) => { + try { + const status = req.query.status || "ALL"; + let page = parseInt(req.query.page) || 1; + let limit = parseInt(req.query.limit) || 10; + if (page <= 0) page = 1; + page = page - 1; + if (limit < 0) limit = 0; + if (!allstatus.includes(status)) + return next(new ErrorHandler(406, "Invalid status value")); + let items = + status !== "ALL" + ? await Item.aggregate([ + { + $match: { + status: status, + }, + }, { $facet: { - count: [ - { $count: "total" } - ], + count: [{ $count: "total" }], results: [ { $skip: page * limit }, { $limit: limit }, - { $project: { password: 0, items: 0 } } - ] - } + { + $lookup: { + from: "users", + localField: "user", + foreignField: "_id", + as: "user", + }, + }, + { $unwind: "$user" }, + { $project: { "user.password": 0, "user.items": 0 } }, + ], + }, }, { - $unwind: "$count" + $unwind: "$count", }, { $project: { results: 1, - count: "$count.total" - } - } - ]): - await User.aggregate([ - { - $match: { - role: role - } + count: "$count.total", + }, }, + ]) + : await Item.aggregate([ { $facet: { - count: [ - { $count: "total" } - ], + count: [{ $count: "total" }], results: [ { $skip: page * limit }, { $limit: limit }, - { $project: { password: 0, items: 0 } } - ] - } + { + $lookup: { + from: "users", + localField: "user", + foreignField: "_id", + as: "user", + }, + }, + { $unwind: "$user" }, + { $project: { "user.password": 0, "user.items": 0 } }, + ], + }, }, { - $unwind: "$count" + $unwind: "$count", }, { $project: { results: 1, - count: "$count.total" - } - } + count: "$count.total", + }, + }, ]); - - const totalCount = users.length > 0 ? users[0].count : 0; - const paginatedResults = users.length > 0 ? users[0].results : []; - return res.status(200).json({success:true,pages:Math.ceil(totalCount/limit),users:paginatedResults}); + const totalCount = items.length > 0 ? items[0].count : 0; + const paginatedResults = items.length > 0 ? items[0].results : []; + return res + .status(200) + .json({ + success: true, + pages: Math.ceil(totalCount / limit) || 0, + items: paginatedResults, + }); + } catch (err) { + return next(err); + } +}; - } catch (err) { - return next(err); +const changeStatus = async (req, res, next) => { + try { + const { itemId } = req.params; + const { status } = req.body; + if (!status) return next(new ErrorHandler(400, "Input required -> status")); + if ( + allstatus.includes(status) === false && + status != "ALL" && + status != "DONATED" + ) + return next( + new ErrorHandler( + 406, + `Invalid status value : can only be ${[...allstatus]}` + ) + ); + const updateStatus = await Item.findByIdAndUpdate(itemId, { + status, + }); + if (!updateStatus) return next(new ErrorHandler(404, "Item not found")); + return res + .status(200) + .json({ success: true, msg: `Updated item status to ${status}` }); + } catch (err) { + return next(err); + } +}; + +const donateItem = async (req, res, next) => { + try { + const { itemId } = req.params; + const { name, email } = req.body; + if (!name) return next(new ErrorHandler(400, "Input required -> name")); + const updateStatus = await Item.findByIdAndUpdate(itemId, { + status: "DONATED", + acceptedBy: { name, email }, + }); + if (!updateStatus) return next(new ErrorHandler(404, "Item not found")); + return res + .status(200) + .json({ success: true, msg: `Updated item status to DONATED` }); + } catch (err) { + return next(err); + } +}; + +const toggleCollector = async (req, res, next) => { + try { + const { email } = req.body; + if (!email) return next(new ErrorHandler(400, "Input required -> email")); + const user = await User.findOne({ email: email }); + if (!user) return next(new ErrorHandler(400, "User Does Not Exist")); + if (user.role === "COLLECTOR") { + user.role = "USER"; + await user.save(); + return res + .status(200) + .json({ success: true, msg: "Converted to USER role" }); + } else { + user.role = "COLLECTOR"; + await user.save(); + return res + .status(200) + .json({ success: true, msg: "Converted to COLLECTOR role" }); } -} + } catch (err) { + return next(err); + } +}; -const allCollectedItems = async (req,res,next) => { - try { - let page = parseInt(req.query.page) || 1; - let limit = parseInt(req.query.limit) || 10; - if(page<=0) page = 1; - page = page - 1; - if(limit<0) limit = 0; - const items = await await Item.aggregate([ - // Match the desired conditions using $match and $regex +const seeAllUsers = async (req, res, next) => { + try { + const role = req.query.role || "ALL"; + + if (role != "USER" && role != "COLLECTOR" && role != "ALL") + return next( + new ErrorHandler( + 400, + "Invalid role must be -> USER or COLLECTOR or ALL" + ) + ); + + let page = parseInt(req.query.page) || 1; + let limit = parseInt(req.query.limit) || 10; + if (page <= 0) page = 1; + page = page - 1; + if (limit < 0) limit = 0; + + let users = + role === "ALL" + ? await User.aggregate([ + { + $facet: { + count: [{ $count: "total" }], + results: [ + { $skip: page * limit }, + { $limit: limit }, + { $project: { password: 0, items: 0 } }, + ], + }, + }, + { + $unwind: "$count", + }, + { + $project: { + results: 1, + count: "$count.total", + }, + }, + ]) + : await User.aggregate([ { $match: { - status: { $regex: /^COLLECTED_.*$/ } - } + role: role, + }, }, - // Count the total documents { $facet: { - count: [ - { $count: "total" } - ], + count: [{ $count: "total" }], results: [ - // Apply pagination { $skip: page * limit }, { $limit: limit }, - // Populate the 'user' field while excluding 'password' and 'items' - { $lookup: { from: "users", localField: "user", foreignField: "_id", as: "user" } }, - { $unwind: "$user" }, - { $project: { "user.password": 0, "user.items": 0 } } - ] - } + { $project: { password: 0, items: 0 } }, + ], + }, }, - // Unwind the count facet and project the result { - $unwind: "$count" + $unwind: "$count", }, { $project: { results: 1, - count: "$count.total" - } - } + count: "$count.total", + }, + }, ]); - const totalCount = items.length > 0 ? items[0].count : 0; - const paginatedResults = items.length > 0 ? items[0].results : []; - res.status(200).json({success:true,pages:Math.ceil(totalCount/limit),items:paginatedResults}); - } catch (err) { - next(err); - } -} -const highestDonor = async (req,res,next) => { - try { - const topDonors = await User.aggregate([ + const totalCount = users.length > 0 ? users[0].count : 0; + const paginatedResults = users.length > 0 ? users[0].results : []; + + return res + .status(200) + .json({ + success: true, + pages: Math.ceil(totalCount / limit), + users: paginatedResults, + }); + } catch (err) { + return next(err); + } +}; + +const allCollectedItems = async (req, res, next) => { + try { + let page = parseInt(req.query.page) || 1; + let limit = parseInt(req.query.limit) || 10; + if (page <= 0) page = 1; + page = page - 1; + if (limit < 0) limit = 0; + const items = await await Item.aggregate([ + // Match the desired conditions using $match and $regex + { + $match: { + status: { $regex: /^COLLECTED_.*$/ }, + }, + }, + // Count the total documents + { + $facet: { + count: [{ $count: "total" }], + results: [ + // Apply pagination + { $skip: page * limit }, + { $limit: limit }, + // Populate the 'user' field while excluding 'password' and 'items' { $lookup: { - from: "items", - localField: "items", + from: "users", + localField: "user", foreignField: "_id", - as: "populatedItems" - } - }, - { - $addFields: { - donated_count: { - $size: { - $filter: { - input: "$populatedItems", - as: "item", - cond: { $eq: ["$$item.status", "DONATED"] } - } - } - } - } + as: "user", + }, }, - { - $project: { - _id: 0, - name: 1, - email: 1, - donated_count: 1 - } - }, - { - $sort: { - donated_count: -1 - } + { $unwind: "$user" }, + { $project: { "user.password": 0, "user.items": 0 } }, + ], + }, + }, + // Unwind the count facet and project the result + { + $unwind: "$count", + }, + { + $project: { + results: 1, + count: "$count.total", + }, + }, + ]); + const totalCount = items.length > 0 ? items[0].count : 0; + const paginatedResults = items.length > 0 ? items[0].results : []; + res + .status(200) + .json({ + success: true, + pages: Math.ceil(totalCount / limit), + items: paginatedResults, + }); + } catch (err) { + next(err); + } +}; + +const highestDonor = async (req, res, next) => { + try { + const topDonors = await User.aggregate([ + { + $lookup: { + from: "items", + localField: "items", + foreignField: "_id", + as: "populatedItems", + }, + }, + { + $addFields: { + donated_count: { + $size: { + $filter: { + input: "$populatedItems", + as: "item", + cond: { $eq: ["$$item.status", "DONATED"] }, + }, }, - { - $limit: 5 - } - ]); - res.status(200).json({success:true,topDonors}); - } catch (err) { - next(err); - } -} + }, + }, + }, + { + $project: { + _id: 0, + name: 1, + email: 1, + donated_count: 1, + }, + }, + { + $sort: { + donated_count: -1, + }, + }, + { + $limit: 5, + }, + ]); + res.status(200).json({ success: true, topDonors }); + } catch (err) { + next(err); + } +}; // const create = async (req,res,next) => { // try { @@ -362,19 +427,18 @@ const highestDonor = async (req,res,next) => { // } // } - module.exports = { - refreshToken, - login, - itemlist, - // create, - changeStatus, - toggleCollector, - seeAllUsers, - allCollectedItems, - highestDonor, -} - + refreshToken, + login, + itemlist, + // create, + changeStatus, + toggleCollector, + seeAllUsers, + allCollectedItems, + highestDonor, + donateItem, +}; // Admin Side: To see the highest donator -// Admin Side: To see all the items and their history of donation and all \ No newline at end of file +// Admin Side: To see all the items and their history of donation and all diff --git a/controller/authController.js b/controller/authController.js index 67ffd0b..1547403 100644 --- a/controller/authController.js +++ b/controller/authController.js @@ -1,366 +1,404 @@ -const jwt = require('jsonwebtoken'); +const jwt = require("jsonwebtoken"); const bcrypt = require("bcrypt"); -const otpGenerator = require('otp-generator'); +const otpGenerator = require("otp-generator"); const mailer = require("../utils/mailer"); -require('dotenv').config(); -const {User,Otp} = require("../models"); -const { ErrorHandler } = require('../middleware/errors'); -const {validatemail,validatepass} = require('../utils/validation'); - -const home = async (req,res,next) => { - const data = {msg:"Samriddhi Prawah!",pid:`${process.pid}`}; - try { - res.json(data); - } catch (err) { - next(err) - } -} +require("dotenv").config(); +const { User, Otp } = require("../models"); +const { ErrorHandler } = require("../middleware/errors"); +const { validatemail, validatepass } = require("../utils/validation"); + +const home = async (req, res, next) => { + const data = { msg: "Samriddhi Prawah!", pid: `${process.pid}` }; + try { + res.json(data); + } catch (err) { + next(err); + } +}; const createAccessToken = (user) => { - return jwt.sign(user, process.env.JWT_ACCESS_KEY, { expiresIn: process.env.JWT_ACCESS_EXP }); + return jwt.sign(user, process.env.JWT_ACCESS_KEY, { + expiresIn: process.env.JWT_ACCESS_EXP, + }); }; -const refreshToken = (req, res,next) => { - try { - const rf_token = req.body.refreshtoken; - if (!rf_token) - return next(new ErrorHandler(400,"Please Login or Register")); +const refreshToken = (req, res, next) => { + try { + const rf_token = req.body.refreshtoken; + if (!rf_token) + return next(new ErrorHandler(400, "Please Login or Register")); - jwt.verify(rf_token, process.env.JWT_REFRESH_KEY, (err, user) => { - if (err) return next(new ErrorHandler(401,"Invalid Authentication")); + jwt.verify(rf_token, process.env.JWT_REFRESH_KEY, (err, user) => { + if (err) return next(new ErrorHandler(401, "Invalid Authentication")); - const accesstoken = createAccessToken({ id: user._id }); + const accesstoken = createAccessToken({ id: user._id }); - return res.status(200).json({ accesstoken }); - }); - } catch (err) { - next(err); - } -} + return res.status(200).json({ accesstoken }); + }); + } catch (err) { + next(err); + } +}; const login = async (req, res, next) => { - try{ - // Destructuring username & password from body - let { email, password } = req.body; - email = email.toLowerCase(); - const user = await User.findOne({ email }); - if (!user) - return next(new ErrorHandler(404,"User Not Found")); - if (!user.verify) - return next(new ErrorHandler(404,"User Not Found")); - const result = await bcrypt.compare(password, user.password); - if (!result) return next(new ErrorHandler(400,"Invalid Credentials")); - - const accessToken = createAccessToken({ id: user._id }); - - const refreshToken = jwt.sign({ - id: user._id, - }, process.env.JWT_REFRESH_KEY, { expiresIn: process.env.JWT_REFRESH_EXP }); - return res.status(200).json({success:true, accessToken , refreshToken}); - }catch(err){ - next(err); + try { + // Destructuring username & password from body + let { email, password } = req.body; + email = email.toLowerCase(); + const user = await User.findOne({ email }); + if (!user) return next(new ErrorHandler(404, "User Not Found")); + if (!user.verify) return next(new ErrorHandler(404, "User Not Found")); + const result = await bcrypt.compare(password, user.password); + if (!result) return next(new ErrorHandler(400, "Invalid Credentials")); + + const accessToken = createAccessToken({ id: user._id }); + + const refreshToken = jwt.sign( + { + id: user._id, + }, + process.env.JWT_REFRESH_KEY, + { expiresIn: process.env.JWT_REFRESH_EXP } + ); + return res.status(200).json({ success: true, accessToken, refreshToken }); + } catch (err) { + next(err); + } +}; + +const email = async (req, res, next) => { + try { + const { email } = req.body; + + if (!email) return next(new ErrorHandler(400, "Email Required.")); + if (!validatemail(email)) + return next(new ErrorHandler(406, "Incorrect Email format.")); + + const oldUser = await User.findOne({ + email: email.toLowerCase(), + }); + + if (oldUser && oldUser.verify == true) + return next(new ErrorHandler(400, "User by this email already exists.")); + + const mailedOTP = otpGenerator.generate(6, { + upperCaseAlphabets: false, + specialChars: false, + lowerCaseAlphabets: false, + }); + + mailer.sendmail(email, mailedOTP); + + const oldotp = await Otp.findOne({ email }); + + if (oldotp) { + let dateNow = new Date(); + dateNow = dateNow.getTime() / 1000; + let otpDate = new Date(oldotp.updatedAt); + otpDate = otpDate.getTime() / 1000; + console.log(dateNow, otpDate); + if (dateNow < otpDate + 10) + return next( + new ErrorHandler(400, "Wait for 10 seconds to resend mail.") + ); + oldotp.otp = mailedOTP; + oldotp.used = false; + await oldotp.save(); + } else { + await Otp.create({ + email: email.toLowerCase(), + otp: mailedOTP, + }); } -} - -const email = async (req,res,next) => { - try { - const {email} = req.body; - - if(!email) - return next(new ErrorHandler(400,"Email Required.")); - if(!validatemail(email)) - return next(new ErrorHandler(406,"Incorrect Email format.")); - - const oldUser = await User.findOne({ - email:email.toLowerCase() - }); - - if(oldUser&&oldUser.verify==true) - return next(new ErrorHandler(400,"User by this email already exists.")); - - const mailedOTP = otpGenerator.generate(6, { - upperCaseAlphabets: false, - specialChars: false, - lowerCaseAlphabets: false - }); - - mailer.sendmail(email,mailedOTP); - - const oldotp = await Otp.findOne({email}); - - if(oldotp){ - let dateNow = new Date(); - dateNow = dateNow.getTime()/1000; - let otpDate = new Date(oldotp.updatedAt); - otpDate = otpDate.getTime()/1000; - console.log(dateNow,otpDate) - if(dateNow { + try { + const { email, otp } = req.body; + if (!email) { + return next(new ErrorHandler(400, "Email Required.")); } -} - -const everify = async (req,res,next) => { - try { - const {email,otp} = req.body; - if(!email){ - return next(new ErrorHandler(400,"Email Required.")); - } - if (!otp) { - return next(new ErrorHandler(400,"Otp Required.")); - } - const otpdb = await Otp.findOne({ - email:email.toLowerCase() - }); - if(!otpdb||(otpdb&&otpdb.used)) - return next(new ErrorHandler(400,"Otp expired.")); - - if(otpdb.otp!=otp){ - console.log(otpdb.otp,otp); - return next(new ErrorHandler(400,"Incorrect Otp")); - } - otpdb.used=true; - await otpdb.save(); - const prev = await User.findOne({ - email:email.toLowerCase() - }) - let user; - if(!prev){ - user = await User.create({ - email:email.toLowerCase() - }); - }else{ - user = prev; - } - console.log(user); - const token = jwt.sign({_id:user._id},process.env.JWT_TOKEN,{expiresIn:'30m'}); - if(user) - return res.status(200).json({success:true,msg:'OTP Verified.',token}); - - } catch (err) { - next(err); + if (!otp) { + return next(new ErrorHandler(400, "Otp Required.")); } -} - - -const signup = async (req,res,next)=>{ - try{ - const { - name, - gender, - student_no, - year, - course, - branch, - POR, - password, - phone_no - } = req.body; - - let user = req.user; - if(user.verify==true) - return next(new ErrorHandler(400,"Account already made")); - if (!(name&&student_no&&year&&branch&&POR&&password&&phone_no&&gender)) { - return next(new ErrorHandler(400,"All input fields are required.")); - } - - if(!validatepass(password)){ - return next(new ErrorHandler(400,"Incorrect Password Format")); - } - - if(phone_no.length<10||!(phone_no.match(/^[0-9]+$/))){ - return next(new ErrorHandler(400,"Invalid phone number")); - } - - const encryptedPassword = await bcrypt.hash(password, 12); - - user.name = name; - user.student_no = student_no, - user.year = year; - user.course = course; - user.branch = branch; - user.POR = POR; - user.password = encryptedPassword; - user.phone_no = phone_no; - user.gender = gender; - user.verify = true; - - user = await user.save(); - - const accessToken = createAccessToken({ id: user._id }); - - const refreshToken = jwt.sign({ - id: user._id, - }, process.env.JWT_REFRESH_KEY, { expiresIn: process.env.JWT_REFRESH_EXP }); - return res.status(200).json({success:true,msg:`Welcome to Samriddhi Prawah, ${name}!`,user,refreshToken,accessToken}); - - } catch (err) { - next(err); + const otpdb = await Otp.findOne({ + email: email.toLowerCase(), + }); + if (!otpdb || (otpdb && otpdb.used)) + return next(new ErrorHandler(400, "Otp expired.")); + + if (otpdb.otp != otp) { + console.log(otpdb.otp, otp); + return next(new ErrorHandler(400, "Incorrect Otp")); } -} - -const getUser = async (req,res,next) => { - try { - const user = req.user; - return res.status(200).json({success:true,user}); - } catch (err) { - next(err); + otpdb.used = true; + await otpdb.save(); + const prev = await User.findOne({ + email: email.toLowerCase(), + }); + let user; + if (!prev) { + user = await User.create({ + email: email.toLowerCase(), + }); + } else { + user = prev; } -} - -const forgotEmail = async (req,res,next) => { - try { - const {email} = req.body; - - if(!email) - return next(new ErrorHandler(400,"Email Required.")); - if(!validatemail(email)) - return next(new ErrorHandler(406,"Incorrect Email format.")); - - const oldUser = await User.findOne({ - email:email.toLowerCase() - }); - - if(!oldUser) - return next(new ErrorHandler(400,"User by this email does not exist")); - - const mailedOTP = otpGenerator.generate(6, { - upperCaseAlphabets: false, - specialChars: false, - lowerCaseAlphabets: false - }); - - mailer.sendmail(email,mailedOTP); - - const oldotp = await Otp.findOne({email}); - - if(oldotp){ - let dateNow = new Date(); - dateNow = dateNow.getTime()/1000; - let otpDate = new Date(oldotp.updatedAt); - otpDate = otpDate.getTime()/1000; - console.log(dateNow,otpDate) - if(dateNow { + try { + const { + name, + gender, + student_no, + year, + course, + branch, + POR, + password, + phone_no, + } = req.body; + + let user = req.user; + if (user.verify == true) + return next(new ErrorHandler(400, "Account already made")); + if ( + !( + name && + student_no && + year && + branch && + POR && + password && + phone_no && + gender + ) + ) { + return next(new ErrorHandler(400, "All input fields are required.")); } -} - -const forgotVerify = async (req,res,next) => { - try { - const {email,otp} = req.body; - if(!email){ - return next(new ErrorHandler(400,"Email Required.")); - } - if (!otp) { - return next(new ErrorHandler(400,"Otp Required.")); - } - - if(!validatemail(email)) - return next(new ErrorHandler(406,"Incorrect Email format.")); - - const otpdb = await Otp.findOne({ - email:email.toLowerCase() - }); - if(!otpdb||(otpdb&&otpdb.used)) - return next(new ErrorHandler(400,"Otp expired.")); - - if(otpdb.otp!=otp){ - console.log(otpdb.otp,otp); - return next(new ErrorHandler(400,"Incorrect Otp")); - } - otpdb.used=true; - console.log(1234,otpdb); - await otpdb.save(); - const prev = await User.findOne({ - email:email.toLowerCase() - }) - let user; - user = prev; - console.log(user); - const token = jwt.sign({_id:user._id},process.env.JWT_TOKEN,{expiresIn:'30m'}); - if(user) - return res.status(200).json({success:true,msg:'OTP Verified.',token}); - - } catch (err) { - next(err); + + if (!validatepass(password)) { + return next(new ErrorHandler(400, "Incorrect Password Format")); } -} - -const ChangePassword = async (req,res,next)=>{ - try{ - const { - email, - newpassword - } = req.body; - - let user = req.user; - if(user.verify!=true) - return next(new ErrorHandler(400,"User Not Verified")); - if (!(email&&newpassword)) { - return next(new ErrorHandler(400,"All input fields are required.")); - } - - if(!validatepass(newpassword)){ - return next(new ErrorHandler(400,"Incorrect Password Format")); - } - - if(!validatemail(email)) - return next(new ErrorHandler(406,"Incorrect Email format.")); - - - const encryptedPassword = await bcrypt.hash(newpassword, 12); - - - user.password = encryptedPassword; - - user = await user.save(); - - const accessToken = createAccessToken({ id: user._id }); - - const refreshToken = jwt.sign({ - id: user._id, - }, process.env.JWT_REFRESH_KEY, { expiresIn: process.env.JWT_REFRESH_EXP }); - return res.status(200).json({success:true,msg:`Welcome to Samriddhi Prawah, ${user.name}!`,user,refreshToken,accessToken}); - - } catch (err) { - next(err); + + if (phone_no.length < 10 || !phone_no.match(/^[0-9]+$/)) { + return next(new ErrorHandler(400, "Invalid phone number")); } -} + + const encryptedPassword = await bcrypt.hash(password, 12); + + user.name = name; + (user.student_no = student_no), (user.year = year); + user.course = course; + user.branch = branch; + user.POR = POR; + user.password = encryptedPassword; + user.phone_no = phone_no; + user.gender = gender; + user.verify = true; + + user = await user.save(); + + const accessToken = createAccessToken({ id: user._id }); + + const refreshToken = jwt.sign( + { + id: user._id, + }, + process.env.JWT_REFRESH_KEY, + { expiresIn: process.env.JWT_REFRESH_EXP } + ); + return res + .status(200) + .json({ + success: true, + msg: `Welcome to Samriddhi Prawah, ${name}!`, + user, + refreshToken, + accessToken, + }); + } catch (err) { + next(err); + } +}; + +const getUser = async (req, res, next) => { + try { + const user = req.user; + return res.status(200).json({ success: true, user }); + } catch (err) { + next(err); + } +}; + +const forgotEmail = async (req, res, next) => { + try { + const { email } = req.body; + + if (!email) return next(new ErrorHandler(400, "Email Required.")); + if (!validatemail(email)) + return next(new ErrorHandler(406, "Incorrect Email format.")); + + const oldUser = await User.findOne({ + email: email.toLowerCase(), + }); + + if (!oldUser) + return next(new ErrorHandler(400, "User by this email does not exist")); + + const mailedOTP = otpGenerator.generate(6, { + upperCaseAlphabets: false, + specialChars: false, + lowerCaseAlphabets: false, + }); + + mailer.sendmail(email, mailedOTP); + + const oldotp = await Otp.findOne({ email }); + + if (oldotp) { + let dateNow = new Date(); + dateNow = dateNow.getTime() / 1000; + let otpDate = new Date(oldotp.updatedAt); + otpDate = otpDate.getTime() / 1000; + console.log(dateNow, otpDate); + if (dateNow < otpDate + 10) + return next( + new ErrorHandler(400, "Wait for 10 seconds to resend mail.") + ); + } + + if (oldotp) { + oldotp.otp = mailedOTP; + await oldotp.save(); + } else { + Otp.create({ + email: email.toLowerCase(), + otp: mailedOTP, + }); + } + return res.status(200).json({ success: true, msg: `OTP sent on ${email}` }); + } catch (err) { + next(err); + } +}; + +const forgotVerify = async (req, res, next) => { + try { + const { email, otp } = req.body; + if (!email) { + return next(new ErrorHandler(400, "Email Required.")); + } + if (!otp) { + return next(new ErrorHandler(400, "Otp Required.")); + } + + if (!validatemail(email)) + return next(new ErrorHandler(406, "Incorrect Email format.")); + + const otpdb = await Otp.findOne({ + email: email.toLowerCase(), + }); + if (!otpdb || (otpdb && otpdb.used)) + return next(new ErrorHandler(400, "Otp expired.")); + + if (otpdb.otp != otp) { + console.log(otpdb.otp, otp); + return next(new ErrorHandler(400, "Incorrect Otp")); + } + otpdb.used = true; + console.log(1234, otpdb); + await otpdb.save(); + const prev = await User.findOne({ + email: email.toLowerCase(), + }); + let user; + user = prev; + console.log(user); + const token = jwt.sign({ _id: user._id }, process.env.JWT_TOKEN, { + expiresIn: "30m", + }); + if (user) + return res + .status(200) + .json({ success: true, msg: "OTP Verified.", token }); + } catch (err) { + next(err); + } +}; + +const ChangePassword = async (req, res, next) => { + try { + const { email, newpassword } = req.body; + + let user = req.user; + if (user.verify != true) + return next(new ErrorHandler(400, "User Not Verified")); + if (!(email && newpassword)) { + return next(new ErrorHandler(400, "All input fields are required.")); + } + + if (!validatepass(newpassword)) { + return next(new ErrorHandler(400, "Incorrect Password Format")); + } + + if (!validatemail(email)) + return next(new ErrorHandler(406, "Incorrect Email format.")); + + const encryptedPassword = await bcrypt.hash(newpassword, 12); + + user.password = encryptedPassword; + + user = await user.save(); + + const accessToken = createAccessToken({ id: user._id }); + + const refreshToken = jwt.sign( + { + id: user._id, + }, + process.env.JWT_REFRESH_KEY, + { expiresIn: process.env.JWT_REFRESH_EXP } + ); + return res + .status(200) + .json({ + success: true, + msg: `Welcome to Samriddhi Prawah, ${user.name}!`, + user, + refreshToken, + accessToken, + }); + } catch (err) { + next(err); + } +}; module.exports = { - home, - refreshToken, - login, - email, - everify, - signup, - getUser, - forgotEmail, - forgotVerify, - ChangePassword -} \ No newline at end of file + home, + refreshToken, + login, + email, + everify, + signup, + getUser, + forgotEmail, + forgotVerify, + ChangePassword, +}; diff --git a/controller/homeController.js b/controller/homeController.js index c541992..833d153 100644 --- a/controller/homeController.js +++ b/controller/homeController.js @@ -1,195 +1,221 @@ -require('dotenv').config(); -const {Item, User} = require("../models"); -const { ErrorHandler } = require('../middleware/errors'); -const {validatemail,validatepass} = require('../utils/validation'); -const cloudinary = require('cloudinary').v2; -const {userSchema} = require ('../utils/joiValidations') -const bcrypt = require('bcrypt') +require("dotenv").config(); +const { Item, User } = require("../models"); +const { ErrorHandler } = require("../middleware/errors"); +const { validatemail, validatepass } = require("../utils/validation"); +const cloudinary = require("cloudinary").v2; +const { userSchema } = require("../utils/joiValidations"); +const bcrypt = require("bcrypt"); cloudinary.config({ - cloud_name: process.env.cloud_name, - api_key: process.env.api_key, - api_secret: process.env.api_secret, - secure: true - }); - -const createItem = async (req,res,next) => { - - try { - - const {name , description } = req.body; - const user = req.user; - - if(!name){ - return next(new ErrorHandler(406,"Name required")); - } - - - let files = req.files ? req.files.files : null; - let images=[]; - let Promises = []; - - isArr = Object.prototype.toString.call(files) == '[object Array]'; - if(!isArr){ - files=[]; - files.push(req.files.files); - } - - - for(const file of files){ - let image=null; - if(file){ - Promises.push(cloudinary.uploader.upload(file.tempFilePath,{ - public_id: `${Date.now()}`, - resource_type:'image', - allowed_formats:['jpg','png'], - folder:'images', - width: 2000, height: 1000, crop: "limit" - },(err,result)=>{ - // if (err) return res.status(500).send("upload image error"); - if (err) return next(new ErrorHandler(500,"Upload Image Error(ONLY JPG AND PNG ALLOWED)")); - image = result.secure_url - // console.log((result)); - images.push(image); - })); - } - } - await Promise.all(Promises); - - - const item = await Item.create({ - user:user._id, - name, - description, - images:images - }); - - let userItems = user.items; - userItems.push(item._id); - user.items = userItems; - await user.save(); - - return res.status(201).json({success:true, msg:"Item Created"}) - } catch (err) { - return next(err); - } -} + cloud_name: process.env.cloud_name, + api_key: process.env.api_key, + api_secret: process.env.api_secret, + secure: true, +}); -const getCollectedItems = async (req,res,next) => { - try { +const createItem = async (req, res, next) => { + try { + const { name, description } = req.body; + const user = req.user; - const user = req.user; - let page = parseInt(req.query.page) || 1; - let limit = parseInt(req.query.limit) || 10; + if (!name) { + return next(new ErrorHandler(406, "Name required")); + } - if(page<=0) page = 1; - page = page - 1; - if(limit<0) limit = 0; + let files = req.files ? req.files.files : null; + let images = []; + let Promises = []; - const items = await Item.aggregate([ - { - $match: { - status: 'COLLECTED_AKG', - user: { $ne: user._id } - } - }, - { - $facet: { - count: [ - { $count: "total" } - ], - results: [ - { $skip: page * limit }, - { $limit: limit }, - { $lookup: { from: "users", localField: "user", foreignField: "_id", as: "user" } }, - { $unwind: "$user" }, - { $project: { "user.password": 0, "user.items": 0 } } - ] - } - }, + isArr = Object.prototype.toString.call(files) == "[object Array]"; + if (!isArr) { + files = []; + files.push(req.files.files); + } + + for (const file of files) { + let image = null; + if (file) { + Promises.push( + cloudinary.uploader.upload( + file.tempFilePath, { - $unwind: "$count" + public_id: `${Date.now()}`, + resource_type: "image", + allowed_formats: ["jpg", "png"], + folder: "images", + width: 2000, + height: 1000, + crop: "limit", }, - { - $project: { - results: 1, - count: "$count.total" - } + (err, result) => { + // if (err) return res.status(500).send("upload image error"); + if (err) + return next( + new ErrorHandler( + 500, + "Upload Image Error(ONLY JPG AND PNG ALLOWED)" + ) + ); + image = result.secure_url; + // console.log((result)); + images.push(image); } - ]); - - return res.status(200).json({success:true, pages:Math.ceil(items[0].count/limit), items:items[0].results}); - } catch (err) { - return next(err) + ) + ); + } } -} + await Promise.all(Promises); + + const item = await Item.create({ + user: user._id, + name, + description, + images: images, + }); + + let userItems = user.items; + userItems.push(item._id); + user.items = userItems; + await user.save(); + + return res.status(201).json({ success: true, msg: "Item Created" }); + } catch (err) { + return next(err); + } +}; -const getMyItems = async (req,res,next) => { - try { - const user = req.user; - let page = parseInt(req.query.page) || 1; - let limit = parseInt(req.query.limit) || 10; +const getCollectedItems = async (req, res, next) => { + try { + const user = req.user; + let page = parseInt(req.query.page) || 1; + let limit = parseInt(req.query.limit) || 10; + + if (page <= 0) page = 1; + page = page - 1; + if (limit < 0) limit = 0; + + const items = await Item.aggregate([ + { + $match: { + status: "COLLECTED_AKG", + user: { $ne: user._id }, + }, + }, + { + $facet: { + count: [{ $count: "total" }], + results: [ + { $skip: page * limit }, + { $limit: limit }, + { + $lookup: { + from: "users", + localField: "user", + foreignField: "_id", + as: "user", + }, + }, + { $unwind: "$user" }, + { $project: { "user.password": 0, "user.items": 0 } }, + ], + }, + }, + { + $unwind: "$count", + }, + { + $project: { + results: 1, + count: "$count.total", + }, + }, + ]); + + return res + .status(200) + .json({ + success: true, + pages: Math.ceil(items[0].count / limit), + items: items[0].results, + }); + } catch (err) { + return next(err); + } +}; - if(page<=0) page = 1; - page = page - 1; - if(limit<0) limit = 0; +const getMyItems = async (req, res, next) => { + try { + const user = req.user; + let page = parseInt(req.query.page) || 1; + let limit = parseInt(req.query.limit) || 10; - const items = await Item.find({_id:{$in:user.items}}) - .skip(page*limit).limit(limit); + if (page <= 0) page = 1; + page = page - 1; + if (limit < 0) limit = 0; - return res.status(200).json({success:true, items}); + const items = await Item.find({ _id: { $in: user.items } }) + .skip(page * limit) + .limit(limit); - } catch (err) { - return next(err); - } -} - - -const searchItems = async (req,res,next) => { - try { - const find = req.query.find || ""; - let page = parseInt(req.query.page) || 1; - let limit = parseInt(req.query.limit) || 10; - - if(page<=0) page = 1; - page = page - 1; - if(limit<0) limit = 0; - - const regexQuery = find - .split(' ') - .map(term => `${term}*`) - .join(' '); - - const results = await Item.find({ - $text: { $search: regexQuery }, - status: 'COLLECTED_AKG' - }, - { score: { $meta: 'textScore' }, _id: 1, name: 1, description: 1,images: 1 }) - .sort({ score: { $meta: 'textScore' } }) - .skip(page * limit) - .limit(limit); - return res.status(200).json({success:true,items:results}) - } catch (err) { - next(err); - } -} + return res.status(200).json({ success: true, items }); + } catch (err) { + return next(err); + } +}; + +const searchItems = async (req, res, next) => { + try { + const find = req.query.find || ""; + let page = parseInt(req.query.page) || 1; + let limit = parseInt(req.query.limit) || 10; + + if (page <= 0) page = 1; + page = page - 1; + if (limit < 0) limit = 0; + + const regexQuery = find + .split(" ") + .map((term) => `${term}*`) + .join(" "); + + const results = await Item.find( + { + $text: { $search: regexQuery }, + status: "COLLECTED_AKG", + }, + { + score: { $meta: "textScore" }, + _id: 1, + name: 1, + description: 1, + images: 1, + } + ) + .sort({ score: { $meta: "textScore" } }) + .skip(page * limit) + .limit(limit); + return res.status(200).json({ success: true, items: results }); + } catch (err) { + next(err); + } +}; -const updateUser = async (req,res,next) => { +const updateUser = async (req, res, next) => { try { const body = await userSchema.validateAsync(req.body); body.password = await bcrypt.hash(body.password, 12); - await User.findByIdAndUpdate(body.id ,body) + await User.findByIdAndUpdate(body.id, body); - return res.status(200).json({success:true,msg:"Updated User"}); + return res.status(200).json({ success: true, msg: "Updated User" }); } catch (err) { next(err); } -} +}; module.exports = { - createItem, - getCollectedItems, - getMyItems, - searchItems, - updateUser -} \ No newline at end of file + createItem, + getCollectedItems, + getMyItems, + searchItems, + updateUser, +}; diff --git a/middleware/authverify.js b/middleware/authverify.js index 133f474..36231ba 100644 --- a/middleware/authverify.js +++ b/middleware/authverify.js @@ -10,44 +10,44 @@ const auth = (req, res, next) => { if (!token) return res.status(401).json({ msg: "Please Login or Signup" }); token = token.replace(/^Bearer\s+/, ""); jwt.verify(token, process.env.JWT_ACCESS_KEY, async (err, payload) => { - if(err){ - return next(new ErrorHandler(401,"Invalid Authentication")); + if (err) { + return next(new ErrorHandler(401, "Invalid Authentication")); } - const {id}=payload; + const { id } = payload; const user = await User.findById(id); - if(!user) next(new ErrorHandler(401,"Invalid Authentication")); - if(!user.verify) next(new ErrorHandler(401,"User not verified")); - req.user=user; + if (!user) next(new ErrorHandler(401, "Invalid Authentication")); + if (!user.verify) next(new ErrorHandler(401, "User not verified")); + req.user = user; next(); - }) + }); } catch (err) { return next(err); } }; -const auth2 = (req,res,next) => { - try{ - let token=req.headers['accesstoken'] || req.headers['authorization']; - - if(!token&&!token.startsWith('Bearer')) - return next(new ErrorHandler(401,"Please Login or Signup")); - else{ +const auth2 = (req, res, next) => { + try { + let token = req.headers["accesstoken"] || req.headers["authorization"]; + + if (!token && !token.startsWith("Bearer")) + return next(new ErrorHandler(401, "Please Login or Signup")); + else { token = token.replace(/^Bearer\s+/, ""); - jwt.verify(token,process.env.JWT_TOKEN, async (err,payload)=>{ - if(err){ - return next(new ErrorHandler(401,"Invalid Authentication")); + jwt.verify(token, process.env.JWT_TOKEN, async (err, payload) => { + if (err) { + return next(new ErrorHandler(401, "Invalid Authentication")); } - const {_id}=payload; + const { _id } = payload; const user = await User.findById(_id); - if(!user) next(new ErrorHandler(401,"Invalid Authentication")); - req.user=user; + if (!user) next(new ErrorHandler(401, "Invalid Authentication")); + req.user = user; next(); }); } - } catch(err){ - return next(err); + } catch (err) { + return next(err); } -} +}; const adminauth = (req, res, next) => { try { @@ -55,19 +55,23 @@ const adminauth = (req, res, next) => { // console.log(token); if (!token) return res.status(401).json({ msg: "Please Login or Signup" }); token = token.replace(/^Bearer\s+/, ""); - jwt.verify(token, process.env.ADMIN_JWT_ACCESS_KEY, async (err, payload) => { - if(err){ - return next(new ErrorHandler(401,"Invalid Authentication")); + jwt.verify( + token, + process.env.ADMIN_JWT_ACCESS_KEY, + async (err, payload) => { + if (err) { + return next(new ErrorHandler(401, "Invalid Authentication")); + } + const { id } = payload; + const user = await Admin.findById(id); + if (!user) next(new ErrorHandler(401, "Invalid Authentication")); + req.user = user; + next(); } - const {id}=payload; - const user = await Admin.findById(id); - if(!user) next(new ErrorHandler(401,"Invalid Authentication")); - req.user=user; - next(); - }) + ); } catch (err) { return next(err); } }; -module.exports = {auth,auth2,adminauth}; \ No newline at end of file +module.exports = { auth, auth2, adminauth }; diff --git a/models/UserModel.js b/models/UserModel.js index 799bfd8..1270310 100644 --- a/models/UserModel.js +++ b/models/UserModel.js @@ -2,31 +2,44 @@ const mongoose = require("mongoose"); const { ObjectId } = require("mongodb"); const userSchema = mongoose.Schema({ - name:{ - type: String + name: { + type: String, }, - gender:{ - type:String, - enum:['MALE','FEMALE','OTHERS'] + gender: { + type: String, + enum: ["MALE", "FEMALE", "OTHERS"], }, - student_no:{ - type: Number + student_no: { + type: Number, }, - course:{ + course: { type: String, - enum:['BTECH','BCA','MCA'] + enum: ["BTECH", "BCA", "MCA"], }, - year:{ + year: { type: Number, - enum:[1,2,3,4] + enum: [1, 2, 3, 4], }, - branch:{ + branch: { type: String, - enum:['CSE','CS','CSIT','IT','AIML','CSE-AIML','CSE-DS','EN','MECH','CIVIL','ECE','CSE-HINDI'] + enum: [ + "CSE", + "CS", + "CSIT", + "IT", + "AIML", + "CSE-AIML", + "CSE-DS", + "EN", + "MECH", + "CIVIL", + "ECE", + "CSE-HINDI", + ], }, - POR:{ - type:String, - enum:['BH1','BH2','BH3','GH1','GH2','GH3','DAYSCHOLAR'] + POR: { + type: String, + enum: ["BH1", "BH2", "BH3", "GH1", "GH2", "GH3", "DAYSCHOLAR"], }, email: { type: String, @@ -34,31 +47,33 @@ const userSchema = mongoose.Schema({ unique: true, }, password: { - type: String + type: String, + }, + verify: { + type: Boolean, + default: false, }, - verify:{ - type:Boolean, - default:false + phone_no: { + type: String, + default: "0000000000", }, - phone_no:{ - type:String, - default:'0000000000' + phoneVerification: { + type: Boolean, + default: false, }, - phoneVerification:{ - type:Boolean, - default:false + items: [ + { + type: ObjectId, + ref: "item", + }, + ], + role: { + type: String, + enum: ["USER", "COLLECTOR"], + default: "USER", }, - items:[{ - type: ObjectId, - ref:'item' - }], - role:{ - type:String, - enum:['USER','COLLECTOR'], - default:'USER' - } }); -const UserModel = mongoose.model("user",userSchema); +const UserModel = mongoose.model("user", userSchema); -module.exports=UserModel; \ No newline at end of file +module.exports = UserModel; diff --git a/models/adminModel.js b/models/adminModel.js index 89c8e52..af2bf18 100644 --- a/models/adminModel.js +++ b/models/adminModel.js @@ -1,15 +1,15 @@ const mongoose = require("mongoose"); const adminSchema = mongoose.Schema({ - uname:{ + uname: { type: String, - unique: true + unique: true, }, password: { - type: String - } + type: String, + }, }); -const adminModel = mongoose.model("admin",adminSchema); +const adminModel = mongoose.model("admin", adminSchema); -module.exports= adminModel; \ No newline at end of file +module.exports = adminModel; diff --git a/models/itemsModel.js b/models/itemsModel.js index 093c3d6..5935db5 100644 --- a/models/itemsModel.js +++ b/models/itemsModel.js @@ -21,6 +21,21 @@ const itemSchema = mongoose.Schema({ 'COLLECTED_GH1','COLLECTED_GH2','COLLECTED_GH3', 'COLLECTED_AKG','REJECTED','DONATED'], default:'PENDING' + }, + acceptedBy: { + name: { + type: String, + validate: { + validator: function(value) { + // Custom validation function to check if 'name' is required when 'acceptedBy' is present + return !this.acceptedBy || (this.acceptedBy && value); + }, + message: "Name is required when 'acceptedBy' is provided." + } + }, + email: { + type: String + } } }); diff --git a/routes/adminRoutes.js b/routes/adminRoutes.js index 858d442..6f22620 100644 --- a/routes/adminRoutes.js +++ b/routes/adminRoutes.js @@ -9,6 +9,7 @@ router.get('/highestdonor',authverify.adminauth,adminController.highestDonor); router.get('/items/collected',authverify.adminauth,adminController.allCollectedItems); router.post('/togglecollector',authverify.adminauth,adminController.toggleCollector); router.patch('/status/:itemId',authverify.adminauth,adminController.changeStatus); +router.patch('/donate/:itemId',authverify.adminauth,adminController.donateItem); router.post('/refresh',adminController.refreshToken); router.post('/login',adminController.login); // router.post('/create',adminController.create);