39 lines
3.5 KiB
JavaScript
39 lines
3.5 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs/promises';
|
|
|
|
const reports=[];
|
|
for (const [host,port,page] of [['compras',8005,'/obrigacoes-fornecedores'],['sgf',8006,'/supplier-payables']]) {
|
|
const cookies=new Map();
|
|
async function request(path,method='GET',body) {
|
|
const r=await fetch(`http://127.0.0.1:${port}${path}`, {method,redirect:'manual',headers:{Cookie:[...cookies].map(([k,v])=>`${k}=${v}`).join('; '),...(body?{'Content-Type':'application/x-www-form-urlencoded'}:{})},...(body?{body:new URLSearchParams(body)}:{})});
|
|
for(const c of r.headers.getSetCookie()) {const pair=c.split(';',1)[0],i=pair.indexOf('=');cookies.set(pair.slice(0,i),pair.slice(i+1));}
|
|
return {status:r.status,text:await r.text(),location:r.headers.get('location')};
|
|
}
|
|
const token=text=>{const m=text.match(/name="_token" value="([^"]+)"/);assert(m,'CSRF token present');return m[1];};
|
|
const entry=await request('/demo');assert.equal(entry.status,200);assert(!entry.text.includes('type="password"'));
|
|
assert.equal((await request('/demo/entrar','POST',{role:'consulta'})).status,419);
|
|
assert.equal((await request('/demo/entrar','POST',{role:'admin',_token:token(entry.text)})).status,302);
|
|
let baseline;
|
|
for(const role of ['preparacao','validacao','consulta']) {
|
|
const landing=await request('/demo');
|
|
const login=await request('/demo/entrar','POST',{role,_token:token(landing.text)});
|
|
assert.equal(login.status,302,host+' '+role+' '+login.text.slice(0,150));assert(login.location.endsWith(page));
|
|
const ui=await request(page);assert.equal(ui.status,200,host+' authorised page');assert(ui.text.includes('Trocar função ou sair da demonstração'));
|
|
assert.equal(ui.text.includes('data-action="prepare"'),role==='preparacao');
|
|
if(role==='consulta')assert(!ui.text.includes('<form data-action='));
|
|
const data=JSON.parse((await request('/api/supplier-payables')).text);
|
|
assert.equal(data.documents[0].total_minor,1160000);
|
|
const counts=[data.proposals.length,data.obligations.length,data.events.length];
|
|
if(baseline)assert.deepEqual(counts,baseline);else baseline=counts;
|
|
if(host==='sgf'){const session=JSON.parse((await request('/api/session')).text);assert.equal(session.user.email,role+'-obrigacoes@example.test');assert(session.context);assert.equal((await request('/')).status,200);}
|
|
}
|
|
const landing=await request('/demo');assert.equal((await request('/demo/sair','POST',{_token:token(landing.text)})).status,302);
|
|
assert.notEqual((await request(page)).status,200);
|
|
const again=await request('/demo');assert.equal((await request('/demo/entrar','POST',{role:'consulta',_token:token(again.text)})).status,302);
|
|
const recovered=JSON.parse((await request('/api/supplier-payables')).text);assert.deepEqual([recovered.proposals.length,recovered.obligations.length,recovered.events.length],baseline);
|
|
await request('/demo/sair','POST',{_token:token((await request('/demo')).text)});
|
|
reports.push({host,passed:true,password_required:false,roles:['preparacao','validacao','consulta'],csrf_enforced:true,arbitrary_role_refused:true,context_selected:host==='sgf',history_preserved:true,financial_commands_executed:false});
|
|
}
|
|
await fs.writeFile('docs/proofs/payables-demo-entry.json',JSON.stringify({checked_at:new Date().toISOString(),hosts:reports,visual_review:false,public_deployment:false},null,2)+'\n');
|
|
console.log('Password-free synthetic entry passed in both compositions; no financial commands executed.');
|