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"
|
RAZERPAY_SECRET_KEY="WFhHbXL7AlLIuull9kKjYiNA"
|
||||||
FRONTEND_URL="https://smellika.com"
|
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"
|
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 ContentRoute from "./resources/Content/ContentRoutes.js";
|
||||||
import UserAddressRoute from "./resources/userAddress/useAddressRoute.js";
|
import UserAddressRoute from "./resources/userAddress/useAddressRoute.js";
|
||||||
import CurrencyRoute from "./resources/Currency/CurrencyRoute.js";
|
import CurrencyRoute from "./resources/Currency/CurrencyRoute.js";
|
||||||
|
// RD Routes
|
||||||
|
import RDRoute from './resources/RetailDistributor/RetailDistributerRoutes.js'
|
||||||
//business_Type
|
//business_Type
|
||||||
// import Business_TypeRoute from "./resources/setting/Business_Type/Business_routes.js";
|
// 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);
|
app.use("/api/sales", SalesRoute);
|
||||||
//Task
|
//Task
|
||||||
app.use("/api/task", TaskRoute);
|
app.use("/api/task", TaskRoute);
|
||||||
|
// RD Rotuts
|
||||||
|
app.use("/api",RDRoute)
|
||||||
//config specialty
|
//config specialty
|
||||||
// app.use("/api/config/specialty", SpecialtiesRouter);
|
// app.use("/api/config/specialty", SpecialtiesRouter);
|
||||||
//specialties
|
//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)) {
|
if (!mongoose.Types.ObjectId.isValid(req.user._id)) {
|
||||||
return res.status(400).json({ message: "Please login again" });
|
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
|
// Upload images to Cloudinary and store only public_id and url
|
||||||
const uploadImage = async (image, folder) => {
|
const uploadImage = async (image, folder) => {
|
||||||
if (!image) return null;
|
if (!image) return null;
|
||||||
@ -378,7 +381,7 @@ export const getKycById = async (req, res) => {
|
|||||||
|
|
||||||
export const updateKycStatus = async (req, res) => {
|
export const updateKycStatus = async (req, res) => {
|
||||||
const { status, rejectionReason, user } = req.body;
|
const { status, rejectionReason, user } = req.body;
|
||||||
console.log(status);
|
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
// console.log(user, rejectionReason, status);
|
// console.log(user, rejectionReason, status);
|
||||||
try {
|
try {
|
||||||
@ -394,7 +397,7 @@ export const updateKycStatus = async (req, res) => {
|
|||||||
const trade_name = kyc.trade_name;
|
const trade_name = kyc.trade_name;
|
||||||
if (status === "approved") {
|
if (status === "approved") {
|
||||||
kyc.status = status;
|
kyc.status = status;
|
||||||
console.log("inside Approved ");
|
|
||||||
await rejectKYC(
|
await rejectKYC(
|
||||||
kyc.addedBy,
|
kyc.addedBy,
|
||||||
"KYC Approved",
|
"KYC Approved",
|
||||||
@ -407,6 +410,7 @@ export const updateKycStatus = async (req, res) => {
|
|||||||
added_for: kyc.addedBy,
|
added_for: kyc.addedBy,
|
||||||
// userType: req.userType,
|
// userType: req.userType,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate a secure password for RetailDistributor
|
// Generate a secure password for RetailDistributor
|
||||||
const password = generatePassword(kyc.name, kyc.email);
|
const password = generatePassword(kyc.name, kyc.email);
|
||||||
|
|
||||||
|
@ -702,7 +702,14 @@ const formatDate = (date) => {
|
|||||||
|
|
||||||
export const getOrderCounts = async (req, res) => {
|
export const getOrderCounts = async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
// console.log(req.user._id,"");
|
||||||
|
const userId = req.user._id;
|
||||||
const statusCounts = await PdOrder.aggregate([
|
const statusCounts = await PdOrder.aggregate([
|
||||||
|
{
|
||||||
|
$match: {
|
||||||
|
addedBy: userId, // Only match orders added by the current user
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
$group: {
|
$group: {
|
||||||
_id: "$status", // Group by status
|
_id: "$status", // Group by status
|
||||||
|
@ -50,6 +50,6 @@ router
|
|||||||
router
|
router
|
||||||
.route("/change/status/:id")
|
.route("/change/status/:id")
|
||||||
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
|
.patch(isAuthenticatedUser, authorizeRoles("admin"), updateOrderStatusById);
|
||||||
router.route("/get-counts-pdOrders").get(getOrderCounts);
|
router.route("/get-counts-pdOrders").get(isAuthenticatedUser, getOrderCounts);
|
||||||
|
|
||||||
export default router;
|
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,
|
resetPasswordExpire: Date,
|
||||||
fcm_token: {
|
fcm_token: {
|
||||||
type: String,
|
type: String,
|
||||||
unique: true,
|
default: null,
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
);
|
);
|
||||||
@ -102,7 +101,9 @@ RetailDistributorSchema.pre("save", function (next) {
|
|||||||
|
|
||||||
// JWT TOKEN
|
// JWT TOKEN
|
||||||
RetailDistributorSchema.methods.getJWTToken = function () {
|
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
|
// Compare Password
|
||||||
@ -128,4 +129,4 @@ const RetailDistributor = mongoose.model(
|
|||||||
"RetailDistributor",
|
"RetailDistributor",
|
||||||
RetailDistributorSchema
|
RetailDistributorSchema
|
||||||
);
|
);
|
||||||
export default RetailDistributor;
|
export default RetailDistributor;
|
||||||
|
Loading…
Reference in New Issue
Block a user