Merge branch 'main' of https://git.cnapp.co.in/gitadmin/api
This commit is contained in:
commit
4a51003d67
2
.env
2
.env
@ -32,7 +32,7 @@ RAZERPAY_KEY_ID="rzp_test_2rg1Bq3Ki8xw9e"
|
||||
RAZERPAY_SECRET_KEY="WFhHbXL7AlLIuull9kKjYiNA"
|
||||
FRONTEND_URL="https://smellika.com"
|
||||
|
||||
PD_APP_URL="https://principal-distributer-cheminova.netlify.app"
|
||||
PD_APP_URL="https://pd.cnapp.co.in/#/login"
|
||||
|
||||
|
||||
SEND_EMAIL_FROM="cheminova2004@gmail.com"
|
||||
|
5
app.js
5
app.js
@ -159,6 +159,8 @@ import shopImageRoute from "./resources/ShopPageImage/ShopPageImageRoute.js";
|
||||
import ContentRoute from "./resources/Content/ContentRoutes.js";
|
||||
import UserAddressRoute from "./resources/userAddress/useAddressRoute.js";
|
||||
import CurrencyRoute from "./resources/Currency/CurrencyRoute.js";
|
||||
// RD Routes
|
||||
import RDRoute from './resources/RetailDistributor/RetailDistributerRoutes.js'
|
||||
//business_Type
|
||||
// import Business_TypeRoute from "./resources/setting/Business_Type/Business_routes.js";
|
||||
|
||||
@ -272,7 +274,8 @@ app.use("/api/inventory", InventoryRoute);
|
||||
app.use("/api/sales", SalesRoute);
|
||||
//Task
|
||||
app.use("/api/task", TaskRoute);
|
||||
|
||||
// RD Rotuts
|
||||
app.use("/api",RDRoute)
|
||||
//config specialty
|
||||
// app.use("/api/config/specialty", SpecialtiesRouter);
|
||||
//specialties
|
||||
|
38
middlewares/rdAuth.js
Normal file
38
middlewares/rdAuth.js
Normal file
@ -0,0 +1,38 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import RetailDistributor from "../resources/RetailDistributor/RetailDistributorModel.js";
|
||||
|
||||
// import { Business } from "../resources/Businesses/BusinessModel.js";
|
||||
|
||||
export const isAuthenticatedRD = 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;
|
||||
// console.log(getToken);
|
||||
//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 RetailDistributor.findById(frontdecoded.id);
|
||||
// console.log(fuser);
|
||||
req.user = fuser;
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: error.message,
|
||||
});
|
||||
}
|
||||
};
|
@ -47,7 +47,10 @@ export const createKyc = async (req, res) => {
|
||||
if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
|
||||
return res.status(400).json({ message: "Please login again" });
|
||||
}
|
||||
|
||||
const isExits = await KYC.find({ email: email });
|
||||
if (isExits.length > 0) {
|
||||
throw new Error("Email already exists");
|
||||
}
|
||||
// Upload images to Cloudinary and store only public_id and url
|
||||
const uploadImage = async (image, folder) => {
|
||||
if (!image) return null;
|
||||
@ -378,7 +381,7 @@ export const getKycById = async (req, res) => {
|
||||
|
||||
export const updateKycStatus = async (req, res) => {
|
||||
const { status, rejectionReason, user } = req.body;
|
||||
console.log(status);
|
||||
|
||||
const { id } = req.params;
|
||||
// console.log(user, rejectionReason, status);
|
||||
try {
|
||||
@ -394,7 +397,7 @@ export const updateKycStatus = async (req, res) => {
|
||||
const trade_name = kyc.trade_name;
|
||||
if (status === "approved") {
|
||||
kyc.status = status;
|
||||
console.log("inside Approved ");
|
||||
|
||||
await rejectKYC(
|
||||
kyc.addedBy,
|
||||
"KYC Approved",
|
||||
@ -407,6 +410,7 @@ export const updateKycStatus = async (req, res) => {
|
||||
added_for: kyc.addedBy,
|
||||
// userType: req.userType,
|
||||
});
|
||||
|
||||
// Generate a secure password for RetailDistributor
|
||||
const password = generatePassword(kyc.name, kyc.email);
|
||||
|
||||
|
@ -702,7 +702,14 @@ const formatDate = (date) => {
|
||||
|
||||
export const getOrderCounts = async (req, res) => {
|
||||
try {
|
||||
// console.log(req.user._id,"");
|
||||
const userId = req.user._id;
|
||||
const statusCounts = await PdOrder.aggregate([
|
||||
{
|
||||
$match: {
|
||||
addedBy: userId, // Only match orders added by the current user
|
||||
},
|
||||
},
|
||||
{
|
||||
$group: {
|
||||
_id: "$status", // Group by status
|
||||
|
@ -50,6 +50,6 @@ router
|
||||
router
|
||||
.route("/change/status/:id")
|
||||
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
|
||||
router.route("/get-counts-pdOrders").get(getOrderCounts);
|
||||
router.route("/get-counts-pdOrders").get(isAuthenticatedUser, getOrderCounts);
|
||||
|
||||
export default router;
|
||||
|
28
resources/RetailDistributor/RetailDistributerRoutes.js
Normal file
28
resources/RetailDistributor/RetailDistributerRoutes.js
Normal file
@ -0,0 +1,28 @@
|
||||
import express from "express";
|
||||
import {
|
||||
ChangePasswordRD,
|
||||
forgotPassword,
|
||||
getmyProfile,
|
||||
loginRD,
|
||||
UpdateProfile,
|
||||
} from "./RetailDistributorController.js";
|
||||
import { isAuthenticatedRD } from "../../middlewares/rdAuth.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.route("/rd-login").post(loginRD);
|
||||
router.route("/rd-get-me").get(isAuthenticatedRD, getmyProfile);
|
||||
router.post("/forgot-password", forgotPassword);
|
||||
router.put(
|
||||
"/rd-password/update",
|
||||
isAuthenticatedRD,
|
||||
|
||||
ChangePasswordRD
|
||||
);
|
||||
router.patch(
|
||||
"/rd-profile/update",
|
||||
isAuthenticatedRD,
|
||||
|
||||
UpdateProfile
|
||||
);
|
||||
export default router;
|
@ -0,0 +1,218 @@
|
||||
import RetailDistributor from "./RetailDistributorModel.js";
|
||||
import validator from "validator";
|
||||
export const loginRD = async (req, res) => {
|
||||
const { email, password } = req.body;
|
||||
|
||||
try {
|
||||
if (!email || !password) {
|
||||
return res.status(400).json({ message: "Please Enter Email & Password" });
|
||||
}
|
||||
|
||||
const retailDistributor = await RetailDistributor.findOne({ email }).select(
|
||||
"+password"
|
||||
);
|
||||
|
||||
if (!retailDistributor) {
|
||||
return res.status(400).json({ message: "Invalid Email or Password" });
|
||||
}
|
||||
|
||||
const isPasswordMatched = await retailDistributor.comparePassword(password);
|
||||
|
||||
if (!isPasswordMatched) {
|
||||
return res.status(400).json({ message: "Invalid Email or Password" });
|
||||
}
|
||||
const token = retailDistributor.getJWTToken();
|
||||
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
token,
|
||||
message: "Login Successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
return res.status(500).json({
|
||||
message: error.message ? error.message : "Something went wrong!",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const ChangePasswordRD = async (req, res) => {
|
||||
// Retrieve id from req.params
|
||||
const { oldPassword, newPassword, confirmPassword } = req.body;
|
||||
const userId = req.user._id; // Use the ID from the URL or from the authenticated user
|
||||
// console.log(userId);
|
||||
if (!oldPassword) {
|
||||
return res.status(400).json({ message: "Please Enter Old password" });
|
||||
}
|
||||
if (!newPassword) {
|
||||
return res.status(400).json({ message: "Please Enter New Password " });
|
||||
}
|
||||
if (!confirmPassword) {
|
||||
return res.status(400).json({ message: "Please Enter Confirm Password" });
|
||||
}
|
||||
try {
|
||||
const retailDistributor = await RetailDistributor.findById(userId).select(
|
||||
"+password"
|
||||
);
|
||||
|
||||
if (!retailDistributor) {
|
||||
return res.status(404).json({ message: "Retail Distributer not found" });
|
||||
}
|
||||
|
||||
const isPasswordMatched = await retailDistributor.comparePassword(
|
||||
oldPassword
|
||||
);
|
||||
|
||||
if (!isPasswordMatched) {
|
||||
return res.status(400).json({ message: "Old password is incorrect" });
|
||||
}
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ message: "New password and confirm Password do not match" });
|
||||
}
|
||||
|
||||
retailDistributor.password = newPassword;
|
||||
await retailDistributor.save();
|
||||
|
||||
return res
|
||||
.status(200)
|
||||
.json({ success: true, message: "Password updated successfully" });
|
||||
} catch (error) {
|
||||
console.error("Error updating password:", error);
|
||||
return res.status(500).json({
|
||||
message: error.message ? error.message : "Server error!",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const forgotPassword = async (req, res) => {
|
||||
try {
|
||||
// Check if email is provided
|
||||
const { email } = req.body;
|
||||
if (!email) {
|
||||
return res.status(400).json({ message: "Please Enter Email!" });
|
||||
}
|
||||
|
||||
// Find the Retail Distributor by email
|
||||
const retailDistributor = await RetailDistributor.findOne({ email });
|
||||
if (!retailDistributor) {
|
||||
return res.status(404).json({ message: "Retail Distributor not found" });
|
||||
}
|
||||
|
||||
// Generate a random password
|
||||
const newPassword = password.randomPassword({
|
||||
length: 12,
|
||||
characters: [
|
||||
{ characters: password.upper, exactly: 1 }, // At least 1 uppercase letter
|
||||
{ characters: password.symbols, exactly: 1 }, // At least 1 symbol
|
||||
password.lower, // Lowercase letters
|
||||
password.digits, // Digits
|
||||
],
|
||||
});
|
||||
|
||||
// Update the retail distributor's password
|
||||
retailDistributor.password = newPassword;
|
||||
await retailDistributor.save(); // The pre-save hook in your schema will handle password hashing
|
||||
|
||||
// Send an email to the retail distributor with the new password
|
||||
await sendEmail({
|
||||
to: retailDistributor.email,
|
||||
from: process.env.SEND_EMAIL_FROM,
|
||||
subject: `Cheminova Password Recovery`,
|
||||
html: `Your new password is: <strong>${newPassword}</strong><br/><br/>If you did not request this, please ignore this email.`,
|
||||
});
|
||||
|
||||
// Respond with success message
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: `Email sent to ${retailDistributor.email} successfully`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error during password reset:", error);
|
||||
return res.status(500).json({
|
||||
message: error.message || "Something went wrong!",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const UpdateProfile = async (req, res) => {
|
||||
const { name, email } = req.body;
|
||||
|
||||
const userId = req.user._id; // Use the ID from params or authenticated user
|
||||
|
||||
// Validate email if provided
|
||||
if (email && !validator.isEmail(email)) {
|
||||
return res.status(400).json({ message: "Invalid email address" });
|
||||
}
|
||||
|
||||
try {
|
||||
// Find the RetailDistributor by user ID
|
||||
const retailDistributor = await RetailDistributor.findById(userId);
|
||||
|
||||
if (!retailDistributor) {
|
||||
return res.status(404).json({ message: "Retail Distributor not found" });
|
||||
}
|
||||
|
||||
// Assuming you have an 'isVerified' field in your RetailDistributor schema
|
||||
if (!retailDistributor.isVerified) {
|
||||
return res
|
||||
.status(400)
|
||||
.json({ message: "Retail Distributor not verified" });
|
||||
}
|
||||
|
||||
// Check if email is being changed and if it's already in use
|
||||
if (email && email !== retailDistributor.email) {
|
||||
const emailExists = await RetailDistributor.findOne({ email });
|
||||
if (emailExists && emailExists._id.toString() !== userId) {
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"This Email ID is already in use by another Retail Distributor",
|
||||
});
|
||||
}
|
||||
retailDistributor.email = email;
|
||||
}
|
||||
|
||||
// Update name if provided
|
||||
if (name) {
|
||||
retailDistributor.name = name;
|
||||
}
|
||||
|
||||
// Save the updated RetailDistributor
|
||||
await retailDistributor.save();
|
||||
|
||||
return res.status(200).json({
|
||||
retailDistributor,
|
||||
message: "Profile updated successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
return res.status(500).json({
|
||||
message: error.message || "Server error!",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const getmyProfile = async (req, res) => {
|
||||
try {
|
||||
// Fetch the profile data using the authenticated user's ID
|
||||
const myData = await RetailDistributor.findById(req.user?._id);
|
||||
|
||||
if (myData) {
|
||||
return res.status(200).json({
|
||||
success: true,
|
||||
message: "Profile fetched successfully!",
|
||||
myData,
|
||||
});
|
||||
} else {
|
||||
return res.status(404).json({
|
||||
success: false,
|
||||
message: "Retail Distributor not found",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
return res.status(500).json({
|
||||
success: false,
|
||||
message: error.message || "Something went wrong!",
|
||||
});
|
||||
}
|
||||
};
|
@ -68,9 +68,8 @@ const RetailDistributorSchema = new mongoose.Schema(
|
||||
resetPasswordExpire: Date,
|
||||
fcm_token: {
|
||||
type: String,
|
||||
unique: true,
|
||||
default: null,
|
||||
},
|
||||
|
||||
},
|
||||
{ timestamps: true }
|
||||
);
|
||||
@ -102,7 +101,9 @@ RetailDistributorSchema.pre("save", function (next) {
|
||||
|
||||
// JWT TOKEN
|
||||
RetailDistributorSchema.methods.getJWTToken = function () {
|
||||
return jwt.sign({ id: this._id }, process.env.JWT_SECRET);
|
||||
return jwt.sign({ id: this._id }, process.env.JWT_SECRET, {
|
||||
expiresIn: "1d", // Token will expire in 1 day
|
||||
});
|
||||
};
|
||||
|
||||
// Compare Password
|
||||
|
Loading…
Reference in New Issue
Block a user