import { describe, test, expect, beforeEach, mock } from 'bun:test' import { mockConfigModule } from './helpers/mock-config' // --------------------------------------------------------------------------- // Mock config before any other imports // --------------------------------------------------------------------------- mock.module('../config', () => mockConfigModule({ pollTimeout: 1 })) import { Hono } from 'hono' import { storeReset, storeCreateSession, storeCreateEnvironment, } from '../store' import { issueToken } from '../auth/token' // Import route modules that should use sessionAuth (not uuidAuth) import webSessions from '../routes/web/sessions' import webControl from '../routes/web/control' import webEnvironments from '../routes/web/environments' import webAuth from '../routes/web/auth' import webAuthRoutes from '../routes/web/auth-routes' import webShares from '../routes/web/shares' import webTeams from '../routes/web/teams' function createApp() { const app = new Hono() app.route('/web', webAuth) app.route('/web/auth', webAuthRoutes) app.route('/web', webSessions) app.route('/web', webControl) app.route('/web', webEnvironments) app.route('/web', webShares) app.route('/web', webTeams) return app } describe('anonymous access blocked everywhere', () => { let app: Hono beforeEach(() => { storeReset() app = createApp() }) test('GET /web/sessions without auth returns 401', async () => { const res = await app.request('/web/sessions') expect(res.status).toBe(401) }) test('POST /web/sessions without auth returns 401', async () => { const res = await app.request('/web/sessions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ environment_id: 'env_test' }), }) expect(res.status).toBe(401) }) test('GET /web/teams without auth returns 401', async () => { const res = await app.request('/web/teams') expect(res.status).toBe(401) }) test('POST /web/sessions/:id/shares without auth returns 401', async () => { const res = await app.request('/web/sessions/test-session/shares', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ grantTo: 'user1' }), }) expect(res.status).toBe(401) }) test('GET /web/auth/me without auth returns 401', async () => { const res = await app.request('/web/auth/me') expect(res.status).toBe(401) }) test('GET /web/environments without auth returns 401', async () => { const res = await app.request('/web/environments') expect(res.status).toBe(401) }) test('GET /web/server-info without auth returns 401', async () => { const res = await app.request('/web/server-info') expect(res.status).toBe(401) }) test('POST /web/sessions/:id/events without auth returns 401', async () => { const res = await app.request('/web/sessions/test/events', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: 'test' }), }) expect(res.status).toBe(401) }) test('POST /web/sessions/:id/control without auth returns 401', async () => { const res = await app.request('/web/sessions/test/control', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: 'test' }), }) expect(res.status).toBe(401) }) test('POST /web/sessions/:id/interrupt without auth returns 401', async () => { const res = await app.request('/web/sessions/test/interrupt', { method: 'POST', }) expect(res.status).toBe(401) }) test('DELETE /web/sessions/:id without auth returns 401', async () => { const res = await app.request('/web/sessions/test', { method: 'DELETE', }) expect(res.status).toBe(401) }) }) describe('UUID as auth no longer accepted', () => { let app: Hono beforeEach(() => { storeReset() app = createApp() }) test('GET /web/sessions with ?uuid=xxx but no token returns 401', async () => { const res = await app.request('/web/sessions?uuid=some-user-uuid') expect(res.status).toBe(401) }) test('GET /web/sessions with X-UUID header but no token returns 401', async () => { const res = await app.request('/web/sessions', { headers: { 'X-UUID': 'some-user-uuid' }, }) expect(res.status).toBe(401) }) test('POST /web/sessions with ?uuid=xxx but no token returns 401', async () => { const res = await app.request('/web/sessions?uuid=some-user-uuid', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ environment_id: 'env_test' }), }) expect(res.status).toBe(401) }) test('GET /web/environments with ?uuid=xxx but no token returns 401', async () => { const res = await app.request('/web/environments?uuid=some-user-uuid') expect(res.status).toBe(401) }) test('GET /web/auth/me with ?uuid=xxx but no token returns 401', async () => { const res = await app.request('/web/auth/me?uuid=some-user-uuid') expect(res.status).toBe(401) }) test('GET /web/teams with X-UUID header but no token returns 401', async () => { const res = await app.request('/web/teams', { headers: { 'X-UUID': 'some-user-uuid' }, }) expect(res.status).toBe(401) }) }) describe('session token still works', () => { let app: Hono beforeEach(() => { storeReset() app = createApp() }) test('valid access token cookie returns success on /web/sessions', async () => { const { token } = issueToken('testuser') const res = await app.request('/web/sessions', { headers: { Cookie: `rcs_access=${token}` }, }) // Should be 200, not 401 expect(res.status).not.toBe(401) }) test('valid Bearer token returns success on /web/sessions', async () => { const { token } = issueToken('testuser') const res = await app.request('/web/sessions', { headers: { Authorization: `Bearer ${token}` }, }) expect(res.status).not.toBe(401) }) test('admin API key returns success on /web/sessions', async () => { const res = await app.request('/web/sessions', { headers: { Authorization: 'Bearer test-api-key' }, }) expect(res.status).not.toBe(401) }) test('admin API key returns success on /web/auth/me', async () => { const res = await app.request('/web/auth/me', { headers: { Authorization: 'Bearer test-api-key' }, }) expect(res.status).toBe(200) const body = await res.json() expect(body.isAdmin).toBe(true) }) test('valid access token cookie returns success on /web/environments', async () => { const { token } = issueToken('testuser') const res = await app.request('/web/environments', { headers: { Cookie: `rcs_access=${token}` }, }) expect(res.status).not.toBe(401) }) test('invalid token returns 401', async () => { const res = await app.request('/web/sessions', { headers: { Authorization: 'Bearer definitely-not-valid' }, }) expect(res.status).toBe(401) }) })