diff --git a/app.js b/app.js index dc9dcad..88e338a 100644 --- a/app.js +++ b/app.js @@ -31,8 +31,8 @@ import orderRoute from './resources/Orders/orderRoute.js' app.use("/api", orderRoute); //Franchisee -import FranchiseeRouter from "./resources/Franchisee/FranchiseeRoute.js"; -app.use("/api/franchisee", FranchiseeRouter); +import FranchiseeRouter from "./resources/Temple/FranchiseeRoute.js"; +app.use("/api/franchisee/", FranchiseeRouter); //state import StateRouter from "./resources/setting/state/state_routes.js"; app.use("/api/state", StateRouter); @@ -46,6 +46,6 @@ app.use("/api/tax", TaxRouter); //config import ConfigRouter from "./resources/setting/Configration/Config_routes.js"; -app.use("/api/config", ConfigRouter); +app.use("/api/config", ConfigRouter) export default app; \ No newline at end of file diff --git a/middlewares/auth.js b/middlewares/auth.js index 8376b20..72ecb27 100644 --- a/middlewares/auth.js +++ b/middlewares/auth.js @@ -1,10 +1,10 @@ import User from "../resources/user/userModel.js"; import jwt from "jsonwebtoken"; import ErrorHander from "../Utils/errorhander.js" +import { Franchisee } from "../resources/Temple/FranchiseeModel.js"; export const isAuthenticatedUser = async (req, res, next) => { try { - if (!req.headers.authorization) { return res.status(400).json({ success: false, @@ -36,6 +36,49 @@ export const isAuthenticatedUser = async (req, res, next) => { }); } }; + + + + + +export const isFranchiAuthenticated = async (req, res, next) => { + try { + + if (!req.headers.authorization) { + return res.status(400).json({ + success: false, + message: "Login to Access this resource", + }); + } + const getToken = req.headers; + //remove Bearer from token + + const fronttoken = getToken.authorization.slice(7); + + const frontdecoded = jwt.verify(fronttoken, process.env.JWT_SECRET); + + if (!frontdecoded) { + return res.status(400).json({ + success: false, + message: "incorrect token", + }); + } + // console.log(frontdecoded) + const fuser = await Franchisee.findById(frontdecoded.id); + + req.franchi = fuser; + + next(); + } catch (error) { + return res.status(400).json({ + success: false, + message: error.message, + }); + } +}; + + + export const authorizeRoles = (...roles) => {//pass admin return (req, res, next) => { if (!roles.includes(req.user.role)) { diff --git a/resources/Franchisee/FranchiseeModel.js b/resources/Temple/FranchiseeModel.js similarity index 88% rename from resources/Franchisee/FranchiseeModel.js rename to resources/Temple/FranchiseeModel.js index 26bc635..619aee4 100644 --- a/resources/Franchisee/FranchiseeModel.js +++ b/resources/Temple/FranchiseeModel.js @@ -15,7 +15,10 @@ const FranchiseeSchema = new Schema( }, email: { type: String, required: [true, "Please Enter Your Email"], - unique: true, + + unique: [true, "Email already exist ! please try with diffent email"], + + validate: [validator.isEmail, "Please Enter a valid Email"], }, password: { @@ -42,6 +45,11 @@ const FranchiseeSchema = new Schema( pin_Code: { type: Number, required: true }, short_url: { type: String, default: "" }, banner: { type: Object, default: { url: "", public_id: "" } }, + verify: { + type: Boolean, + required: true, + default: false + } }, { timestamps: true } ); diff --git a/resources/Franchisee/FranchiseeRoute.js b/resources/Temple/FranchiseeRoute.js similarity index 52% rename from resources/Franchisee/FranchiseeRoute.js rename to resources/Temple/FranchiseeRoute.js index d4a4dab..d6e2350 100644 --- a/resources/Franchisee/FranchiseeRoute.js +++ b/resources/Temple/FranchiseeRoute.js @@ -12,13 +12,24 @@ import { addProductToFranchisee, // addGradeToFranchisee, getFranchiseeByIdPopulated, + FranchiseeLogin, + franchiseeForgotPassword, + franchiseeUpdatePassword, + getFransiDetails, + EditFranchiseeProfile, } from "./Franchisee_controller.js"; -import { authorizeRoles, isAuthenticatedUser } from "../../middlewares/auth.js"; +import { authorizeRoles, isAuthenticatedUser, isFranchiAuthenticated } from "../../middlewares/auth.js"; +import { FranchiseeVarificationFromAdmin } from "./Franchisee_controller.js"; +import { FranchiseePriceLevelProduct } from "./Franchisee_controller.js"; router.get("/", getAllFranchisees); router.get("/withpopulate", isAuthenticatedUser, getAllFranchiseesPopulated); // router.get("/withpopulate/:option", getAllFranchiseesPopulatedWithOption); router.get("/withoutpopulate/:id", isAuthenticatedUser, getFranchiseeByIdWithoutPopulate); + + + + router.get("/:id", isAuthenticatedUser, getFranchiseeById); router.get("/arrayspopulate/:id", getFranchiseeByIdPopulated); router.post("/", isAuthenticatedUser, authorizeRoles("admin"), addFranchisee); @@ -26,5 +37,26 @@ router.patch("/product/:id", isAuthenticatedUser, addProductToFranchisee); // router.patch("/grade/:id", addGradeToFranchisee); router.patch("/:id", isAuthenticatedUser, authorizeRoles("admin"), updateFranchisee); router.delete("/:id", isAuthenticatedUser, authorizeRoles("admin"), deleteFranchiseeById); +//varify +router.get("/admin/verify/:id", isAuthenticatedUser, authorizeRoles("admin"), FranchiseeVarificationFromAdmin); + + +// ---------franchisee Auth ----------------------//////// +franchiseeForgotPassword +router.post("/login", FranchiseeLogin); +router.post("/password/forgot", franchiseeForgotPassword) +router.get("/getDetails/me", isFranchiAuthenticated, getFransiDetails); +router.patch("/edit/self", isFranchiAuthenticated, EditFranchiseeProfile); + + +router.route("/password/update").put(isFranchiAuthenticated, franchiseeUpdatePassword); +//fetch product franchisee Wise +router.route("/product/price_level").get(isFranchiAuthenticated, FranchiseePriceLevelProduct); + + + + + + export default router; diff --git a/resources/Franchisee/Franchisee_controller.js b/resources/Temple/Franchisee_controller.js similarity index 52% rename from resources/Franchisee/Franchisee_controller.js rename to resources/Temple/Franchisee_controller.js index c8a3a80..179b7ce 100644 --- a/resources/Franchisee/Franchisee_controller.js +++ b/resources/Temple/Franchisee_controller.js @@ -6,6 +6,7 @@ import bcrypt from "bcryptjs" import password from 'secure-random-password' import mongoose from "mongoose"; +import { Product } from "../Products/ProductModel.js"; const addFranchisee = async (req, res) => { const image_file = req?.files?.image; @@ -47,6 +48,7 @@ const addFranchisee = async (req, res) => { }) req.body.password = passwords; + req.user.role === 'admin' ? req.body.verify = true : req.body.verify = false const entity = await Franchisee.create(req.body); await sendEmail({ @@ -96,7 +98,7 @@ const getFranchiseeById = async (req, res) => { .populate("products"); return res.status(200).json({ status: "OK", data: entity }); } catch (err) { - console.log(err); + // console.log(err); return res.status(500).json({ message: "Unable to get menu items." }); } }; @@ -191,6 +193,8 @@ const updateFranchisee = async (req, res) => { }) req.body.password = await bcrypt.hash(passwords, 12) + req.user.role === 'admin' ? req.body.verify = true : req.body.verify = false + const entity = await Franchisee.findByIdAndUpdate(req.params.id, req.body); await sendEmail({ @@ -211,7 +215,7 @@ const updateFranchisee = async (req, res) => { console.log(err); if (req?.files?.image?.tempFilePath) fs.unlinkSync(image_file?.tempFilePath); - return res.status(500).json({ message: "Unable to create." }); + return res.status(500).json({ message: err.message ? err.message : "Unable to Update." }); } }; @@ -259,8 +263,264 @@ const findFranchiseeByURL = async (req, res) => { return res.status(500).json({ message: "Franchisee not found" }); } }; +//------------------------------Franchisee Auth----------------------// +export const FranchiseeLogin = async (req, res) => { + try { + const { email, password } = req.body; + + const franchisee = await Franchisee.findOne({ email }) + .select("+password") + if (!franchisee) { + return res.status(400).json({ + success: false, + message: "Franchisee does not exist", + }); + } + + const isMatch = await franchisee.comparePassword(password); + + if (!isMatch) { + return res.status(400).json({ + success: false, + message: "Incorrect password", + }); + } + + const token = await franchisee.getJWTToken(); + + + res.status(200).json({ + success: true, + franchisee, + token, + }); + } catch (error) { + res.status(500).json({ + success: false, + message: error.message, + }); + } +}; +//6.Get User Detail +export const getFransiDetails = async (req, res) => { + try { + const franchisee = await Franchisee.findById(req.franchi._id); + + res.status(200).json({ + success: true, + franchisee, + }); + } + catch (error) { + res.status(500).json({ + success: false, + message: error.message, + }) + } + +}; + +export const franchiseeUpdatePassword = async (req, res) => { + try { + const franchisee = await Franchisee.findById(req.franchi._id).select("+password"); + + const { oldPassword, newPassword } = req.body; + + if (!oldPassword || !newPassword) { + return res.status(400).json({ + success: false, + message: "Please provide old and new password", + }); + } + + const isMatch = await franchisee.comparePassword(oldPassword); + + if (!isMatch) { + return res.status(400).json({ + success: false, + message: "Incorrect Old password", + }); + } + + franchisee.password = newPassword; + await franchisee.save(); + + res.status(200).json({ + success: true, + message: "Password Updated", + }); + } catch (error) { + res.status(500).json({ + success: false, + message: error.message, + }); + } +}; +export const franchiseeForgotPassword = async (req, res, next) => { + const franchisee = await Franchisee.findOne({ email: req.body.email }); + + if (!franchisee) { + return res.status(404).json({ message: "Franchisee not found" }); + + } + + const passwords = password.randomPassword({ + length: 12, + characters: [ + { characters: password.upper, exactly: 1 }, + { characters: password.symbols, exactly: 1 }, + password.lower, + password.digits] + }) + + franchisee.password = passwords; + // req.body.password = await bcrypt.hash(passwords, 12) + + await franchisee.save() + try { + + await sendEmail({ + + to: `${franchisee.email}`, // Change to your recipient + + from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender + + subject: `ATP Franchisee Password Recovery`, + html: `your new password is:
${passwords}

