Skip to content

Commit 1091ac5

Browse files
committed
feat: Implement backend configuration check and test server setup
1 parent 8e7fea7 commit 1091ac5

3 files changed

Lines changed: 159 additions & 105 deletions

File tree

check-config.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env node
2+
require('dotenv').config();
3+
4+
console.log('\n🔍 CHECKING BACKEND CONFIGURATION...\n');
5+
6+
// Check environment variables
7+
console.log('📋 Environment Variables:');
8+
console.log(` PORT: ${process.env.PORT || '5000 (default)'}`);
9+
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'development (default)'}`);
10+
console.log(` JWT_SECRET: ${process.env.JWT_SECRET ? '✅ Set' : '❌ Missing'}`);
11+
console.log(` DATABASE_URL: ${process.env.DATABASE_URL ? '✅ Set' : '❌ Missing'}`);
12+
console.log(` FRONTEND_URL: ${process.env.FRONTEND_URL || 'http://localhost:3000 (default)'}`);
13+
14+
// Check required files
15+
const fs = require('fs');
16+
const path = require('path');
17+
18+
console.log('\n📁 Required Files:');
19+
const requiredFiles = [
20+
'app.js',
21+
'server.js',
22+
'middleware/auth.js',
23+
'middleware/errorHandler.js',
24+
'routers/auth.js',
25+
'controllers/authcontroller.js',
26+
'config/database.js'
27+
];
28+
29+
let allFilesExist = true;
30+
requiredFiles.forEach(file => {
31+
const exists = fs.existsSync(path.join(__dirname, file));
32+
console.log(` ${exists ? '✅' : '❌'} ${file}`);
33+
if (!exists) allFilesExist = false;
34+
});
35+
36+
// Test database connection
37+
console.log('\n🗄️ Testing Database Connection...');
38+
const { sequelize } = require('./config/database');
39+
40+
sequelize.authenticate()
41+
.then(() => {
42+
console.log(' ✅ Database connection successful');
43+
return sequelize.close();
44+
})
45+
.then(() => {
46+
console.log('\n' + '='.repeat(50));
47+
if (allFilesExist) {
48+
console.log('✅ All checks passed! Ready to start server.');
49+
console.log('\n💡 To start the server, run:');
50+
console.log(' npm start');
51+
console.log(' or');
52+
console.log(' node server.js');
53+
} else {
54+
console.log('❌ Some files are missing. Please check above.');
55+
}
56+
console.log('='.repeat(50) + '\n');
57+
process.exit(0);
58+
})
59+
.catch(err => {
60+
console.log(' ❌ Database connection failed:');
61+
console.log(' ', err.message);
62+
console.log('\n' + '='.repeat(50));
63+
console.log('❌ Database connection issue. Check your .env file.');
64+
console.log('='.repeat(50) + '\n');
65+
process.exit(1);
66+
});

middleware/auth.js

Lines changed: 54 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,104 @@
11
const jwt = require('jsonwebtoken');
2-
const { User } = require('../models');
32

43
/**
5-
* Ensures the request has a valid, unexpired token and attaches the decoded
6-
* user data (including userId, role, and guestId) to req.user.
4+
* Middleware to authenticate JWT token
75
*/
8-
const authenticateToken = async (req, res, next) => {
6+
const authenticateToken = (req, res, next) => {
97
try {
8+
// Get token from header
109
const authHeader = req.headers['authorization'];
11-
const token = authHeader && authHeader.split(' ')[1];
10+
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
1211

1312
if (!token) {
14-
return res.status(401).json({
13+
return res.status(401).json({
1514
success: false,
16-
error: 'Access token required'
15+
error: 'Access token is required'
1716
});
1817
}
1918

20-
// 1. Verify and Decode the token
21-
const decoded = jwt.verify(token, process.env.JWT_SECRET);
22-
23-
// 2. Attach the DECODED JWT payload to req.user
24-
// This payload already contains userId, role, and guestId (if present in the token).
25-
// This allows controllers to access req.user.guestId, req.user.userId, etc., without
26-
// needing another complex database query here.
27-
req.user = decoded;
28-
29-
// Optional Security Check: Verify user still exists in the database
30-
// We only select essential, existing columns (user_id, username)
31-
const user = await User.findByPk(decoded.userId, {
32-
attributes: ['user_id', 'username']
33-
});
34-
35-
if (!user) {
36-
return res.status(401).json({
37-
success: false,
38-
error: 'Invalid token or user not found in database'
39-
});
40-
}
19+
// Verify token
20+
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
21+
if (err) {
22+
return res.status(403).json({
23+
success: false,
24+
error: 'Invalid or expired token'
25+
});
26+
}
4127

42-
// Since the database does not have an 'is_active' column, we remove that faulty check entirely.
43-
44-
next();
28+
// Attach user info to request
29+
req.user = user;
30+
next();
31+
});
4532
} catch (error) {
46-
// This catches JWT errors (expired, tampered, invalid signature)
47-
// The previous error of 'user inactive' is now resolved.
48-
return res.status(403).json({
33+
return res.status(500).json({
4934
success: false,
50-
error: 'Invalid or expired token'
35+
error: 'Token authentication failed'
5136
});
5237
}
5338
};
5439

5540
/**
56-
* Authorizes the user based on their role included in the JWT payload.
41+
* Middleware to authorize based on user roles
42+
* Usage: authorizeRoles('Admin', 'Manager')
5743
*/
58-
// In middleware/auth.js
59-
60-
// const authorizeRoles = (...roles) => {
61-
// return (req, res, next) => {
62-
63-
// // 1. Check 1: Ensure the user object is attached and has a role property.
64-
// // We must return a clear error if the role is truly missing from the token.
65-
// if (!req.user || req.user.role === undefined || req.user.role === null) {
66-
// return res.status(403).json({
67-
// success: false,
68-
// error: 'Access denied. User role not defined in token.' // More specific message
69-
// });
70-
// }
71-
72-
// // 2. Perform Case-Insensitive Comparison
73-
// // Ensure the role is treated as a string before calling toLowerCase().
74-
// const userRole = String(req.user.role).toLowerCase();
75-
// const allowedRoles = roles.map(role => String(role).toLowerCase()); // Also convert allowed roles to strings
76-
77-
// if (!allowedRoles.includes(userRole)) {
78-
// return res.status(403).json({
79-
// success: false,
80-
// error: 'Access denied. Insufficient permissions.'
81-
// });
82-
// }
83-
84-
// next();
85-
// };
86-
// };
87-
88-
const authorizeRoles = (...roles) => {
44+
const authorizeRoles = (...allowedRoles) => {
8945
return (req, res, next) => {
90-
// 1. Ensure req.user and req.user.role exist
91-
if (!req.user || !req.user.role) {
92-
return res.status(403).json({
46+
if (!req.user) {
47+
return res.status(401).json({
9348
success: false,
94-
error: 'Access denied. User role not defined in token.'
49+
error: 'Authentication required'
9550
});
9651
}
9752

98-
// 2. Normalize user role: trim spaces and lowercase
99-
const userRole = String(req.user.role).trim().toLowerCase();
100-
101-
// 3. Normalize allowed roles
102-
const allowedRoles = roles.map(role => String(role).trim().toLowerCase());
53+
const userRole = req.user.role;
10354

104-
// 4. Debug: log roles (remove or comment out in production)
105-
console.log(`DEBUG: userRole="${userRole}", allowedRoles=[${allowedRoles.join(', ')}]`);
106-
107-
// 5. Check if the user's role exists in allowedRoles
55+
// Check if user's role is in the allowed roles
10856
if (!allowedRoles.includes(userRole)) {
10957
return res.status(403).json({
11058
success: false,
111-
error: `Access denied. User role "${req.user.role}" insufficient.`
59+
error: `Access denied. Required roles: ${allowedRoles.join(', ')}`
11260
});
11361
}
11462

11563
next();
11664
};
11765
};
11866

119-
module.exports = { authorizeRoles };
120-
121-
122-
123-
12467
/**
125-
* Optionally authenticates a token if one is present, but allows the request to continue if not.
68+
* Optional authentication - doesn't fail if no token
69+
* Useful for endpoints that work for both authenticated and public users
12670
*/
127-
const optionalAuth = async (req, res, next) => {
71+
const optionalAuth = (req, res, next) => {
12872
try {
12973
const authHeader = req.headers['authorization'];
13074
const token = authHeader && authHeader.split(' ')[1];
13175

132-
if (token) {
133-
const decoded = jwt.verify(token, process.env.JWT_SECRET);
134-
135-
// Optionally verify user existence again, but primarily attach the payload data
136-
const user = await User.findByPk(decoded.userId, {
137-
attributes: ['user_id', 'username']
138-
});
76+
if (!token) {
77+
// No token provided, continue without user
78+
req.user = null;
79+
return next();
80+
}
13981

140-
if (user) {
141-
req.user = decoded;
82+
// Verify token if provided
83+
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
84+
if (err) {
85+
// Invalid token, continue without user
86+
req.user = null;
87+
} else {
88+
// Valid token, attach user
89+
req.user = user;
14290
}
143-
}
144-
next();
91+
next();
92+
});
14593
} catch (error) {
146-
// Do not throw an error if token is invalid/expired; just proceed without req.user
94+
// Error in processing, continue without user
95+
req.user = null;
14796
next();
14897
}
14998
};
15099

151-
module.exports = {
152-
authenticateToken,
153-
authorizeRoles,
154-
optionalAuth
155-
};
100+
module.exports = {
101+
authenticateToken,
102+
authorizeRoles,
103+
optionalAuth
104+
};

test-server.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
require('dotenv').config();
2+
const express = require('express');
3+
const cors = require('cors');
4+
5+
const app = express();
6+
const PORT = process.env.PORT || 5000;
7+
8+
// CORS configuration
9+
app.use(cors({
10+
origin: ['http://localhost:3000', 'https://nadeeshanj.github.io'],
11+
credentials: true
12+
}));
13+
14+
app.use(express.json());
15+
16+
// Test route
17+
app.get('/api/health', (req, res) => {
18+
res.json({
19+
success: true,
20+
message: 'Backend is running!',
21+
timestamp: new Date().toISOString()
22+
});
23+
});
24+
25+
// Test login route
26+
app.post('/api/auth/login', (req, res) => {
27+
console.log('Login attempt:', req.body);
28+
res.json({
29+
success: true,
30+
message: 'Login endpoint is working',
31+
received: req.body
32+
});
33+
});
34+
35+
app.listen(PORT, () => {
36+
console.log(`\n✅ Test server running on http://localhost:${PORT}`);
37+
console.log(`🔗 Health check: http://localhost:${PORT}/api/health`);
38+
console.log(`🔐 Login endpoint: http://localhost:${PORT}/api/auth/login\n`);
39+
});

0 commit comments

Comments
 (0)