Skip to content

Commit ff7deea

Browse files
Merge branch 'main' into fix-footer-placeholder-links
2 parents 75626e8 + f02b3c5 commit ff7deea

21 files changed

Lines changed: 1238 additions & 645 deletions

File tree

.github/workflows/auto-label-gssoc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@ jobs:
2727
labels: |
2828
level:intermediate
2929
quality:clean
30+
type:accessibility
3031
gssoc:approved

CONTRIBUTING.md

Lines changed: 93 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,130 +1,130 @@
1-
# 🌟 Contributing to GitHub Tracker
1+
# 🌟 Contributing to GitHub Tracker
22

3-
Thank you for showing interest in **GitHub Tracker**! 🚀
4-
Whether you're here to fix a bug, propose an enhancement, or add a new feature, we’re thrilled to welcome you aboard. Let’s build something awesome together!
3+
Thank you for showing interest in **GitHub Tracker**! 🚀
4+
Whether you're here to fix a bug, propose an enhancement, or add a new feature, we’re thrilled to welcome you aboard. Let’s build something awesome together!
55

6-
<br>
6+
<br>
77

8-
## 🧑‍⚖️ Code of Conduct
8+
## 🧑‍⚖️ Code of Conduct
99

10-
Please make sure to read and adhere to our [Code of Conduct](https://github.com/GitMetricsLab/github_tracker/CODE_OF_CONDUCT.md) before contributing. We aim to foster a respectful and inclusive environment for everyone.
10+
Please make sure to read and adhere to our [Code of Conduct](https://github.com/GitMetricsLab/github_tracker/CODE_OF_CONDUCT.md) before contributing. We aim to foster a respectful and inclusive environment for everyone.
1111

12-
<br>
12+
<br>
1313

14-
## 🛠 Project Structure
14+
## 🛠 Project Structure
1515

16-
```bash
17-
github_tracker/
18-
├── backend/ # Node.js + Express backend
19-
│ ├── routes/ # API routes
20-
│ ├── controllers/ # Logic handlers
21-
│ └── index.js # Entry point for server
22-
23-
├── frontend/ # React + Vite frontend
24-
│ ├── components/ # Reusable UI components
25-
│ ├── pages/ # Main pages/routes
26-
│ └── main.jsx # Root file
27-
28-
├── public/ # Static assets like images
29-
30-
├── .gitignore
31-
├── README.md
32-
├── package.json
33-
├── tailwind.config.js
34-
└── CONTRIBUTING.md
35-
```
16+
```bash
17+
github_tracker/
18+
├── backend/ # Node.js + Express backend
19+
│ ├── routes/ # API routes
20+
│ ├── controllers/ # Logic handlers
21+
│ └── index.js # Entry point for server
22+
23+
├── frontend/ # React + Vite frontend
24+
│ ├── components/ # Reusable UI components
25+
│ ├── pages/ # Main pages/routes
26+
│ └── main.jsx # Root file
27+
28+
├── public/ # Static assets like images
29+
30+
├── .gitignore
31+
├── README.md
32+
├── package.json
33+
├── tailwind.config.js
34+
└── CONTRIBUTING.md
35+
```
3636

37-
---
37+
---
3838

39-
## 🤝 How to Contribute
39+
## 🤝 How to Contribute
4040

41-
### 🧭 First-Time Contribution Steps
41+
### 🧭 First-Time Contribution Steps
4242

43-
1. **Fork the Repository** 🍴
44-
Click "Fork" to create your own copy under your GitHub account.
43+
1. **Fork the Repository** 🍴
44+
Click "Fork" to create your own copy under your GitHub account.
4545

46-
2. **Clone Your Fork** 📥
47-
```bash
48-
git clone https://github.com/<your-username>/github_tracker.git
49-
```
46+
2. **Clone Your Fork** 📥
47+
```bash
48+
git clone https://github.com/<your-username>/github_tracker.git
49+
```
5050

51-
3. **Navigate to the Project Folder** 📁
52-
```bash
53-
cd github_tracker
54-
```
51+
3. **Navigate to the Project Folder** 📁
52+
```bash
53+
cd github_tracker
54+
```
5555

56-
4. **Create a New Branch** 🌿
57-
```bash
58-
git checkout -b your-feature-name
59-
```
56+
4. **Create a New Branch** 🌿
57+
```bash
58+
git checkout -b your-feature-name
59+
```
6060

61-
5. **Make Your Changes**
62-
After modifying files, stage and commit:
61+
5. **Make Your Changes**
62+
After modifying files, stage and commit:
6363

64-
```bash
65-
git add .
66-
git commit -m "✨ Added [feature/fix]: your message"
67-
```
64+
```bash
65+
git add .
66+
git commit -m "✨ Added [feature/fix]: your message"
67+
```
6868

69-
6. **Push Your Branch to GitHub** 🚀
70-
```bash
71-
git push origin your-feature-name
72-
```
69+
6. **Push Your Branch to GitHub** 🚀
70+
```bash
71+
git push origin your-feature-name
72+
```
7373

74-
7. **Open a Pull Request** 🔁
75-
Go to the original repo and click **Compare & pull request**.
76-
77-
---
74+
7. **Open a Pull Request** 🔁
75+
Go to the original repo and click **Compare & pull request**.
76+
77+
---
7878

79-
## 🚦 Pull Request Guidelines
79+
## 🚦 Pull Request Guidelines
8080

81-
### **Split Big Changes into Multiple Commits**
82-
- When making large or complex changes, break them into smaller, logical commits.
83-
- Each commit should represent a single purpose or unit of change (e.g. refactoring, adding a feature, fixing a bug).
84-
---
85-
- ✅ Ensure your code builds and runs without errors.
86-
- 🧪 Include tests where applicable.
87-
- 💬 Add comments if the logic is non-trivial.
88-
- 📸 Attach screenshots for UI-related changes.
89-
- 🔖 Use meaningful commit messages and titles.
81+
### **Split Big Changes into Multiple Commits**
82+
- When making large or complex changes, break them into smaller, logical commits.
83+
- Each commit should represent a single purpose or unit of change (e.g. refactoring, adding a feature, fixing a bug).
84+
---
85+
- ✅ Ensure your code builds and runs without errors.
86+
- 🧪 Include tests where applicable.
87+
- 💬 Add comments if the logic is non-trivial.
88+
- 📸 Attach screenshots for UI-related changes.
89+
- 🔖 Use meaningful commit messages and titles.
9090

91-
---
91+
---
9292

93-
## 🐞 Reporting Issues
93+
## 🐞 Reporting Issues
9494

95-
If you discover a bug or have a suggestion:
95+
If you discover a bug or have a suggestion:
9696

97-
➡️ [Open an Issue](https://github.com/GitMetricsLab/github_tracker/issues/new/choose)
97+
➡️ [Open an Issue](https://github.com/GitMetricsLab/github_tracker/issues/new/choose)
9898

99-
Please include:
99+
Please include:
100100

101-
- **Steps to Reproduce**
102-
- **Expected vs. Actual Behavior**
103-
- **Screenshots/Logs (if any)**
101+
- **Steps to Reproduce**
102+
- **Expected vs. Actual Behavior**
103+
- **Screenshots/Logs (if any)**
104104

105-
---
105+
---
106106

107-
## 🧠 Good Coding Practices
107+
## 🧠 Good Coding Practices
108108

109-
1. **Consistent Style**
110-
Stick to the project's linting and formatting conventions (e.g., ESLint, Prettier, Tailwind classes).
109+
1. **Consistent Style**
110+
Stick to the project's linting and formatting conventions (e.g., ESLint, Prettier, Tailwind classes).
111111
112-
2. **Meaningful Naming**
113-
Use self-explanatory names for variables and functions.
112+
2. **Meaningful Naming**
113+
Use self-explanatory names for variables and functions.
114114
115-
3. **Avoid Duplication**
116-
Keep your code DRY (Don't Repeat Yourself).
115+
3. **Avoid Duplication**
116+
Keep your code DRY (Don't Repeat Yourself).
117117

118-
4. **Testing**
119-
Add unit or integration tests for any new logic.
118+
4. **Testing**
119+
Add unit or integration tests for any new logic.
120120

121-
5. **Review Others’ PRs**
122-
Help others by reviewing their PRs too!
121+
5. **Review Others’ PRs**
122+
Help others by reviewing their PRs too!
123123

124-
---
124+
---
125125

126-
## 🙌 Thank You!
126+
## 🙌 Thank You!
127127

128-
We’re so glad you’re here. Your time and effort are deeply appreciated. Feel free to reach out via Issues or Discussions if you need any help.
128+
We’re so glad you’re here. Your time and effort are deeply appreciated. Feel free to reach out via Issues or Discussions if you need any help.
129129

130-
**Happy Coding!** 💻🚀
130+
**Happy Coding!** 💻🚀

backend/config/passportConfig.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ passport.use(
99
try {
1010
const user = await User.findOne( {email} );
1111
if (!user) {
12-
return done(null, false, { message: 'Email is invalid '});
12+
// Generic message prevents user enumeration
13+
return done(null, false, { message: 'Invalid credentials' });
1314
}
1415

1516
const isMatch = await user.comparePassword(password);
1617
if (!isMatch) {
17-
return done(null, false, { message: 'Invalid password' });
18+
return done(null, false, { message: 'Invalid credentials' });
1819
}
1920

2021
return done(null, {
@@ -34,10 +35,10 @@ passport.serializeUser((user, done) => {
3435
done(null, user.id);
3536
});
3637

37-
// Deserialize user (retrieve user from session)
38+
// Deserialize user — exclude password hash from req.user on every request
3839
passport.deserializeUser(async (id, done) => {
3940
try {
40-
const user = await User.findById(id);
41+
const user = await User.findById(id).select('-password');
4142
done(null, user);
4243
} catch (err) {
4344
done(err, null);

backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"cors": "^2.8.5",
1818
"dotenv": "^16.4.5",
1919
"express": "^4.21.1",
20+
"express-rate-limit": "^7.5.1",
2021
"express-session": "^1.18.1",
2122
"mongoose": "^8.8.2",
2223
"passport": "^0.7.0",

backend/routes/auth.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,29 @@ router.post("/signup", validateRequest(signupSchema), async (req, res) => {
2626
return res.status(400).json({ message: 'User already exists' });
2727
}
2828

29-
res.status(500).json({ message: 'Error creating user', error: err.message });
29+
res.status(500).json({ message: 'Error creating user' });
3030
}
3131
});
3232

33-
// Login route
34-
router.post("/login", validateRequest(loginSchema), passport.authenticate('local'), (req, res) => {
35-
res.status(200).json( { message: 'Login successful', user: req.user } );
33+
// Login route — session is regenerated after successful authentication
34+
// to prevent session fixation; only safe fields returned in the response
35+
router.post("/login", validateRequest(loginSchema), (req, res, next) => {
36+
passport.authenticate('local', (err, user, info) => {
37+
if (err) return next(err);
38+
if (!user) return res.status(401).json({ message: info?.message || 'Invalid credentials' });
39+
40+
req.session.regenerate((regenerateErr) => {
41+
if (regenerateErr) return next(regenerateErr);
42+
43+
req.logIn(user, (loginErr) => {
44+
if (loginErr) return next(loginErr);
45+
res.status(200).json({
46+
message: 'Login successful',
47+
user: { id: user.id, username: user.username, email: user.email },
48+
});
49+
});
50+
});
51+
})(req, res, next);
3652
});
3753

3854
// Logout route
@@ -41,7 +57,7 @@ router.get("/logout", (req, res) => {
4157
req.logout((err) => {
4258

4359
if (err)
44-
return res.status(500).json({ message: 'Logout failed', error: err.message });
60+
return res.status(500).json({ message: 'Logout failed' });
4561
else
4662
res.status(200).json({ message: 'Logged out successfully' });
4763
});

backend/server.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const mongoose = require('mongoose');
33
const session = require('express-session');
44
const passport = require('passport');
55
const bodyParser = require('body-parser');
6+
const rateLimit = require('express-rate-limit');
67
require('dotenv').config();
78
const cors = require('cors');
89

@@ -26,6 +27,19 @@ app.use(session({
2627
app.use(passport.initialize());
2728
app.use(passport.session());
2829

30+
// Rate limiting — 10 attempts per 15-minute window per IP on auth endpoints
31+
const authLimiter = rateLimit({
32+
windowMs: 15 * 60 * 1000,
33+
max: 10,
34+
standardHeaders: true,
35+
legacyHeaders: false,
36+
message: { message: 'Too many attempts, please try again after 15 minutes.' },
37+
skipSuccessfulRequests: true,
38+
});
39+
40+
app.use('/api/auth/login', authLimiter);
41+
app.use('/api/auth/signup', authLimiter);
42+
2943
// Routes
3044
const authRoutes = require('./routes/auth');
3145
app.use('/api/auth', authRoutes);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "GitHub Tracker",
2+
"name": "github-tracker",
33
"private": true,
44
"version": "0.0.0",
55
"type": "module",

0 commit comments

Comments
 (0)