This commit is contained in:
Sibunnayak 2024-09-09 16:59:17 +05:30
commit 4a51003d67
9 changed files with 309 additions and 10 deletions

2
.env
View File

@ -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
View File

@ -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
View 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,
});
}
};

View File

@ -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);

View File

@ -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

View File

@ -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;

View 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;

View File

@ -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!",
});
}
};

View File

@ -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;