diff --git a/backend/routes/sessions.js b/backend/routes/sessions.js index f362f99..ce28e9f 100644 --- a/backend/routes/sessions.js +++ b/backend/routes/sessions.js @@ -6,6 +6,7 @@ const { triggerWebhook } = require('../utils/webhooks'); const { getWebSocketManager } = require('../utils/websocket-manager'); const { startMonitor, stopMonitor, getMonitorSnapshot } = require('../utils/ecast-shard-client'); const { computeNotesPreview } = require('../utils/notes-preview'); +const { optionalAuthenticateToken } = require('../middleware/optional-auth'); const router = express.Router(); @@ -71,7 +72,7 @@ router.get('/active', (req, res) => { }); // Get single session by ID -router.get('/:id', (req, res) => { +router.get('/:id', optionalAuthenticateToken, (req, res) => { try { const session = db.prepare(` SELECT @@ -87,7 +88,14 @@ router.get('/:id', (req, res) => { return res.status(404).json({ error: 'Session not found' }); } - res.json(session); + const { has_notes, notes_preview } = computeNotesPreview(session.notes); + + if (req.user) { + res.json({ ...session, has_notes, notes_preview }); + } else { + const { notes, ...publicSession } = session; + res.json({ ...publicSession, has_notes, notes_preview }); + } } catch (error) { res.status(500).json({ error: error.message }); } diff --git a/tests/api/regression-sessions.test.js b/tests/api/regression-sessions.test.js index f888cdd..16f446d 100644 --- a/tests/api/regression-sessions.test.js +++ b/tests/api/regression-sessions.test.js @@ -7,7 +7,7 @@ describe('GET /api/sessions (regression)', () => { cleanDb(); }); - test('GET /api/sessions/:id returns session object', async () => { + test('GET /api/sessions/:id returns session object with preview for unauthenticated', async () => { const session = seedSession({ is_active: 1, notes: 'Test session' }); const res = await request(app).get(`/api/sessions/${session.id}`); @@ -17,9 +17,11 @@ describe('GET /api/sessions (regression)', () => { expect.objectContaining({ id: session.id, is_active: 1, - notes: 'Test session', + has_notes: true, + notes_preview: 'Test session', }) ); + expect(res.body.notes).toBeUndefined(); expect(res.body).toHaveProperty('games_played'); }); diff --git a/tests/api/session-notes.test.js b/tests/api/session-notes.test.js index 7c84eb5..4d0a4e8 100644 --- a/tests/api/session-notes.test.js +++ b/tests/api/session-notes.test.js @@ -104,3 +104,44 @@ describe('GET /api/sessions list', () => { }); }); +describe('GET /api/sessions/:id notes visibility', () => { + beforeEach(() => { + cleanDb(); + }); + + test('returns full notes when authenticated', async () => { + const session = seedSession({ notes: '**Full notes** here\n\nSecond paragraph' }); + + const res = await request(app) + .get(`/api/sessions/${session.id}`) + .set('Authorization', getAuthHeader()); + + expect(res.status).toBe(200); + expect(res.body.notes).toBe('**Full notes** here\n\nSecond paragraph'); + expect(res.body.has_notes).toBe(true); + expect(res.body.notes_preview).toBe('Full notes here'); + }); + + test('returns only preview when unauthenticated', async () => { + const session = seedSession({ notes: '**Full notes** here\n\nSecond paragraph' }); + + const res = await request(app) + .get(`/api/sessions/${session.id}`); + + expect(res.status).toBe(200); + expect(res.body.notes).toBeUndefined(); + expect(res.body.has_notes).toBe(true); + expect(res.body.notes_preview).toBe('Full notes here'); + }); + + test('returns has_notes false when no notes', async () => { + const session = seedSession({ notes: null }); + + const res = await request(app) + .get(`/api/sessions/${session.id}`); + + expect(res.status).toBe(200); + expect(res.body.has_notes).toBe(false); + expect(res.body.notes_preview).toBeNull(); + }); +});