const test = require('node:test'); const assert = require('node:assert/strict'); process.env.JWT_SECRET = 'board-device-test-secret-only'; require.cache[require.resolve('../src/config/database')] = { exports: { query: async () => ({ rows: [] }) } }; const express = require('express'); const jwt = require('jsonwebtoken'); const { createBoardDevicesRouter } = require('../src/routes/boardDevices'); const { createBoardDeviceService } = require('../src/services/boardDeviceService'); const { defaults } = require('../src/services/boardDeviceSettings'); const { memoryRepository } = require('./helpers/boardDeviceMemoryRepository'); test('public pairing and device credentials cannot access admin endpoints; JWT administrator and city are required', async t => { const service = createBoardDeviceService(memoryRepository()); const app = express(); app.use(express.json()); app.use('/api/v1/board-devices', createBoardDevicesRouter(service, { cityMiddleware: (req, _res, next) => { req.city = { id: Number(req.get('X-City-Id') || 1) }; next(); } })); const server = await new Promise(resolve => { const s = app.listen(0, '127.0.0.1', () => resolve(s)); }); t.after(() => new Promise(resolve => server.close(resolve))); const base = `http://127.0.0.1:${server.address().port}/api/v1/board-devices`; const post = (path, body, headers = {}) => fetch(base + path, { method: 'POST', headers: { 'Content-Type': 'application/json', ...headers }, body: JSON.stringify(body) }); const admin = { Authorization: `Bearer ${jwt.sign({ id: 7, role: 'admin' }, process.env.JWT_SECRET)}`, 'X-City-Id': '1' }; const pair = await (await post('/pairings', { width: 879, height: 593 })).json(); assert.match(pair.code, /^\d{4}$/); assert.equal((await fetch(base + '/admin')).status, 401); assert.equal((await fetch(base + '/admin', { headers: { 'X-Board-Token': pair.token } })).status, 401); assert.equal((await fetch(base + '/admin', { headers: { Authorization: `Bearer ${jwt.sign({ id: 7, role: 'user' }, process.env.JWT_SECRET)}` } })).status, 403); assert.equal((await fetch(base + '/self', { headers: admin })).status, 401); assert.equal((await post('/admin/claim', { code: pair.code, name: 'A', settings: defaults }, admin)).status, 200); const status = await fetch(base + '/self', { headers: { 'X-Board-Token': pair.token } }); assert.equal(status.headers.get('cache-control'), 'no-store'); assert.equal((await status.json()).state, 'paired'); assert.equal((await post('/admin/claim', { code: pair.code, name: 'A', settings: defaults }, admin)).status, 409); const list = await (await fetch(base + '/admin', { headers: admin })).json(); assert.equal(list.length, 1); assert.equal(list[0].token_hash, undefined); assert.equal((await (await fetch(base + '/admin', { headers: { ...admin, 'X-City-Id': '2' } })).json()).length, 0); });