The repository contains the backend only. The separate frontend can integrate through the contracts below.
Authentication uses an HTTP session cookie. Use credentials: "include" in browser requests and never store JSESSIONID in local storage.
| Method | Endpoint | Auth | Body | Result |
|---|---|---|---|---|
| POST | /api/auth/register |
No | { "username": "alice", "password": "..." } |
200 or 409 |
| POST | /api/auth/login |
No | same credentials | Sets JSESSIONID |
| GET | /api/auth/session |
No | — | { loggedIn, username? } |
| POST | /api/auth/logout |
Yes | — | Invalidates session |
Usernames are normalized to lowercase and may contain letters, numbers, dots, underscores, and hyphens. Passwords must be 6–100 characters.
POST /api/chat/create:{ "chatName": "Friends", "receiverName": "bob" }. The owner always comes from the authenticated session.GET /api/chat/list: lists chats for the authenticated user.GET /api/chat/{chatId}?limit=50&before=2026-08-13T10:00:00: returns a bounded chronological page.limitis capped at 100;beforeis an optional ISO-8601 cursor.GET /api/chat/{chatId}/search?q=hello&limit=25: member-only case-insensitive search, capped at 50 results.DELETE /api/chat/delete?chatId=...: owner-only deletion and message cleanup; returns204 No Content.
All handled REST errors use { timestamp, status, error, message, path, fieldErrors? }. Stack traces, credentials, and provider details are never returned.
POST /api/files/upload uses multipart field file. Supported types include common images/audio, PDF, Word documents, and plain text. The configured request limit defaults to 10 MB per file and 12 MB per request. The response contains a Cloudinary HTTPS URL that can be used in a file message.
Connect STOMP/SockJS to /ws-chat. Authenticate through the HTTP session before connecting. Subscribe to /topic/chat/{chatId} and publish to /app/chat/{chatId}/send.
Text message:
{ "type": "TEXT", "content": "hello" }File message:
{ "type": "FILE_URL", "content": "https://...", "fileName": "photo.png", "fileType": "image/png" }The server ignores any supplied sender and uses the authenticated username. Text is limited to 4,000 characters and file URLs must be HTTPS.
Additional application destinations:
/app/chat/{chatId}/edit:{ "messageId": "...", "content": "updated" }; sender-only active text edit./app/chat/{chatId}/delete:{ "messageId": "..." }; sender-only soft delete./app/chat/{chatId}/react:{ "messageId": "...", "emoji": "👍" }; member reaction toggle./app/chat/{chatId}/read:{}; marks messages from other participants as read./app/chat/{chatId}/typing:{ "typing": true }; ephemeral typing signal.
Subscribe to /topic/chat/{chatId}/receipts, /topic/chat/{chatId}/typing, and /topic/presence for read, typing, and online/offline events. WebSocket CONNECT, SEND, and SUBSCRIBE operations are checked against authentication and chat membership.
GET /actuator/health is the Render health check. Only health is exposed publicly. Gemini is disabled safely when GEMINI_API_KEY is absent; enabled calls use bounded async execution and connect/read timeouts.