Commit Graph

13 Commits

Author SHA1 Message Date
Radosław Gierwiało
78280ca8d8 feat(dashboard): add unread count for match chats
Track unread messages in match chats and display count badge:
- Schema: Add user1LastReadAt/user2LastReadAt to Match model
- Backend: Calculate unreadCount in dashboard API
- Socket: Update lastReadAt when user joins match room
- Frontend: Display red badge with unread count on match avatar
2025-11-21 21:46:00 +01:00
Radosław Gierwiało
44df50362a feat(security): implement comprehensive security hardening
- Add CSRF protection with cookie-based tokens
  - Add cookie-parser and csurf middleware
  - Create GET /api/csrf-token endpoint
  - Frontend automatically includes CSRF token in POST/PUT/DELETE requests
  - Add retry logic for expired CSRF tokens

- Implement account lockout mechanism
  - Add database fields: failedLoginAttempts, lockedUntil
  - Track failed login attempts and lock accounts after max attempts (configurable)
  - Auto-unlock after lockout duration expires
  - Return helpful error messages with remaining time

- Add comprehensive security environment variables
  - Rate limiting configuration (API, auth, email endpoints)
  - CSRF protection toggle
  - Password policy requirements
  - Account lockout settings
  - Logging levels

- Add comprehensive test coverage
  - 6 new tests for account lockout functionality
  - 11 new tests for CSRF protection
  - All tests handle enabled/disabled states gracefully

- Update documentation
  - Add Phase 3 security hardening to SESSION_CONTEXT.md
  - Document new database fields and migration
  - Update progress to 85%

Files changed:
- Backend: app.js, auth controller, security config, new migration
- Frontend: api.js with CSRF token handling
- Tests: auth.test.js (extended), csrf.test.js (new)
- Config: .env examples with security variables
- Docs: SESSION_CONTEXT.md updated
2025-11-19 20:16:05 +01:00
Radosław Gierwiało
c2010246e3 feat: add match slugs for security and fix message history loading
Security improvements:
- Add random CUID slugs to Match model to prevent ID enumeration attacks
- Update all match URLs from /matches/:id to /matches/:slug
- Keep numeric IDs for internal Socket.IO operations only

Backend changes:
- Add slug field to matches table with unique index
- Update all match endpoints to use slug-based lookups (GET, PUT, DELETE)
- Add GET /api/matches/:slug/messages endpoint to fetch message history
- Include matchSlug in all Socket.IO notifications

Frontend changes:
- Update all match routes to use slug parameter
- Update MatchesPage to use slug for accept/reject/navigate operations
- Update MatchChatPage to fetch match data by slug and load message history
- Update RatePartnerPage to use slug parameter
- Add matchesAPI.getMatchMessages() function

Bug fixes:
- Fix MatchChatPage not loading message history from database on mount
- Messages now persist and display correctly when users reconnect
2025-11-14 22:22:11 +01:00
Radosław Gierwiało
92315d5a8c feat: add test accounts and secure event slugs
Security improvements:
- Add @default(cuid()) to Event.slug for auto-generated random slugs
- Prevent ID enumeration attacks (no more predictable slugs like "warsaw-dance-festival-2025")
- Event slugs now generated as secure cuid strings (e.g., "cmhz3lcgb00018vbn34v4phoi")

Test accounts:
- Add 3 test users to seed (john_dancer, sarah_swings, mike_blues)
- All users checked in to Warsaw Dance Festival 2025
- Pre-configured heats for testing matchmaking system
- Full profiles with WSDC IDs, social media, and locations

Seed improvements:
- Add bcryptjs for password hashing
- Add Prisma seed configuration to package.json
- Use worldsdcId for event upsert (instead of slug)
- Auto-generate event slugs via Prisma default

