import test from 'node:test'; import assert from 'node:assert/strict'; import http from 'node:http'; import https from 'node:https'; import tls from 'node:tls'; import fs from 'node:fs'; import {once} from 'node:events'; import {createRequire} from 'node:module'; const {createConnectProxy}=createRequire(import.meta.url)('../apps/network-broker/connect-inspection-proxy.cjs'); const cert=fs.readFileSync(new URL('./fixtures/icap/cert.pem',import.meta.url)),key=fs.readFileSync(new URL('./fixtures/icap/key.pem',import.meta.url)); async function fixture(t,config={}) { let connections=0,resolutions=0; const received=[]; const target=https.createServer({key,cert},async(req,res)=>{const chunks=[];for await(const chunk of req)chunks.push(chunk);received.push(Buffer.concat(chunks).toString());res.writeHead(201,{'content-type':'text/plain'});res.end('accepted');}); target.on('connection',()=>connections++);target.listen(0,'127.0.0.1');await once(target,'listening'); const destination=`localhost:${target.address().port}`; const proxy=createConnectProxy({authority:'policy-1',current:()=>true,resolveCertificate:async binding=>{resolutions++;if(binding.authority!==destination)return undefined;return {authority:destination,key,cert};},inspect:async({body})=>({decision:body.toString().includes('SECRET')?'block':'allow'}),forward:({request,body,signal})=>new Promise((resolve,reject)=>{ const req=https.request({host:'127.0.0.1',port:target.address().port,path:new URL(request.url).pathname,method:request.method,servername:'localhost',ca:cert,rejectUnauthorized:true,signal,headers:{host:destination,'content-length':body.length}},res=>{const chunks=[];res.on('data',c=>chunks.push(c));res.on('end',()=>resolve({statusCode:res.statusCode,headers:res.headers,body:Buffer.concat(chunks)}));});req.on('error',reject);req.end(body); }),deadlineMs:1000,authMode:'bearer',...config}); const port=await proxy.listen(); t.after(async()=>{await proxy.close();target.closeAllConnections();await new Promise(r=>target.close(r));}); async function send(body,{token=proxy.capability,authorization=`Bearer ${token}`,connectAuthority=destination,host=destination,servername='localhost'}={}) { const result=await new Promise((resolve,reject)=>{ const req=http.request({host:'127.0.0.1',port,method:'CONNECT',path:connectAuthority,headers:{host:connectAuthority,'proxy-authorization':authorization}}); req.setTimeout(2000,()=>req.destroy(new Error('connect-test-deadline')));req.on('error',reject); req.on('connect',(res,socket,head)=>{if(res.statusCode!==200){socket.destroy();resolve({status:res.statusCode,challenge:res.headers['proxy-authenticate']});return;}assert.equal(head.length,0); const secure=tls.connect({socket,servername,ca:cert,rejectUnauthorized:true});let text=''; secure.setTimeout(2000,()=>secure.destroy(new Error('tls-test-deadline')));secure.on('error',reject); secure.on('secureConnect',()=>secure.write(`POST /submit HTTP/1.1\r\nHost: ${host}\r\nContent-Length: ${Buffer.byteLength(body)}\r\nConnection: close\r\n\r\n${body}`)); secure.on('data',c=>text+=c);secure.on('end',()=>{secure.destroy();resolve({status:Number(/^HTTP\/1.1 (\d+)/.exec(text)?.[1]),text});}); });req.end(); });return result; } return {send,received,credentials:proxy.credentials,get connections(){return connections;},get resolutions(){return resolutions;}}; } test('real authenticated CONNECT wraps verified TLS; no opaque target dial for secret',async t=>{ const f=await fixture(t); assert.equal((await f.send('SECRET')).status,403);assert.equal(f.connections,0);assert.deepEqual(f.received,[]); const allowed=await f.send('public');assert.equal(allowed.status,201);assert.match(allowed.text,/accepted$/);assert.equal(f.connections,1);assert.deepEqual(f.received,['public']); }); test('incorrect token prevents certificate resolution, TLS establishment and target dial',async t=>{ const f=await fixture(t);assert.equal((await f.send('public',{token:'incorrect'})).status,407);assert.equal(f.resolutions,0);assert.equal(f.connections,0); }); test('unapproved CONNECT authority, inner mismatch and absent SNI never dial target',async t=>{ const f=await fixture(t); assert.equal((await f.send('public',{connectAuthority:'evil.example:443'})).status,403); assert.equal((await f.send('public',{host:'evil.example:443'})).status,403); assert.equal((await f.send('public',{servername:''})).status,403); assert.equal(f.connections,0);assert.deepEqual(f.received,[]); }); test('shared CONNECT work budget remains consumed when timed-out inspector ignores cancellation',async t=>{ const retained=[]; const f=await fixture(t,{maxClients:1,deadlineMs:100,inspect:({body})=>{retained.push(body);return new Promise(()=>{});}}); assert.equal((await f.send('public')).status,403); for(let index=0;index<3;index++)assert.equal((await f.send('public')).status,403); assert.equal(retained.length,1);assert.equal(retained[0].toString(),'public');assert.equal(f.connections,0); }); test('shared CONNECT work budget retains an ignored forward promise after timeout',async t=>{ let calls=0; const f=await fixture(t,{maxClients:1,deadlineMs:100,forward:()=>{calls++;return new Promise(()=>{});}}); assert.equal((await f.send('public')).status,502); for(let index=0;index<3;index++)assert.equal((await f.send('public')).status,403); assert.equal(calls,1);assert.equal(f.connections,0); }); test('timed-out certificate resolver retains shared capacity across new CONNECT sockets',async t=>{ let calls=0,aborted=false; const f=await fixture(t,{maxClients:1,deadlineMs:100,resolveCertificate:(_binding,{signal})=>{calls++;signal.addEventListener('abort',()=>aborted=true,{once:true});return new Promise(()=>{});}}); for(let index=0;index<4;index++)assert.equal((await f.send('public')).status,403); assert.equal(calls,1);assert.equal(aborted,true);assert.equal(f.connections,0); }); test('Basic mode challenges and rejects Bearer without downgrade then accepts exact random credentials',async t=>{ const f=await fixture(t,{authMode:'basic'}); const refused=await f.send('public');assert.equal(refused.status,407);assert.equal(refused.challenge,'Basic realm="SafetyNet private broker", charset="UTF-8"');assert.equal(f.connections,0);assert.equal(f.resolutions,0); const authorization=`Basic ${Buffer.from(`${f.credentials.username}:${f.credentials.password}`).toString('base64')}`; assert.equal((await f.send('public',{authorization})).status,201);assert.deepEqual(f.received,['public']); });