If you have not requested this email then, please ignore it.` + + }); + + res.status(200).json({ + success: true, + message: `Password sent to ${franchisee.email} successfully`, + }); + } catch (error) { + + return res.status(500).json({ message: error?.message || "Something went wrong!" }); + } +} +//edit franchi profile self +export const EditFranchiseeProfile = async (req, res, next) => { + const image_file = req?.files?.image; + try { + const FranchiseeWithURL = await Franchisee.findOne({ + short_url: req.body?.short_url, + }); + + if ( + FranchiseeWithURL?._id && + FranchiseeWithURL?._id?.toString() !== req.franchi._id.toString() + ) { + if (req?.files?.image?.tempFilePath) + fs.unlinkSync(image_file?.tempFilePath); + return res.status(400).json({ message: "Franchisee URL is not available!" }); + } + const getFranchisee = await Franchisee.findById(req.franchi._id); + + + + if (image_file?.tempFilePath) { + if (getFranchisee?.banner) { + const imageId = getFranchisee?.banner?.public_id; + + await cloudinary.uploader.destroy(imageId) + } + const result = await cloudinary.v2.uploader.upload( + image_file?.tempFilePath, + { + folder: "ATP/Franchisee_banners", + } + ); + const image = { url: result?.secure_url, public_id: result?.public_id }; + req.body.banner = image; + fs.unlinkSync(image_file?.tempFilePath); + await cloudinary.v2.uploader.destroy(getFranchisee.banner.public_id); + } + req.body.verify = false + const entity = await Franchisee.findByIdAndUpdate(req.franchi._id, req.body); + + return res.status(200).json({ + success: true, + data: entity, + message: `Franchisee Edited successfully and varified by admin soon !`, + }); + } catch (err) { + console.log(err); + if (req?.files?.image?.tempFilePath) + fs.unlinkSync(image_file?.tempFilePath); + return res.status(500).json({ message: err.message }); + } +} + +//franchisee varification +export const FranchiseeVarificationFromAdmin = async (req, res) => { + + try { + + const getFranchisee = await Franchisee.findById(req.params.id); + if (getFranchisee.verify === false) { + if (req.user.role === 'admin') { + getFranchisee.verify = true + getFranchisee.save() + await sendEmail({ + + to: `${getFranchisee.email}`, // Change to your recipient + + from: `${process.env.SEND_EMAIL_FROM}`, // Change to your verified sender + + subject: `Cakestick Franchisee Varification`, + html: `your franchisee ${getFranchisee.name} is Varified !!