Documentation:
- Add test account credentials to SESSION_CONTEXT.md
- Document event slug security model
- Include sample heats for each test user
2025-11-14 17:55:29 +01:00
Radosław Gierwiało
02d3d7ac42 feat: add competition heats system backend
- Add 3 new database tables: divisions, competition_types, event_user_heats
- Add seed data for 6 divisions (NEW, NOV, INT, ADV, ALL, CHA) and 2 competition types (J&J, STR)
- Add API endpoints for divisions and competition types
- Add heats management endpoints in events route (POST/GET/DELETE)
- Implement unique constraint: cannot have same role in same division+competition type
- Add participant verification before allowing heats management
- Support heat numbers 1-9 with optional Leader/Follower role
2025-11-14 15:32:40 +01:00
Radosław Gierwiało
71cba01db3 feat: add QR code event check-in system
Backend:
- Add event_checkin_tokens table with unique tokens per event
- Implement GET /api/events/:slug/details endpoint (on-demand token generation)
- Implement POST /api/events/checkin/:token endpoint (date validation only in production)
- Implement DELETE /api/events/:slug/leave endpoint
- Add comprehensive test suite for check-in endpoints

Frontend:
- Add EventDetailsPage with QR code display, participant list, and stats
- Add EventCheckinPage with success/error screens
- Add "Leave Event" button with confirmation modal to EventChatPage
- Install qrcode.react library for QR code generation
- Update routing and API client with new endpoints

Features:
- QR codes valid from (startDate-1d) to (endDate+1d)
- Development mode bypasses date validation for testing
- Automatic participant count tracking
- Duplicate check-in prevention
- Token reuse for same event (generated once, cached)
2025-11-14 14:11:24 +01:00
Radosław Gierwiało
b2c2527c46 feat: add event slugs to prevent ID enumeration attacks
Replace sequential event IDs in URLs with unique alphanumeric slugs to prevent enumeration attacks. Event URLs now use format /events/{slug}/chat instead of /events/{id}/chat.

Backend changes:
- Add slug field (VARCHAR 50, unique) to Event model
- Create migration with auto-generated 12-char MD5-based slugs for existing events
- Update GET /api/events/:slug endpoint (changed from :id)
- Update GET /api/events/:slug/messages endpoint (changed from :eventId)
- Modify Socket.IO join_event_room to accept slug parameter
- Update send_event_message to use stored event context instead of passing eventId

Frontend changes:
- Update eventsAPI.getBySlug() method (changed from getById)
- Update eventsAPI.getMessages() to use slug parameter
- Change route from /events/:eventId/chat to /events/:slug/chat
- Update EventsPage to navigate using event.slug
- Update EventChatPage to fetch event data via slug and use slug in socket events

Security impact: Prevents attackers from discovering all events by iterating sequential IDs.
2025-11-13 21:43:58 +01:00
Radosław Gierwiało
20f405cab3 feat: track event participation and show joined events first
Backend:
- Add EventParticipant model to track user-event participation
- Create database migration for event_participants table
- Record participation when user joins event chat via Socket.IO
- Update GET /api/events to include isJoined flag for current user
- Sort events: joined events first, then by start date
- Add authenticate middleware to GET /api/events

Frontend:
- Replace mock events with real API data from backend
- Add loading and error states to EventsPage
- Display "Joined" badge on events user has joined
- Highlight joined events with colored border
- Show "Open chat" vs "Join chat" button text
- Auto-refresh events list when navigating back

When users join an event chat, this is now recorded in the database.
Joined events appear at the top of the list with visual indicators.
2025-11-13 21:18:15 +01:00
Radosław Gierwiało
144b13a0cf feat: add country and city fields to user profile
- Add country and city fields to User model
- Create database migration for location fields
- Add validation for country and city (max 100 characters)
- Create countries.js with complete list of 195 countries
- Add country dropdown select and city text input to profile page
- Include country and city in GET /api/users/me response
- Update profile form to support location data

