Commit Graph

6 Commits

Author SHA1 Message Date
Radosław Gierwiało
c4240f05bb feat: add Socket.IO heats_updated broadcast event
- Export getIO function from socket module
- Broadcast heats_updated event when user updates their heats
- Event includes userId, username, and updated heats array
- Non-blocking broadcast (won't fail request if socket fails)
2025-11-14 15:35:39 +01:00
Radosław Gierwiało
a6e4981f17 fix: prevent bypassing event check-in via page refresh
Users could gain unauthorized access to event chats by refreshing the page after leaving an event. The socket handler was automatically creating participation records when users joined rooms, completely bypassing the QR code check-in requirement. This fix verifies that users have legitimately checked in before allowing socket room access.
2025-11-14 14:36:49 +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
9d8fc9f6d6 feat: add chat message history and infinite scroll
Backend changes:
- Socket.IO: Send last 20 messages on join_event_room
- REST API: Add GET /api/events/:eventId/messages endpoint with pagination
- Support for 'before' cursor-based pagination for loading older messages

Frontend changes:
- Load initial 20 messages when joining event chat
- Implement infinite scroll to load older messages on scroll to top
- Add loading indicator for older messages
- Preserve scroll position when loading older messages
- Add eventsAPI.getMessages() function for pagination

User experience:
- New users see last 20 messages immediately
- Scrolling up automatically loads older messages in batches of 20
- Smooth scrolling experience with position restoration

Note: Messages are encrypted in transit via HTTPS/WSS but stored
as plain text in database (no E2E encryption).
2025-11-13 20:16:58 +01:00
Radosław Gierwiało
75cb4b16e7 feat: implement real-time chat with Socket.IO
Implemented WebSocket-based real-time messaging for both event rooms and private match chats using Socket.IO with comprehensive test coverage.

Backend changes:
- Installed socket.io@4.8.1 for WebSocket server
- Created Socket.IO server with JWT authentication middleware
- Implemented event room management (join/leave/messages)
- Added active users tracking with real-time updates
- Implemented private match room messaging
- Integrated Socket.IO with Express HTTP server
- Messages are persisted to PostgreSQL via Prisma
- Added 12 comprehensive unit tests (89.13% coverage)

Frontend changes:
- Installed socket.io-client for WebSocket connections
- Created socket service layer for connection management
- Updated EventChatPage with real-time messaging
- Updated MatchChatPage with real-time private chat
- Added connection status indicators (● Connected/Disconnected)
- Disabled message input when not connected

Infrastructure:
- Updated nginx config to proxy WebSocket connections at /socket.io
- Added Upgrade and Connection headers for WebSocket support
- Set long timeouts (7d) for persistent WebSocket connections

Key features:
- JWT-authenticated socket connections
- Room-based architecture for events and matches
- Real-time message broadcasting
- Active users list with automatic updates
- Automatic cleanup on disconnect
- Message persistence in database

Test coverage:
- 12 tests passing (authentication, event rooms, match rooms, disconnect, errors)
- Socket.IO module: 89.13% statements, 81.81% branches, 91.66% functions
- Overall coverage: 81.19%

Phase 1, Step 4 completed. Ready for Phase 2 (Core Features).
2025-11-12 22:42:15 +01:00