import { test } from 'node:test'; import assert from 'node:assert/strict'; import { io } from 'socket.io-client'; import { fixture } from './helpers.js'; import { clientIp } from '../src/security.js'; test('Cloudflare 원본 IP는 신뢰한 인접 프록시의 단일 공인 IP만 허용한다', () => { const resolve = (peer, headers) => clientIp(peer, headers, ['127.0.0.1'], 'cloudflare'); assert.equal( resolve('127.0.0.1', { 'cf-connecting-ip': '8.8.8.8', 'x-forwarded-for': '1.1.1.1' }), '8.8.8.8', ); assert.equal(resolve('8.8.4.4', { 'cf-connecting-ip': '8.8.8.8' }), null); for (const value of ['192.168.1.1', '127.0.0.1', 'bad', '8.8.8.8,1.1.1.1', ['8.8.8.8']]) assert.equal(resolve('127.0.0.1', { 'cf-connecting-ip': value }), null); assert.equal(resolve('127.0.0.1', {}), null); }); test('실제 소켓의 같은 원본 IP는 자동 발견하고 다른 네트워크·발견 꺼짐은 숨긴다', async () => { const f = await fixture(true), sockets = []; f.cfg.clientIpSource = 'cloudflare'; try { const clients = []; for (const ip of ['8.8.8.8', '8.8.8.8', '1.1.1.1']) { const client = await f.create(ip, false); const socket = io(f.url, { transports: ['websocket'], auth: { csrfToken: client.csrf }, extraHeaders: { Origin: f.cfg.appUrl, Cookie: client.cookie, 'CF-Connecting-IP': ip, 'X-Forwarded-For': '9.9.9.9', }, }); sockets.push(socket); await new Promise((resolve, reject) => { socket.once('connect', resolve); socket.once('connect_error', reject); }); clients.push(client); } const list = (await f.call(clients[0], '/discovery/devices')).json().devices; assert.deepEqual( list.map((device) => device.id), [clients[1].deviceId], ); await f.call(clients[1], '/device/me', 'PATCH', { discoverable: false }); assert.equal((await f.call(clients[0], '/discovery/devices')).json().devices.length, 0); } finally { sockets.forEach((socket) => socket.disconnect()); await f.close(); } }); test('프록시 진단은 운영자 토큰 없이 원본 정보를 노출하지 않는다', async () => { const f = await fixture(); f.cfg.proxyDiagnosticToken = 'p'.repeat(40); try { const denied = await f.call(null, '/ops/proxy-diagnostic'); assert.equal(denied.statusCode, 403); assert.equal(denied.json().peerIp, undefined); const allowed = await f.call(null, '/ops/proxy-diagnostic', 'GET', undefined, undefined, { authorization: `Bearer ${f.cfg.proxyDiagnosticToken}`, 'cf-connecting-ip': '8.8.8.8', }); assert.equal(allowed.statusCode, 200); assert.equal(allowed.json().peerIp, '127.0.0.1'); assert.equal(allowed.json().cloudflareClientIpPresent, true); f.cfg.proxyDiagnosticToken = undefined; assert.equal((await f.call(null, '/ops/proxy-diagnostic')).statusCode, 404); } finally { await f.close(); } });