18 lines
4.0 KiB
JavaScript
18 lines
4.0 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import fs from 'node:fs'
|
|
import {createServer} from 'node:http'
|
|
import {randomBytes} from 'node:crypto'
|
|
const database=process.env.MMAPP_OWN_SQL_DB,url=new URL(process.env.DATABASE_URL)
|
|
assert(/^mm_accept_166_\d+$/.test(database??''));assert.equal(url.pathname,'/'+database);assert.equal(url.username,database)
|
|
process.env.AUTH_REQUIRED='true';process.env.AUTH_JWT_SECRET=randomBytes(32).toString('hex');process.env.AUTH_ISSUER='https://own208.invalid';process.env.AUTH_PORTAL_URL='https://own208.invalid'
|
|
const {pool,closePool}=await import('/app/backend/dist/db/index.js'),{initDatabase}=await import('/app/backend/dist/db/bootstrap.js'),{buildApp}=await import('/app/backend/dist/index.js')
|
|
assert.equal((await pool.query('SELECT current_database() AS name')).rows[0].name,database);assert(Object.values((await pool.query('SELECT rolsuper,rolcreatedb,rolcreaterole,rolbypassrls FROM pg_roles WHERE rolname=current_user')).rows[0]).every(v=>v===false))
|
|
const key=randomBytes(32).toString('base64'),publicKey=randomBytes(32).toString('base64'),baseline=process.env.MMAPP_WG_SECRET_EXPECT==='leak',cases=[];let calls=0,app
|
|
const native=createServer((req,res)=>{calls++;assert.equal(req.method,'GET');res.setHeader('content-type','application/json');res.end(JSON.stringify(req.url.endsWith('/interface/wireguard')?[{'.id':'*1',name:'own208-wg','listen-port':'55108',mtu:'1420','public-key':publicKey,'private-key':key,disabled:'false',running:'true'}]:[]))});await new Promise(r=>native.listen(0,'127.0.0.1',r))
|
|
const report={date:'2026-10-13',block:'12.5.208',database,baseline,cases,scope:'Production compiled WireGuard GET/auth/mapper, own restricted PostgreSQL and local RouterOS HTTP fixture with nonempty synthetic private key; isolated signed JWT',passed:false}
|
|
try{await initDatabase();const port=native.address().port;await pool.query("INSERT INTO servers(name,host,port,use_ssl,enabled,username,password) VALUES('own208-native','127.0.0.1',$1,false,true,'fixture','fixture')",[port]);app=await buildApp({logger:false,startScheduler:false});await app.ready()
|
|
for(const role of ['reader','writer','admin']){const permission='mm:network:'+({reader:'read',writer:'write',admin:'admin'}[role]);const token=app.jwt.sign({sub:'own208-'+role,apps:['mm'],permissions:[permission],iss:process.env.AUTH_ISSUER},{expiresIn:'5m'});for(const flag of ['', '?includePrivateKey=1','?includePrivateKey=true']){const before=calls,r=await app.inject({method:'GET',url:'/api/wireguard'+flag,headers:{authorization:'Bearer '+token}});const denied=!baseline&&role==='reader'&&flag!=='';assert.equal(r.statusCode,denied?403:200);if(denied){assert.equal(calls,before);assert(!r.body.includes(key))}else{const dto=r.json();assert.equal(dto.interfaces.length,1);assert.equal(dto.interfaces[0].publicKey,publicKey);assert.equal(dto.interfaces[0].privateKey,flag?key:undefined)}cases.push({role,flag,status:r.statusCode,privateKeyExposed:!denied&&!!flag,nativeRequestCount:calls-before})}}
|
|
const fakeAdmin=app.jwt.sign({sub:'own208-is-admin',apps:['mm'],permissions:['mm:network:read'],is_admin:true,iss:process.env.AUTH_ISSUER},{expiresIn:'5m'});const before=calls,r=await app.inject({method:'GET',url:'/api/wireguard?includePrivateKey=1',headers:{authorization:'Bearer '+fakeAdmin}});assert.equal(r.statusCode,baseline?200:403);if(!baseline)assert.equal(calls,before);cases.push({name:'is_admin alone',status:r.statusCode,permissionRequired:true});assert.equal((await app.inject({method:'GET',url:'/api/wireguard?includePrivateKey=1'})).statusCode,401);cases.push({role:'unauthenticated',status:401});report.passed=true
|
|
}catch(e){report.errorName=e.name;fs.writeFileSync('/app/backend/acceptance/wireguard208-private.log',String(e.stack??e),{mode:0o600})}finally{if(app)await app.close();native.closeAllConnections();await new Promise(r=>native.close(r));await closePool();fs.writeFileSync('/app/backend/acceptance/wireguard208-'+(baseline?'baseline':'fixed')+'-result.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report))}
|
|
if(!report.passed)process.exitCode=1
|