Thank You

` + + }); + return res.status(200).json({ + success: true, + message: `Franchisee varify successfully`, + }); + } + else { + return res.status(400).json({ + success: false, + + message: `Franchisee varification failled! only admin can varify, please try with admin account `, + }); + } + } else { + return res.status(400).json({ + success: false, + message: `Franchisee Allready Varified`, + }); + } + } catch (err) { + // console.log(err) + return res.status(500).json({ message: err.message ? err.message : "Something went wrong." }); + } +}; +//filter franchisee wise product + +export const FranchiseePriceLevelProduct = async (req, res) => { + + try { + const getFranchisee = await Franchisee.findById(req.franchi._id); + // console.log(getFranchisee.price_Lable) + if (getFranchisee?.price_Lable) { + const getFranchiseeProduct = await Product.find().select(`${getFranchisee.price_Lable}`); + + + + return res.status(200).json({ + success: true, + getFranchiseeProduct, + message: `Franchisee product fetched`, + }); + } + + } catch (err) { + + return res.status(500).json({ message: err.message ? err.message : "Something went wrong." }); + } +}; export { addFranchisee, diff --git a/resources/setting/Configration/Config_routes.js b/resources/setting/Configration/Config_routes.js index c67e16c..0d1040d 100644 --- a/resources/setting/Configration/Config_routes.js +++ b/resources/setting/Configration/Config_routes.js @@ -29,6 +29,7 @@ router.route("/address").post(isAuthenticatedUser, authorizeRoles("admin"), addA // router.route("/scrollText").post(isAuthenticatedUser, authorizeRoles("admin"), addScrollText); router.route("/logo").post(isAuthenticatedUser, authorizeRoles("admin"), addLogo); router.route("/").get(getConfig).delete(isAuthenticatedUser, authorizeRoles("admin"), deleteConfig); + router .route("/termsofuse") .get(isAuthenticatedUser, authorizeRoles("admin"), getTermsOfUse)