feat: Implement complete user authentication system with security hardening and comprehensive testing
What does this MR do?
This merge request introduces a production-ready user authentication system for the task manager application, implementing email/password login with session management, comprehensive security controls, and full-stack testing coverage.
Key implementations:
-
Backend (FastAPI + MySQL):
- User registration and authentication endpoints with bcrypt password hashing
- Session-based authentication with 24-hour expiration and 5-session limit per user
- Rate limiting (5 login attempts per 15 minutes) to prevent brute-force attacks
- SQLAlchemy ORM with domain models (User, Session) following clean architecture
- Environment-based configuration with pydantic-settings
- Comprehensive API schema validation with Pydantic
-
Frontend (React 19 + TypeScript):
- Complete authentication UI with login, registration, and protected routes
- AuthContext for global authentication state management
- Route guards (PublicRoute, ProtectedRoute) with redirect logic
- shadcn/ui component library integration for modern UI
- Centralized API service layer with error handling
-
Database:
- dbmate migration system with users and sessions tables
- Proper indexing on email, user_id, and expires_at for performance
- Foreign key constraints with CASCADE delete for data integrity
- UTF8MB4 support for international characters
-
Security Hardening (P0 Fix):
- Test-only endpoints (
/test-register,/test-cleanup) protected with environment checks - Returns 403 Forbidden in production to prevent data manipulation
- Configurable bcrypt rounds (default: 12) via BCRYPT_ROUNDS environment variable
- Safe database URL logging (password masking) via
get_safe_database_url() - Email normalization to prevent duplicate accounts with case variations
- Test-only endpoints (
-
Testing (80%+ Coverage):
- Backend: 137 pytest tests covering unit, integration, and API layers
- Frontend: Vitest unit/integration tests for components and services
- E2E: Playwright tests for complete authentication workflows
- All tests passing with coverage enforcement enabled
-
Documentation:
- Comprehensive README.md with quick start, testing, and deployment guides
- CLAUDE.md with detailed architecture, development commands, and patterns
- Database migration documentation in database/README.md
- E2E testing guide in frontend/tests/e2e/README.md
- Inline code documentation with docstrings and JSDoc comments
Why was this MR needed?
User authentication is the foundational requirement for the task manager application. This implementation provides:
- Security-first approach: Proper password hashing, rate limiting, session management
- Production readiness: Environment-based protection, comprehensive error handling
- Developer experience: Clear documentation, robust testing, make commands for common tasks
- Maintainability: Clean architecture, type safety, comprehensive test coverage
Breaking Changes
Environment Variables Required:
The following environment variables must be configured before running the application:
# Database Configuration (required)
DB_HOST=localhost
DB_PORT=3306
DB_USER=task_user
DB_PASSWORD=task_password
DB_NAME_DEVELOPMENT=task_manager_development
DB_NAME_TEST=task_manager_test
# Environment Control (required)
ENVIRONMENT=development # or "test" or "production"
# MySQL Container (required)
MYSQL_ROOT_PASSWORD=root_password
MYSQL_DATABASE=task_manager_development
MYSQL_USER=task_user
MYSQL_PASSWORD=task_password
MYSQL_PORT=3306
# Optional: Password Hashing
BCRYPT_ROUNDS=12
Database Schema:
New migrations must be applied:
20251028000001_create_users_table.sql20251028000002_create_sessions_table.sql
Run make db-migrate to apply migrations.
Security Improvements
P0 - Production Endpoint Protection:
- Test-only endpoints now check
ENVIRONMENTvariable - Returns 403 Forbidden when
ENVIRONMENT=production - Prevents accidental exposure of user deletion endpoints
- Logs security violations for monitoring
Password Security:
- Bcrypt hashing with configurable rounds (default: 12)
- Password strength validation on registration
- No plaintext passwords in logs or responses
Session Security:
- 24-hour session expiration with automatic cleanup
- Maximum 5 concurrent sessions per user
- Cryptographically secure session ID generation
- Session invalidation on logout
Rate Limiting:
- Per-email rate limiting (5 attempts / 15 minutes)
- Prevents brute-force attacks
- Returns 429 Too Many Requests with retry information
Data Protection:
- Database URL password masking in logs (
get_safe_database_url()) - Email normalization to prevent case-based duplicates
- Input validation on all API endpoints
Testing Coverage
Backend (pytest):
- 137 test cases across 10 test files
- 80%+ code coverage (enforced in pytest.ini)
Frontend (Vitest + Playwright):
- Unit tests: AuthContext, LoginPage, routes, validation
- E2E tests: Complete login flow, session persistence, error handling
Test Commands:
# Backend
make backend-test # All tests
make backend-test-cov # With coverage report
# Frontend
cd frontend
pnpm test # Unit tests
pnpm e2e # E2E tests
Migration Instructions
For Reviewers / QA:
-
Checkout and install dependencies:
git checkout feature/user-login make setup # Automated: db-up + db-migrate + backend-install cd frontend && pnpm install -
Run the application:
# Terminal 1: Backend make backend-run # Terminal 2: Frontend cd frontend && pnpm dev -
Run tests to verify:
make backend-test cd frontend && pnpm test && pnpm e2e
For Production Deployment:
-
Environment configuration:
export ENVIRONMENT=production export BCRYPT_ROUNDS=12 # Set all required database variables -
Database migration:
make db-migrate -
Security checklist:
-
Verify ENVIRONMENT=production is set -
Test that /api/auth/test-cleanup returns 403 -
Confirm database passwords are not in logs -
Enable HTTPS for frontend and backend -
Configure CORS for production domain
-
How to Test
Manual Testing:
- Navigate to http://localhost:5173
- Click "Get Started" → should redirect to /login
- Register new account with email "testuser@example.com"
- Verify redirect to /dashboard after registration
- Logout → should redirect to landing page
- Login with same credentials → should redirect to /dashboard
- Try invalid credentials → should show error message
API Testing:
# Valid login
curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"SecurePass123!"}'
# Rate limiting (6th attempt should return 429)
for i in {1..6}; do curl -X POST http://localhost:8000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"wrong"}'; done
File Changes Summary
100 files changed: 22,485 insertions, 221 deletions
Key Files to Review:
-
/backend/app/api/auth.py- Authentication endpoints (335 lines) -
/backend/app/domain/user.py- User domain model (140 lines) -
/backend/app/util/password.py- Password hashing utilities (167 lines) -
/backend/app/util/rate_limiter.py- Rate limiting (172 lines) -
/frontend/src/contexts/AuthContext.tsx- Auth state management (263 lines) -
/frontend/src/pages/LoginPage.tsx- Login UI (369 lines) -
/backend/tests/test_auth_api.py- API test suite (984 lines)
Post-Merge Tasks
-
Update production environment variables in deployment system -
Run database migrations in staging and production -
Configure monitoring for rate limit violations -
Set up session cleanup cron job for expired sessions -
Configure CORS for production frontend domain -
Enable HTTPS for both frontend and backend -
Consider Redis for rate limiter in high-traffic scenarios -
Document password reset flow (future enhancement) -
Document email verification flow (future enhancement)
This merge request is ready for review. All tests pass, documentation is complete, and the implementation follows security best practices.