Skip to content

Commit 7ac4a19

Browse files
committed
Added JWT Auth system in backend folder
1 parent 68d4ded commit 7ac4a19

File tree

3,302 files changed

+392337
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

3,302 files changed

+392337
-0
lines changed

backend/.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
PORT=3000
2+
MONGODB_URI=mongodb://127.0.0.1:27017/auth-task
3+
JWT_SECRET=yourSuperSecretKey

backend/config/db.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const mongoose = require('mongoose');
2+
3+
const connectDB = async () => {
4+
try {
5+
await mongoose.connect(process.env.MONGODB_URI);
6+
console.log('MongoDB connected');
7+
} catch (error) {
8+
console.error('MongoDB connection failed:', error.message);
9+
process.exit(1);
10+
}
11+
};
12+
13+
module.exports = connectDB;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const jwt = require('jsonwebtoken');
2+
const User = require('../models/user.model');
3+
4+
// Register
5+
exports.register = async (req, res) => {
6+
const { fullName, email, password } = req.body;
7+
8+
try {
9+
const existingUser = await User.findOne({ email });
10+
if (existingUser) return res.status(400).json({ error: 'Email already registered' });
11+
12+
const newUser = new User({ fullName, email, password });
13+
await newUser.save();
14+
res.status(201).json({ message: 'User registered successfully' });
15+
} catch (err) {
16+
res.status(500).json({ error: 'Server error during registration' });
17+
}
18+
};
19+
20+
// Login
21+
exports.login = async (req, res) => {
22+
const { email, password } = req.body;
23+
24+
try {
25+
const user = await User.findOne({ email });
26+
if (!user || user.password !== password) {
27+
return res.status(401).json({ error: 'Invalid email or password' });
28+
}
29+
30+
const payload = { userId: user._id };
31+
const token = jwt.sign(payload, process.env.JWT_SECRET, { expiresIn: '1h' });
32+
33+
res.status(200).json({
34+
message: 'Login successful',
35+
token,
36+
expiresIn: 3600, // 1 hour in seconds
37+
user: {
38+
fullName: user.fullName,
39+
email: user.email,
40+
isEmailVerified: user.isEmailVerified
41+
}
42+
});
43+
} catch (err) {
44+
res.status(500).json({ error: 'Server error during login' });
45+
}
46+
};
47+
48+
49+
// reset password token
50+
exports.resetPasswordRequest = async (req, res) => {
51+
const { email } = req.body;
52+
53+
try {
54+
const user = await User.findOne({ email });
55+
if (!user) return res.status(404).json({ error: 'User not found' });
56+
57+
const resetToken = jwt.sign(
58+
{ userId: user._id },
59+
process.env.JWT_SECRET,
60+
{ expiresIn: '15m' }
61+
);
62+
63+
res.json({ message: 'Reset token generated', resetToken });
64+
} catch (err) {
65+
res.status(500).json({ error: 'Server error' });
66+
}
67+
};
68+
69+
// Set new password
70+
exports.setNewPassword = async (req, res) => {
71+
const { token, newPassword } = req.body;
72+
73+
try {
74+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
75+
const user = await User.findById(decoded.userId);
76+
if (!user) return res.status(404).json({ error: 'User not found' });
77+
78+
user.password = newPassword;
79+
await user.save();
80+
81+
res.json({ message: 'Password has been updated' });
82+
} catch (err) {
83+
res.status(400).json({ error: 'Invalid or expired token' });
84+
}
85+
};
86+
87+
// Logout
88+
exports.logout = async (req, res) => {
89+
res.status(200).json({ message: 'Logged out successfully' });
90+
};
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const jwt = require('jsonwebtoken');
2+
3+
module.exports = (req, res, next) => {
4+
const authHeader = req.headers.authorization;
5+
6+
7+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
8+
return res.status(401).json({ error: 'Authorization token missing' });
9+
}
10+
11+
const token = authHeader.split(' ')[1];
12+
13+
try {
14+
// Verify token
15+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
16+
req.userId = decoded.userId;
17+
next();
18+
} catch (error) {
19+
// Handle expired token
20+
if (error.name === 'TokenExpiredError') {
21+
return res.status(401).json({ error: 'Token has expired. Please log in again.' });
22+
}
23+
24+
// Handle invalid token
25+
if (error.name === 'JsonWebTokenError') {
26+
return res.status(401).json({ error: 'Invalid token. Authentication failed.' });
27+
}
28+
29+
// Generic error fallback
30+
return res.status(401).json({ error: 'Unauthorized access' });
31+
}
32+
};

backend/models/user.model.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const mongoose = require('mongoose');
2+
3+
const userSchema = new mongoose.Schema({
4+
fullName: {
5+
type: String,
6+
required: true,
7+
trim: true
8+
},
9+
email: {
10+
type: String,
11+
required: true,
12+
unique: true,
13+
lowercase: true,
14+
trim: true
15+
},
16+
password: {
17+
type: String,
18+
required: true
19+
},
20+
isEmailVerified: {
21+
type: Boolean,
22+
default: false
23+
}
24+
}, { timestamps: true });
25+
26+
module.exports = mongoose.model('User', userSchema);

backend/node_modules/.bin/node-gyp-build

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/node_modules/.bin/node-gyp-build-optional

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/node_modules/.bin/node-gyp-build-optional.cmd

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/node_modules/.bin/node-gyp-build-optional.ps1

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/node_modules/.bin/node-gyp-build-test

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)