Users can now select their country from a dropdown list of all
countries and enter their city name.
2025-11-13 20:57:43 +01:00
Radosław Gierwiało
48f9dfe1b4 feat: add social media links to user profile
- Add YouTube, Instagram, Facebook, and TikTok URL fields to User model
- Create database migration for social media link columns
- Add custom validators to ensure URLs contain correct domains
- Update profile page with social media input fields
- Include social media URLs in GET /api/users/me response
- Add icons for each social platform in the UI

Users can now add links to their social media profiles. Each field
validates that the URL contains the appropriate domain (e.g.,
instagram.com for Instagram, youtube.com/youtu.be for YouTube).
2025-11-13 20:47:57 +01:00
Radosław Gierwiało
46224fca79 feat: add auto-lookup and duplicate check for WSDC registration
Enhanced WSDC registration flow with auto-lookup and account validation:

Backend changes:
- Add accountExists flag to WSDC lookup endpoint
- Check database for existing users with WSDC ID
- Fix Prisma binary target for Alpine Linux Docker containers

Frontend changes:
- Auto-lookup WSDC data after entering 4+ digits (500ms debounce)
- Show live preview dropdown with dancer information
- Display warning if account with WSDC ID already exists
- Block registration and suggest login for existing accounts
- Improve UX with real-time validation feedback
- Add CheckCircle, XCircle, AlertCircle icons for visual feedback

This prevents duplicate WSDC ID registrations and provides immediate
feedback to users, improving the registration experience.

Tested with:
- ID 26111 (Vince Yap) - new account allowed
- ID 26997 (Radoslaw) - existing account blocked
2025-11-13 16:11:04 +01:00
Radosław Gierwiało
7a2f6d07ec feat: add email verification, password reset, and WSDC integration (Phase 1.5)
Backend features:
- AWS SES email service with HTML templates
- Email verification with dual method (link + 6-digit PIN code)
- Password reset workflow with secure tokens
- WSDC API proxy for dancer lookup and auto-fill registration
- Extended User model with verification and WSDC fields
- Email verification middleware for protected routes

Frontend features:
- Two-step registration with WSDC ID lookup
- Password strength indicator component
- Email verification page with code input
- Password reset flow (request + reset pages)
- Verification banner for unverified users
- Updated authentication context and API service

Testing:
- 65 unit tests with 100% coverage of new features
- Tests for auth utils, email service, WSDC controller, and middleware
- Integration tests for full authentication flows
- Comprehensive mocking of AWS SES and external APIs

Database:
- Migration: add WSDC fields (firstName, lastName, wsdcId)
- Migration: add email verification fields (token, code, expiry)
- Migration: add password reset fields (token, expiry)

Documentation:
- Complete Phase 1.5 documentation
- Test suite documentation and best practices
- Updated session context with new features
2025-11-13 15:47:54 +01:00
Radosław Gierwiało
0e62b12f5e feat: add PostgreSQL database with Prisma ORM
Phase 1 - Step 2: PostgreSQL Setup

**Infrastructure:**
- Add PostgreSQL 15 Alpine container to docker-compose.yml
- Configure persistent volume for database data
- Update backend Dockerfile with OpenSSL for Prisma compatibility

**Database Schema (Prisma):**
- 6 tables: users, events, chat_rooms, messages, matches, ratings
- Foreign key relationships and cascading deletes
- Performance indexes on frequently queried columns
- Unique constraints for data integrity

**Prisma Setup:**
- Prisma Client for database queries
- Migration system with initial migration
- Seed script with 4 test events and chat rooms
- Database connection utility with singleton pattern

**API Implementation:**
- GET /api/events - List all events (with filtering and sorting)
- GET /api/events/:id - Get single event with relations
- Database connection test on server startup
- Graceful database disconnect on shutdown

**Seed Data:**
- Warsaw Dance Festival 2025
- Swing Camp Barcelona 2025
- Blues Week Herräng 2025
- Krakow Swing Connection 2025

**Testing:**
- Database connection verified 
- API endpoints returning data from PostgreSQL 
- Migrations applied successfully 

All systems operational 🚀
2025-11-12 21:56:11 +01:00