Skip to content

Commit

Permalink
Merge pull request #53 from SLIIT-24-25J-047-Research/Development
Browse files Browse the repository at this point in the history
shedule interview - backend
  • Loading branch information
BoshithaMGunarathna authored Dec 31, 2024
2 parents 918123f + 414a202 commit f1b0a1c
Show file tree
Hide file tree
Showing 29 changed files with 2,085 additions and 122 deletions.
138 changes: 128 additions & 10 deletions backend/controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const User = require("../models/User");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const { OAuth2Client } = require('google-auth-library'); // Import Google OAuth2 client
const client = new OAuth2Client(process.env.GOOGLE_CLIENT_ID); // Your Google Client ID


// Register User
const register = async (req, res) => {
Expand Down Expand Up @@ -48,44 +51,45 @@ const login = async (req, res) => {
try {
console.log("Checking for user with email:", email);

// Check if user exists
const user = await User.findOne({ email });
// Check if user exists and include the password in the query
const user = await User.findOne({ email }).select("+password");
if (!user) {
console.log("User not found");
return res.status(404).json({ message: "User not found" }); // Return response and stop further execution
return res.status(404).json({ message: "User not found" });
}

console.log("User found:");
console.log("User found");

// Check if password matches
const isMatch = await user.comparePassword(password);
if (!isMatch) {
console.log("Password mismatch");
return res.status(400).json({ message: "Invalid credentials" }); // Return response and stop further execution
return res.status(400).json({ message: "Invalid credentials" });
}

console.log("Password match, generating token");

// Generate JWT token
const token = jwt.sign(
{ id: user._id, role: user.role, email: user.email }, // Include email in JWT payload
{ id: user._id, role: user.role, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: "1h" } // Token expiration time
{ expiresIn: "1h" }
);

// Send back the token, user role, and email
return res.json({
token,
role: user.role,
email: user.email, // Include email in the response
email: user.email,
});
} catch (error) {
console.error("Error during login:", error);
return res.status(500).json({ message: "Server error" }); // Return response and stop further execution
return res.status(500).json({ message: "Server error" });
}
};



// Get logged-in user data based on email query
const getUserData = async (req, res) => {
const { email } = req.query; // Retrieve the email from query parameters
Expand Down Expand Up @@ -117,5 +121,119 @@ const getUserData = async (req, res) => {
};

//---
const googleLogin = async (req, res) => {
const { token } = req.body;

try {
const ticket = await client.verifyIdToken({
idToken: token,
audience: process.env.GOOGLE_CLIENT_ID,
});

const payload = ticket.getPayload(); // Google payload
console.log("Backend Google Payload:", payload); // Log in backend terminal

const email = payload.email.toLowerCase();
console.log("Email Being Queried:", email); // Log queried email

let user = await User.findOne({ email });

if (!user) {
console.log("User Not Found, Creating New User...");
user = new User({
email,
name: payload.name,
role: 'candidate',
googleId: payload.sub,
});
await user.save();
} else {
console.log("User Found:", user);
}

const jwtToken = jwt.sign(
{ id: user._id, role: user.role, email: user.email, googleId: user.googleId },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
);

return res.json({ token: jwtToken, role: user.role, email: user.email });
} catch (error) {
console.error("Google Login Error:", error);
return res.status(500).json({ message: "Server error" });
}
};


const googleSignup = async (req, res) => {
const { token } = req.body;

try {
// Verify the Google token
const ticket = await client.verifyIdToken({
idToken: token,
audience: process.env.GOOGLE_CLIENT_ID,
});

// Extract user information from the Google token
const payload = ticket.getPayload();
const { email, name, sub: googleId } = payload;

// Check if the user already exists in the database
let existingUser = await User.findOne({ email });
if (existingUser) {
// If user exists, verify Google ID to confirm ownership
if (existingUser.googleId && existingUser.googleId === googleId) {
// Generate a new token and log them in
const jwtToken = jwt.sign(
{ id: existingUser._id, role: existingUser.role },
process.env.JWT_SECRET,
{ expiresIn: "1h" }
);

return res.status(200).json({
message: "Logged in successfully",
token: jwtToken,
role: existingUser.role,
});
} else {
// Google ID mismatch; potential security issue
return res.status(403).json({
message: "Account already exists but Google ID does not match. Please use your registered method to log in.",
});
}
}

// If the user doesn't exist, create a new user with Google ID
const newUser = new User({
email,
name,
role: 'candidate',
googleId, // Store the Google ID here
});

await newUser.save();

// Generate JWT token for the new user
const newToken = jwt.sign(
{ id: newUser._id, role: newUser.role },
process.env.JWT_SECRET,
{ expiresIn: "1h" }
);

// Return the token and user role
res.status(201).json({
message: "Google signup successful",
token: newToken,
role: newUser.role,
});
} catch (error) {
console.error("Error during Google signup:", error);
res.status(500).json({ message: "Server error" });
}
};




module.exports = { login, register, getUserData };
module.exports = { login, register, getUserData, googleLogin, googleSignup };
27 changes: 23 additions & 4 deletions backend/controllers/employer/JobsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,32 @@ const JobsModel = require ('../../models/employer/JobsModel.js');
// Create a new job
const createJob = async (req, res) => {
try {
const newJob = new JobsModel(req.body);
// Find the last created job based on jobID (assuming jobID follows the pattern "vacancy01", "vacancy02", etc.)
const lastJob = await JobsModel.findOne().sort({ jobID: -1 }); // Sort by jobID in descending order

let newJobID = "vacancy01"; // Default to "vacancy01" if no jobs exist

if (lastJob) {
// Extract the number part from the last job's jobID (e.g., "vacancy01" -> 1)
const lastJobNumber = parseInt(lastJob.jobID.replace("vacancy", ""));

// Increment the number by 1
const newJobNumber = lastJobNumber + 1;

// Generate the new jobID (padding with leading zeros to maintain two digits)
newJobID = `vacancy${String(newJobNumber).padStart(2, '0')}`;
}

// Create a new job with the generated jobID
const newJob = new JobsModel({
...req.body, // The rest of the job details come from the request body
jobID: newJobID, // Set the new jobID
});

await newJob.save();
res.status(201).json({ message: "Job created successfully", job: newJob });
} catch (error) {
res
.status(500)
.json({ message: "Failed to create job", error: error.message });
res.status(500).json({ message: "Failed to create job", error: error.message });
}
};

Expand Down
156 changes: 156 additions & 0 deletions backend/controllers/employer/NonTechInterviewController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
const InterviewSchedule = require('../../models/employer/NonTechInterviewSchedule');
const User = require('../../models/User');

const scheduleInterview = async (req, res) => {
try {
const { userId, userName, interviewTime, media } = req.body;

// Validate user
const user = await User.findById(userId);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}

// Check if the user already has an interview scheduled within the next 3 days
const existingInterview = await InterviewSchedule.findOne({
userId,
interviewDate: { $gte: new Date(), $lt: new Date(new Date().setDate(new Date().getDate() + 3)) }, // Check for interviews within the next 3 days
});

if (existingInterview) {
return res.status(400).json({ message: 'User already has an interview scheduled within the next 3 days. Please update the existing schedule.' });
}


const interviewDate = new Date();
interviewDate.setDate(interviewDate.getDate() + 3);

const newInterview = new InterviewSchedule({
userId,
userName,
interviewDate,
interviewTime,
media,
});

await newInterview.save();

return res.status(201).json({ message: 'Interview scheduled successfully', interview: newInterview });
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Error scheduling interview', error });
}
};


const editInterview = async (req, res) => {
try {
const { id } = req.params;
const { interviewDate, interviewTime, media } = req.body;

// Find the interview
const interview = await InterviewSchedule.findById(id);
if (!interview) {
return res.status(404).json({ message: 'Interview not found' });
}

const currentDate = new Date();
const interviewScheduledDate = new Date(interview.interviewDate);

// Block updates attempted on the interview day
if (currentDate.toISOString().split('T')[0] === interviewScheduledDate.toISOString().split('T')[0]) {
return res.status(400).json({
message: 'Cannot update the interview on the same day as the interview date.',
});
}

// Check if the new interview date is in the past
if (interviewDate && new Date(interviewDate) < currentDate) {
return res.status(400).json({
message: 'The updated interview date cannot be in the past.',
});
}


interview.interviewDate = interviewDate || interview.interviewDate;
interview.interviewTime = interviewTime || interview.interviewTime;
interview.media = media || interview.media;
interview.status = 'updated';

await interview.save();

return res.status(200).json({ message: 'Interview updated successfully', interview });
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Error updating interview', error });
}
};




const cancelInterview = async (req, res) => {
try {
const { id } = req.params; // Interview ID

const interview = await InterviewSchedule.findById(id);
if (!interview) {
return res.status(404).json({ message: 'Interview not found' });
}

// Update the status to "canceled"
interview.status = 'canceled';

await interview.save();

return res.status(200).json({ message: 'Interview canceled successfully', interview });
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Error canceling interview', error });
}
};

const getAllSchedules = async (req, res) => {
try {
const schedules = await InterviewSchedule.find();
return res.status(200).json({ message: 'All interview schedules retrieved', schedules });
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Error retrieving schedules', error });
}
}

// Get by ID
const getScheduleById = async (req, res) => {
try {
const { id } = req.params;

const schedule = await InterviewSchedule.findById(id);
if (!schedule) {
return res.status(404).json({ message: 'Schedule not found' });
}

return res.status(200).json({ message: 'Schedule retrieved', schedule });
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Error retrieving schedule', error });
}
};

const getSchedulesByUserId = async (req, res) => {
try {
const { userId } = req.params;

const schedules = await InterviewSchedule.find({ userId });
if (schedules.length === 0) {
return res.status(404).json({ message: 'No schedules found for this user' });
}

return res.status(200).json({ message: 'Schedules retrieved for user', schedules });
} catch (error) {
console.error(error);
return res.status(500).json({ message: 'Error retrieving schedules by user ID', error });
}
};

module.exports = { scheduleInterview, editInterview, cancelInterview, getAllSchedules, getScheduleById, getSchedulesByUserId };
Loading

0 comments on commit f1b0a1c

Please sign in to comment.