Skip to content

Commit

Permalink
Temp (#549)
Browse files Browse the repository at this point in the history
* --work-start-protected-routing

* --no-token-found-resolved

* --redirect-login-on-session-expiration

* --small-changes

---------

Co-authored-by: SB2318 <[email protected]>
  • Loading branch information
SB2318 and SB2318 authored Sep 15, 2024
1 parent 54cbcf2 commit e7fd715
Show file tree
Hide file tree
Showing 13 changed files with 2,036 additions and 596 deletions.
154 changes: 113 additions & 41 deletions backend/controllers/usersControllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,64 +193,136 @@ module.exports.verifyOtpForForgotPassword = async (req, res) => {
res.status(200).json({ message: 'OTP is valid.' });
};

module.exports.login = async (req, res) => {
try {
const { email, password } = req.body;
module.exports.login = async (req, res) => {
try {
const { email, password } = req.body;

if (!email || !password) {
return res.status(400).json({ error: 'Please provide email and password' });
}

let user = await User.findOne({ email });
if (!user) {
user = await UnverifiedUser.findOne({ email });
if (!user) return res.status(404).json({ error: 'User not found' });
return res.status(403).json({ error: 'Email not verified. Please check your email.' });
}

if (!user.isVerified) {
return res.status(403).json({ error: 'Email not verified. Please check your email.' });
}

const isPasswordValid = await bcrypt.compare(password, user.password);
if (!isPasswordValid) {
return res.status(401).json({ error: 'Invalid password' });
}

// Generate JWT Access Token
const accessToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '15m' } // Short-lived access token
);

// Generate Refresh Token
const refreshToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '7d' } // Longer-lived refresh token
);
console.log('Generated Token:', accessToken);
console.log('Generated Refresh Token', refreshToken)
// Store refresh token in the database
user.refreshToken = refreshToken;
await user.save();

// Set cookies for tokens
res.cookie('accessToken', accessToken, { httpOnly: true, maxAge: 900000 }); // 15 minutes
res.cookie('refreshToken', refreshToken, { httpOnly: true, maxAge: 604800000 }); // 7 days

res.status(200).json({ user, accessToken, refreshToken, message: 'Login Successful' });
} catch (error) {
console.log("Login Error", error);

if (!email || !password) {
return res.status(400).json({ error: 'Please provide email and password' });
if (error.name === 'ValidationError') {
return res.status(400).json({ error: error.message }); // Validation errors
} else {
return res.status(500).json({ error: 'Internal server error' });
}
}
};

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


if (!user) {
module.exports.logout = async (req, res) => {
const { refreshToken } = req.cookies;

user = UnverifiedUser.findOne({email});
if(!user)
return res.status(404).json({ error: 'User not found' });
else
return res.status(403).json({ error: 'Email not verified. Please check your email.' });

}
if (!refreshToken) {
return res.status(400).json({ error: 'Refresh token required' });
}

if (!user.isVerified) {
return res.status(403).json({ error: 'Email not verified. Please check your email.' });
try {
// Find the user and remove the refresh token
const user = await User.findOne({ refreshToken });
if (user) {
user.refreshToken = null;
await user.save();
}


const isPasswordValid = await bcrypt.compare(password, user.password);
// Clear cookies
res.clearCookie('accessToken');
res.clearCookie('refreshToken');

if (!isPasswordValid) {
return res.status(401).json({ error: 'Invalid password' });
res.status(200).json({ message: 'Logout successful' });
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
};

module.exports.refreshToken = async (req, res) => {
const { refreshToken } = req.body;

if (!refreshToken) {
return res.status(401).json({ error: 'Refresh token required' });
}

try {
// Verify the refresh token
const decoded = jwt.verify(refreshToken, process.env.JWT_SECRET);

// Check if the refresh token is valid and associated with the user
const user = await User.findOne({ _id: decoded.userId, refreshToken });
if (!user) {
return res.status(403).json({ error: 'Invalid refresh token' });
}

const token = jwt.sign(
// Generate a new access token
const newAccessToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '1d' }
{ expiresIn: '15m' }
);

user.verificationToken = token;
res.cookie('token', token, { httpOnly: true, maxAge: 86400000 });
res.status(200).json({ user, token, message: "Login Successful" });

// Optionally, generate a new refresh token
const newRefreshToken = jwt.sign(
{ userId: user._id, email: user.email },
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);

// Update the refresh token in the database
user.refreshToken = newRefreshToken;
await user.save();

res.cookie('accessToken', newAccessToken, { httpOnly: true, maxAge: 900000 }); // 15 minutes
res.cookie('refreshToken', newRefreshToken, { httpOnly: true, maxAge: 604800000 }); // 7 days

res.status(200).json({ accessToken: newAccessToken, refreshToken: newRefreshToken });
} catch (error) {
if (error.name === 'ValidationError') {
return res.status(400).json({ error: error.message }); // Validation errors
} else {
return res.status(500).json({ error: 'Internal server error' });
}
res.status(403).json({ error: 'Invalid refresh token' });
}
};

module.exports.logout = (req, res) => {

// Clear the JWT token cookie
res.clearCookie('token');
res.json({ message: 'Logout successful' });
};

module.exports.deleteByUser = async(req,res)=>{
module.exports.deleteByUser = async(req,res)=>{
let token;
if (req.cookies && req.cookies['token']) {
token = req.cookies['token'];
Expand Down Expand Up @@ -285,7 +357,7 @@ module.exports.logout = (req, res) => {
} catch (error) {
res.status(500).json({ error: error.message });
}
}
}


module.exports.deleteByAdmin = async(req,res)=>{
Expand Down
23 changes: 11 additions & 12 deletions backend/middleware/authentcatetoken.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
const jwt = require('jsonwebtoken');

const authenticateToken = (req, res, next) => {
// console.log(req.cookies.token);
const token = req.cookies.token || req.headers['authorization'];
const token = req.cookies.token || req.headers['authorization']?.split(' ')[1];
console.log("Token", token)
if (!token) return res.status(401).json({ error: 'No token provided' });

if (!token) {
return res.status(401).json({ error: 'Access denied. No token provided.' });
}

try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) {
console.error('Token verification error:', err.message);
return res.status(403).json({ error: 'Invalid token' });
}
req.user = user;
next();
} catch (ex) {
res.status(400).json({ error: 'Invalid token.' });
}
});
};

module.exports = authenticateToken;

1 change: 1 addition & 0 deletions backend/models/UserModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const userSchema = new mongoose.Schema({
type: String,
default: null,
},
refreshToken: { type: String, default: null } ,
articles: {
type:Array,
default:[]
Expand Down
6 changes: 5 additions & 1 deletion backend/routes/usersRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const {
updateReadArticles,
collectMonthlyRecordsForReading,
collectMonthlyRecordsForWriting,
checkOtp
checkOtp,
refreshToken
} = require("../controllers/usersControllers");

const { verifyEmail, sendVerificationEmail, Sendverifymail,resendVerificationEmail } = require('../controllers/emailservice');
Expand All @@ -27,6 +28,9 @@ router.post("/user/register", register);
// Login User Route
router.post("/user/login", login);

// Refresh Token
router.post("/user/refreshToken", refreshToken);

// Get profile
router.get('/user/getprofile',getprofile)
// Follow and Unfollow Routes
Expand Down
Loading

0 comments on commit e7fd715

Please sign in to comment.