diff --git a/src/controllers/Auth/index.ts b/src/controllers/Auth/index.ts index 9782499..4ab625d 100644 --- a/src/controllers/Auth/index.ts +++ b/src/controllers/Auth/index.ts @@ -1,9 +1,9 @@ +import jwt from 'jsonwebtoken'; import { Request, Response, NextFunction } from "express"; import User from "../../models/userModel"; import { CustomError } from "../../middleware/error"; import setCookie from "../../utils/setCookies"; import crypto from "crypto"; -// import { db } from "../../db/db"; import { sendMail } from "../../utils/sendMail"; const hashPassword = (password: string, salt: string): Promise => { @@ -38,7 +38,18 @@ export const register = async (req: Request, res: Response, next: NextFunction) await newUser.save(); - res.status(201).json({ message: 'User registered successfully' }); + // Generate JWT token + const token = jwt.sign( + { userId: newUser._id, email: newUser.email }, + process.env.JWT_SECRET!, + { expiresIn: '1h' } // Token valid for 1 hour + ); + + // Send response with token + res.status(201).json({ + message: 'User registered successfully', + token, // Return the token to the client + }); } catch (error: any) { console.log(error); next(new CustomError(error.message)); @@ -60,14 +71,25 @@ export const login = async (req: Request, res: Response, next: NextFunction) => return res.status(400).json({ message: 'Invalid email or password' }); } - setCookie({ - user, - res, - next, - message: "Login Success", - statusCode: 200, + // Generate JWT token + const token = jwt.sign( + { userId: user._id, email: user.email }, + process.env.JWT_SECRET!, // Ensure your JWT secret is available in environment variables + { expiresIn: '1h' } // Token valid for 1 hour + ); + + // Optionally set the token as an HTTP-only cookie + res.cookie('token', token, { + httpOnly: true, + secure: process.env.NODE_ENV === 'production', // Only send over HTTPS in production + maxAge: 3600000, // 1 hour + }); + + // Send response with token + res.status(200).json({ + message: 'Logged in successfully', + token, // Return the token to the client }); - res.status(200).json({ message: 'Logged in successfully' }); } catch (error: any) { console.log(error); next(new CustomError(error.message)); diff --git a/src/controllers/Mentor/index.ts b/src/controllers/Mentor/index.ts index e054568..4030971 100644 --- a/src/controllers/Mentor/index.ts +++ b/src/controllers/Mentor/index.ts @@ -2,7 +2,7 @@ import { Request, Response, NextFunction } from "express"; import { db } from "../../db/db"; import { CustomError } from "../../middleware/error"; import mongoose from "mongoose"; - +import { ObjectId } from "mongodb"; export const getMentor = async (req: Request, res: Response, next: NextFunction) => { try { const mentors = await db.collection('mentors').find().toArray(); @@ -21,6 +21,30 @@ export const getMentor = async (req: Request, res: Response, next: NextFunction) } }; + export const getMentorById = async (req: Request, res: Response, next: NextFunction) => { + try { + const { id } = req.params; + + if (!ObjectId.isValid(id)) { + return next(new CustomError("Invalid ID format", 400)); + } + + const mentor = await db.collection('mentors').findOne({ _id: new ObjectId(id) }); + + if (!mentor) { + return next(new CustomError("Mentor not found", 404)); + } + + res.status(200).json({ + success: true, + mentor, + }); + + } catch (error: any) { + next(new CustomError(error.message)); + } + }; + export const verifyMentor = async (req: Request, res: Response, next: NextFunction) => { try { const mentorId = req.params.id; diff --git a/src/controllers/Student/index.ts b/src/controllers/Student/index.ts index b2e8e7a..83c26d1 100644 --- a/src/controllers/Student/index.ts +++ b/src/controllers/Student/index.ts @@ -2,8 +2,49 @@ import { Request, Response, NextFunction } from "express"; import { db } from "../../db/db"; import { CustomError } from "../../middleware/error"; import mongoose from "mongoose"; +import { ObjectId } from "mongodb"; +export const getStudent = async (req: Request, res: Response, next: NextFunction) => { + try { + const students = await db.collection('users').find().toArray(); + if (!students || students.length === 0) { + return next(new CustomError("No students found", 404)); + } + + res.status(200).json({ + success: true, + students + }); + + } catch (error: any) { + next(new CustomError(error.message)); + } +}; +export const getStudentById = async (req: Request, res: Response, next: NextFunction) => { + try { + const { id } = req.params; // id will come from the route params + + // Validate if ID is a valid ObjectId + if (!ObjectId.isValid(id)) { + return next(new CustomError("Invalid ID format", 400)); + } + + const student = await db.collection('users').findOne({ _id: new ObjectId(id) }); + + if (!student) { + return next(new CustomError("Student not found", 404)); + } + + res.status(200).json({ + success: true, + student, + }); + + } catch (error: any) { + next(new CustomError(error.message)); + } +}; export const allocateStudents = async (req: Request, res: Response, next: NextFunction) => { try { const { mentorId } = req.params; @@ -99,77 +140,115 @@ export const deallocateStudents = async (req: Request, res: Response, next: Next }; export const getStudentsWithNullMentor = async (req: Request, res: Response, next: NextFunction) => { - try { - const { query } = req.query as { query?: string }; - - let filter: any = { "mentor._id": null }; - - if (query) { - // Exact match filter - const exactMatchFilter = { - $or: [ - { firstname: query }, - { lastname: query }, - { email: query }, - ], - }; - - // Search for exact matches first - const exactMatches = await db.collection('users').find({ - ...filter, - $or: [ - exactMatchFilter - ] - }).project({ + try { + const { mentorId, query } = req.query as { mentorId?: string; query?: string }; + + if (!mentorId) { + return res.status(400).json({ + success: false, + message: "Mentor ID is required", + }); + } + + const objectId = new mongoose.Types.ObjectId(mentorId); + + // Fetch mentor details to determine gender + const mentor = await db.collection("mentors").findOne( + { _id: objectId }, + { projection: { "about.gender": 1 } } + ); + + if (!mentor) { + return res.status(404).json({ + success: false, + message: "Mentor not found", + }); + } + + const mentorGender = mentor.about?.gender; // Mentor's gender from `about` + + // Base filter for students with null mentor + let filter: any = { "mentor._id": null }; + + // Apply query filter if provided + if (query) { + const exactMatchFilter = { + $or: [ + { firstname: query }, + { lastname: query }, + { email: query }, + ], + }; + + const exactMatches = await db.collection("users").find({ + ...filter, + $or: [exactMatchFilter], + }) + .project({ _id: 1, firstname: 1, lastname: 1, email: 1, academic: 1, mentor: 1, - }).toArray(); - - if (exactMatches.length > 0) { - return res.status(200).json({ - success: true, - students: exactMatches, - }); - } - - // If no exact matches, search for partial matches - filter = { - ...filter, - $or: [ - { firstname: { $regex: query, $options: 'i' } }, - { lastname: { $regex: query, $options: 'i' } }, - { email: { $regex: query, $options: 'i' } }, - ], - }; + "about.gender": 1, + }) + .toArray(); + + if (exactMatches.length > 0) { + return res.status(200).json({ + success: true, + students: exactMatches.sort((a: any, b: any) => + a.about?.gender === mentorGender ? -1 : b.about?.gender === mentorGender ? 1 : 0 + ), + }); } - - const students = await db.collection('users').find(filter).project({ + + filter = { + ...filter, + $or: [ + { firstname: { $regex: query, $options: "i" } }, + { lastname: { $regex: query, $options: "i" } }, + { email: { $regex: query, $options: "i" } }, + ], + }; + } + + // Fetch students with null mentor + const students = await db.collection("users") + .find(filter) + .project({ _id: 1, firstname: 1, lastname: 1, email: 1, academic: 1, mentor: 1, - }).toArray(); - - if (students.length === 0) { - return res.status(404).json({ - success: false, - message: "No students found with null mentor", - }); - } - - res.status(200).json({ - success: true, - students: students, + "about.gender": 1, + }) + .toArray(); + + if (students.length === 0) { + return res.status(404).json({ + success: false, + message: "No students found with null mentor", }); - } catch (error: any) { - console.error(`Error: ${error.message}`); - next(new CustomError(error.message)); } - }; + + // Sort students based on mentor's gender + const sortedStudents = students.sort((a: any, b: any) => + a.about?.gender === mentorGender ? -1 : b.about?.gender === mentorGender ? 1 : 0 + ); + + res.status(200).json({ + success: true, + students: sortedStudents, + }); + } catch (error: any) { + console.error(`Error: ${error.message}`); + next(new CustomError(error.message)); + } +}; + + \ No newline at end of file diff --git a/src/routes/auth.ts b/src/routes/auth.ts index 986e0c2..4557705 100644 --- a/src/routes/auth.ts +++ b/src/routes/auth.ts @@ -12,8 +12,6 @@ import { checkAuth } from "../middleware/checkAuth"; const router = express.Router(); router.post("/register", register); -// router.post("/verify", otpVerification); -// router.post("/resend", resentOtp); router.post("/login", login); router.get("/logout", checkAuth, logout); router.post("/forgetpassword", forgotPassword); @@ -21,3 +19,4 @@ router.put("/resetpassword/:token", checkAuth, resetPassword); router.get("/user", checkAuth, getUser); export default router; + \ No newline at end of file diff --git a/src/routes/mentorRoutes.ts b/src/routes/mentorRoutes.ts index 459e81c..b60fb0b 100644 --- a/src/routes/mentorRoutes.ts +++ b/src/routes/mentorRoutes.ts @@ -1,12 +1,13 @@ import express from "express"; import { checkAuth } from "../middleware/checkAuth"; -import { getMentor, getMentorWithStudents, verifyMentor } from "../controllers/Mentor"; +import { getMentor, getMentorById, getMentorWithStudents, verifyMentor } from "../controllers/Mentor"; const router = express.Router(); -router.get("/getmentor", checkAuth, getMentor); +router.get("/getmentor", getMentor); router.put("/verify/:id", checkAuth, verifyMentor) -router.get("/getstudent/:id", checkAuth, getMentorWithStudents) +router.get("/getMentor/:id", getMentorById) +router.get("/getstudent/:id", getMentorWithStudents) export default router; diff --git a/src/routes/studentRoute.ts b/src/routes/studentRoute.ts index c9ad5ed..10ec288 100644 --- a/src/routes/studentRoute.ts +++ b/src/routes/studentRoute.ts @@ -1,12 +1,14 @@ import express from "express"; import { checkAuth } from "../middleware/checkAuth"; -import { getStudentsWithNullMentor, allocateStudents, deallocateStudents} from "../controllers/Student"; +import { getStudentsWithNullMentor, allocateStudents, deallocateStudents, getStudent, getStudentById} from "../controllers/Student"; const router = express.Router(); -router.post("/allocate-student/:mentorId", checkAuth, allocateStudents) -router.post("/deallocate-student", checkAuth, deallocateStudents) -router.get("/getmentorstudent", checkAuth, getStudentsWithNullMentor) +router.get("/getstudents", getStudent) +router.get("/getstudent/:id", getStudentById) +router.post("/allocate-student/:mentorId", allocateStudents) +router.post("/deallocate-student", deallocateStudents) +router.get("/getmentorstudent", getStudentsWithNullMentor) export default router; diff --git a/src/types/IUser.d.ts b/src/types/IUser.d.ts index cbc9ed2..1b05d06 100644 --- a/src/types/IUser.d.ts +++ b/src/types/IUser.d.ts @@ -18,6 +18,7 @@ interface IUser extends Document { college?: string; degree?: string; dob?: string; + gender?: string; }; students: Array<{ id: mongoose.Types.ObjectId }>; createdAt?: Date;