Files
compras/scripts/evaluation-access-check.mjs
2026-10-30 20:14:24 +02:00

179 lines
5.0 KiB
JavaScript

import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
const base = 'http://127.0.0.1:8005';
const cookies = new Map();
async function request(
path,
method = 'GET',
body,
accept = 'application/json',
) {
const response = await fetch(base + path, {
method,
redirect: 'manual',
headers: {
Accept: accept,
Cookie: [...cookies].map(([k, v]) => `${k}=${v}`).join('; '),
...(body
? { 'Content-Type': 'application/x-www-form-urlencoded' }
: {}),
},
...(body ? { body: new URLSearchParams(body) } : {}),
});
for (const cookie of response.headers.getSetCookie()) {
const pair = cookie.split(';', 1)[0],
index = pair.indexOf('=');
cookies.set(pair.slice(0, index), pair.slice(index + 1));
}
return {
status: response.status,
text: await response.text(),
location: response.headers.get('location'),
};
}
const token = (text) => text.match(/name="_token" value="([^"]+)"/)[1];
async function enter(role, destination = '/dashboard') {
const page = await request('/avaliar');
assert.equal(page.status, 200);
const entered = await request('/avaliar/entrar', 'POST', {
role,
_token: token(page.text),
});
assert.equal(entered.status, 302, role);
assert.equal(new URL(entered.location).pathname, destination);
assert.equal((await request('/dashboard')).status, 200);
return entered;
}
let page = await request('/avaliar');
const guestReport = await request(
'/relatorios?status=approved',
'GET',
undefined,
'text/html',
);
assert.equal(guestReport.status, 302);
assert.equal(new URL(guestReport.location).pathname, '/avaliar');
assert.equal(
new URL((await request('/login', 'GET', undefined, 'text/html')).location)
.pathname,
'/avaliar',
);
assert.equal(
(await request('/avaliar/entrar', 'POST', { role: 'admin' })).status,
419,
);
assert.equal(
(
await request('/avaliar/entrar', 'POST', {
role: 'root',
_token: token(page.text),
})
).status,
422,
);
assert.equal(
(
await request('/avaliar/entrar', 'POST', {
role: 'admin',
user_id: '1',
_token: token(page.text),
})
).status,
422,
);
const reportEntry = await enter('admin', '/relatorios');
assert.equal(
new URL(reportEntry.location).searchParams.get('status'),
'approved',
);
const modules = [
'/dashboard',
'/empresa',
'/requisicoes',
'/planeamento',
'/fornecedores',
'/cotacoes',
'/ordens',
'/recepcoes',
'/stock',
'/stock/operacoes',
'/equipamentos',
'/orcamentos',
'/regras-investimento',
'/facturas',
'/pagamentos',
'/obrigacoes-fornecedores',
'/conflitos',
'/revisao-compras',
'/politica-admissao',
'/politica-recomendacao',
'/relatorios',
'/relatorios/medidas-fornecedores',
'/administracao/parametrizacao',
];
for (const path of modules)
assert.equal((await request(path)).status, 200, path);
const roles = [
'requester',
'department_head',
'procurement',
'finance',
'warehouse',
'admin',
];
for (const role of roles) await enter(role);
page = await request('/avaliar');
assert.equal(
(await request('/logout', 'POST', { _token: token(page.text) })).status,
204,
);
assert.equal((await request('/empresa')).status, 401);
assert.equal((await request('/dashboard')).status, 200);
assert.equal((await request('/empresa')).status, 200);
assert.equal((await request('/administracao/parametrizacao')).status, 200);
page = await request('/avaliar');
assert.equal(
(await request('/logout', 'POST', { _token: token(page.text) })).status,
204,
);
assert.equal((await request('/empresa')).status, 401);
const operational = await fetch('http://127.0.0.1:8015/avaliar', {
redirect: 'manual',
}).catch(() => null);
if (operational)
assert.equal(
operational.status,
404,
'Evaluation entry must not exist on the normal installation',
);
await fs.mkdir('docs/proofs', { recursive: true });
await fs.writeFile(
'docs/proofs/evaluation-access.json',
JSON.stringify(
{
checked_at: new Date().toISOString(),
base,
owner_modules: modules,
roles,
csrf_enforced: true,
arbitrary_role_refused: true,
arbitrary_user_refused: true,
logout: true,
business_commands: 0,
real_accounts_changed: false,
operational_entry_status: operational?.status ?? 'not running',
visual_review: false,
dashboard_auto_entry: true,
other_routes_require_session: true,
guest_report_redirect: true,
intended_report_and_filters_preserved: true,
},
null,
2,
) + '\n',
);
console.log(
'Owner entry, 23 module pages, six roles, report return, CSRF, rejected identifiers and logout passed.',
);