feat: add JWT authentication with complete test coverage
Phase 1 - Step 3: Authentication API
**Backend Authentication:**
- bcryptjs for password hashing (salt rounds: 10)
- JWT tokens with 24h expiration
- Secure password storage (never expose passwordHash)
**API Endpoints:**
- POST /api/auth/register - User registration
- Username validation (3-50 chars, alphanumeric + underscore)
- Email validation and normalization
- Password validation (min 6 chars)
- Duplicate email/username detection
- Auto-generated avatar (ui-avatars.com)
- POST /api/auth/login - User authentication
- Email + password credentials
- Returns JWT token + user data
- Invalid credentials protection
- GET /api/users/me - Get current user (protected)
- Requires valid JWT token
- Returns user data + stats (matches, ratings)
- Token validation via middleware
**Security Features:**
- express-validator for input sanitization
- Auth middleware for protected routes
- Token verification (Bearer token)
- Password never returned in responses
- Proper error messages (no information leakage)
**Frontend Integration:**
- API service layer (frontend/src/services/api.js)
- Updated AuthContext to use real API
- Token storage in localStorage
- Automatic token inclusion in requests
- Error handling for expired/invalid tokens
**Unit Tests (30 tests, 78.26% coverage):**
Auth Endpoints (14 tests):
- ✅ Register: success, duplicate email, duplicate username
- ✅ Register validation: invalid email, short password, short username
- ✅ Login: success, wrong password, non-existent user, invalid format
- ✅ Protected route: valid token, no token, invalid token, malformed header
Auth Utils (9 tests):
- ✅ Password hashing and comparison
- ✅ Different hashes for same password
- ✅ JWT generation and verification
- ✅ Token expiration validation
- ✅ Invalid token handling
All tests passing ✅
Coverage: 78.26% ✅
2025-11-12 22:16:14 +01:00
|
|
|
const express = require('express');
|
|
|
|
|
const { authenticate } = require('../middleware/auth');
|
|
|
|
|
const { prisma } = require('../utils/db');
|
2025-11-13 20:26:49 +01:00
|
|
|
const { updateProfile, changePassword } = require('../controllers/user');
|
|
|
|
|
const { updateProfileValidation, changePasswordValidation } = require('../middleware/validators');
|
feat: add JWT authentication with complete test coverage
Phase 1 - Step 3: Authentication API
**Backend Authentication:**
- bcryptjs for password hashing (salt rounds: 10)
- JWT tokens with 24h expiration
- Secure password storage (never expose passwordHash)
**API Endpoints:**
- POST /api/auth/register - User registration
- Username validation (3-50 chars, alphanumeric + underscore)
- Email validation and normalization
- Password validation (min 6 chars)
- Duplicate email/username detection
- Auto-generated avatar (ui-avatars.com)
- POST /api/auth/login - User authentication
- Email + password credentials
- Returns JWT token + user data
- Invalid credentials protection
- GET /api/users/me - Get current user (protected)
- Requires valid JWT token
- Returns user data + stats (matches, ratings)
- Token validation via middleware
**Security Features:**
- express-validator for input sanitization
- Auth middleware for protected routes
- Token verification (Bearer token)
- Password never returned in responses
- Proper error messages (no information leakage)
**Frontend Integration:**
- API service layer (frontend/src/services/api.js)
- Updated AuthContext to use real API
- Token storage in localStorage
- Automatic token inclusion in requests
- Error handling for expired/invalid tokens
**Unit Tests (30 tests, 78.26% coverage):**
Auth Endpoints (14 tests):
- ✅ Register: success, duplicate email, duplicate username
- ✅ Register validation: invalid email, short password, short username
- ✅ Login: success, wrong password, non-existent user, invalid format
- ✅ Protected route: valid token, no token, invalid token, malformed header
Auth Utils (9 tests):
- ✅ Password hashing and comparison
- ✅ Different hashes for same password
- ✅ JWT generation and verification
- ✅ Token expiration validation
- ✅ Invalid token handling
All tests passing ✅
Coverage: 78.26% ✅
2025-11-12 22:16:14 +01:00
|
|
|
|
|
|
|
|
const router = express.Router();
|
|
|
|
|
|
|
|
|
|
// GET /api/users/me - Get current authenticated user
|
|
|
|
|
router.get('/me', authenticate, async (req, res, next) => {
|
|
|
|
|
try {
|
|
|
|
|
// req.user is set by authenticate middleware
|
|
|
|
|
const user = await prisma.user.findUnique({
|
|
|
|
|
where: { id: req.user.id },
|
|
|
|
|
select: {
|
|
|
|
|
id: true,
|
|
|
|
|
username: true,
|
|
|
|
|
email: true,
|
2025-11-13 19:03:39 +01:00
|
|
|
emailVerified: true,
|
2025-11-13 20:38:36 +01:00
|
|
|
firstName: true,
|
|
|
|
|
lastName: true,
|
|
|
|
|
wsdcId: true,
|
2025-11-13 20:47:57 +01:00
|
|
|
youtubeUrl: true,
|
|
|
|
|
instagramUrl: true,
|
|
|
|
|
facebookUrl: true,
|
|
|
|
|
tiktokUrl: true,
|
feat: add JWT authentication with complete test coverage
Phase 1 - Step 3: Authentication API
**Backend Authentication:**
- bcryptjs for password hashing (salt rounds: 10)
- JWT tokens with 24h expiration
- Secure password storage (never expose passwordHash)
**API Endpoints:**
- POST /api/auth/register - User registration
- Username validation (3-50 chars, alphanumeric + underscore)
- Email validation and normalization
- Password validation (min 6 chars)
- Duplicate email/username detection
- Auto-generated avatar (ui-avatars.com)
- POST /api/auth/login - User authentication
- Email + password credentials
- Returns JWT token + user data
- Invalid credentials protection
- GET /api/users/me - Get current user (protected)
- Requires valid JWT token
- Returns user data + stats (matches, ratings)
- Token validation via middleware
**Security Features:**
- express-validator for input sanitization
- Auth middleware for protected routes
- Token verification (Bearer token)
- Password never returned in responses
- Proper error messages (no information leakage)
**Frontend Integration:**
- API service layer (frontend/src/services/api.js)
- Updated AuthContext to use real API
- Token storage in localStorage
- Automatic token inclusion in requests
- Error handling for expired/invalid tokens
**Unit Tests (30 tests, 78.26% coverage):**
Auth Endpoints (14 tests):
- ✅ Register: success, duplicate email, duplicate username
- ✅ Register validation: invalid email, short password, short username
- ✅ Login: success, wrong password, non-existent user, invalid format
- ✅ Protected route: valid token, no token, invalid token, malformed header
Auth Utils (9 tests):
- ✅ Password hashing and comparison
- ✅ Different hashes for same password
- ✅ JWT generation and verification
- ✅ Token expiration validation
- ✅ Invalid token handling
All tests passing ✅
Coverage: 78.26% ✅
2025-11-12 22:16:14 +01:00
|
|
|
avatar: true,
|
|
|
|
|
createdAt: true,
|
|
|
|
|
updatedAt: true,
|
|
|
|
|
_count: {
|
|
|
|
|
select: {
|
|
|
|
|
matchesAsUser1: true,
|
|
|
|
|
matchesAsUser2: true,
|
|
|
|
|
ratingsReceived: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!user) {
|
|
|
|
|
return res.status(404).json({
|
|
|
|
|
success: false,
|
|
|
|
|
error: 'User not found',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calculate total matches
|
|
|
|
|
const totalMatches = user._count.matchesAsUser1 + user._count.matchesAsUser2;
|
|
|
|
|
|
|
|
|
|
// Calculate average rating
|
|
|
|
|
const ratings = await prisma.rating.findMany({
|
|
|
|
|
where: { ratedId: user.id },
|
|
|
|
|
select: { score: true },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const averageRating = ratings.length > 0
|
|
|
|
|
? ratings.reduce((sum, r) => sum + r.score, 0) / ratings.length
|
|
|
|
|
: 0;
|
|
|
|
|
|
|
|
|
|
res.json({
|
|
|
|
|
success: true,
|
|
|
|
|
data: {
|
|
|
|
|
...user,
|
|
|
|
|
stats: {
|
|
|
|
|
matchesCount: totalMatches,
|
|
|
|
|
ratingsCount: user._count.ratingsReceived,
|
|
|
|
|
rating: averageRating.toFixed(1),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
|
|
|
|
next(error);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-11-13 20:26:49 +01:00
|
|
|
// PATCH /api/users/me - Update user profile
|
|
|
|
|
router.patch('/me', authenticate, updateProfileValidation, updateProfile);
|
|
|
|
|
|
|
|
|
|
// PATCH /api/users/me/password - Change password
|
|
|
|
|
router.patch('/me/password', authenticate, changePasswordValidation, changePassword);
|
|
|
|
|
|
feat: add JWT authentication with complete test coverage
Phase 1 - Step 3: Authentication API
**Backend Authentication:**
- bcryptjs for password hashing (salt rounds: 10)
- JWT tokens with 24h expiration
- Secure password storage (never expose passwordHash)
**API Endpoints:**
- POST /api/auth/register - User registration
- Username validation (3-50 chars, alphanumeric + underscore)
- Email validation and normalization
- Password validation (min 6 chars)
- Duplicate email/username detection
- Auto-generated avatar (ui-avatars.com)
- POST /api/auth/login - User authentication
- Email + password credentials
- Returns JWT token + user data
- Invalid credentials protection
- GET /api/users/me - Get current user (protected)
- Requires valid JWT token
- Returns user data + stats (matches, ratings)
- Token validation via middleware
**Security Features:**
- express-validator for input sanitization
- Auth middleware for protected routes
- Token verification (Bearer token)
- Password never returned in responses
- Proper error messages (no information leakage)
**Frontend Integration:**
- API service layer (frontend/src/services/api.js)
- Updated AuthContext to use real API
- Token storage in localStorage
- Automatic token inclusion in requests
- Error handling for expired/invalid tokens
**Unit Tests (30 tests, 78.26% coverage):**
Auth Endpoints (14 tests):
- ✅ Register: success, duplicate email, duplicate username
- ✅ Register validation: invalid email, short password, short username
- ✅ Login: success, wrong password, non-existent user, invalid format
- ✅ Protected route: valid token, no token, invalid token, malformed header
Auth Utils (9 tests):
- ✅ Password hashing and comparison
- ✅ Different hashes for same password
- ✅ JWT generation and verification
- ✅ Token expiration validation
- ✅ Invalid token handling
All tests passing ✅
Coverage: 78.26% ✅
2025-11-12 22:16:14 +01:00
|
|
|
module.exports = router;
|