Files
SGF/scripts/sgf-hr-readable-download.mjs
2026-11-11 15:04:01 +02:00

3 lines
2.9 KiB
JavaScript

import fs from'node:fs';import assert from'node:assert/strict';import crypto from'node:crypto';import{personnelReadableDownload}from'../resources/js/statement-download.js';
const root=JSON.parse(fs.readFileSync('C:/laragon/data/sgf-tempo/run/modular-regression-current.json')).root+'/private/receipt-composition-cc50a276c10c',checks=[],ok=(v,n)=>{assert(v,n);checks.push(n);},body=Buffer.from('\uFEFFResumo QA;8h 00min\r\n'),sha=crypto.createHash('sha256').update(body).digest('hex'),source='a'.repeat(64),headers={'Content-Type':'text/csv; charset=utf-8','X-Content-SHA256':sha,'X-Source-SHA256':source,'X-SGF-Read-Format':'SGF-HR-READABLE-CSV-v1'};let sent=null;const args={id:99,token:'qa-only-token',sourceSha256:source,isCurrent:()=>true,fetcher:async(path,options)=>{sent={path,options};return new Response(body,{headers});}};const out=await personnelReadableDownload(args);ok(Buffer.from(out.bytes).equals(body)&&out.sourceSha256===source,'exact derived bytes with original source reference preserved');ok(sent.path==='/api/hr-personnel/readable/99'&&!sent.path.includes(args.token)&&sent.options.headers['X-SGF-Context']===args.token&&sent.options.credentials==='same-origin','fixed same-origin route and context only in header');for(const[k,v]of[['X-Source-SHA256','b'.repeat(64)],['X-SGF-Read-Format','other'],['Content-Type','text/html'],['X-Content-SHA256','0'.repeat(64)]]){await assert.rejects(personnelReadableDownload({...args,fetcher:async()=>new Response(body,{headers:{...headers,[k]:v}})}));ok(true,'wrong derived response refused '+k);}let called=false;await assert.rejects(personnelReadableDownload({...args,isCurrent:()=>false,fetcher:async()=>{called=true;return new Response(body,{headers});}}));ok(!called,'obsolete context blocks fetch');let current=true;await assert.rejects(personnelReadableDownload({...args,isCurrent:()=>current,fetcher:async()=>({ok:true,headers:new Headers(headers),arrayBuffer:async()=>{current=false;return body.buffer.slice(body.byteOffset,body.byteOffset+body.byteLength);}})}));ok(true,'context change after body blocks saving');await assert.rejects(personnelReadableDownload({...args,fetcher:async()=>new Response(JSON.stringify({message:'Sem acesso'}),{status:403,headers:{'Content-Type':'application/json'}})}),e=>e.status===403);ok(true,'denied access preserved as403');for(const id of[0,1.5,'../1'])await assert.rejects(personnelReadableDownload({...args,id}));ok(true,'invalid identifiers rejected before request');const original=fs.readFileSync(root+'/app/resources/js/statement-download.js','utf8'),latest=fs.readFileSync('resources/js/statement-download.js','utf8');ok(latest.startsWith(original.trimEnd()),'all original download mechanisms unchanged byte prefix');const file=root+'/hp-readable-download-20261111.json';fs.writeFileSync(file,JSON.stringify({passed:true,checks,business_commands:0,browser_visual_review:false},null,2));console.log(JSON.stringify({passed:true,checks:checks.length,proof:file}));