46 lines
6.0 KiB
JavaScript
46 lines
6.0 KiB
JavaScript
// Ephemeral loopback/nonce diagnostic. No authentication, domain data or document records.
|
|
const fs=require('node:fs'),path=require('node:path'),crypto=require('node:crypto'),assert=require('node:assert/strict');
|
|
const {chromium}=require('C:/Users/macbook/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
|
|
const ROOT=path.resolve(__dirname,'..'),PRIV=path.join(ROOT,'storage/app/private/investmoz-v2/portal-audit'),REV='41caea0f900fe0705e84e065a65f9534ff3a585ee34098f860666f522875a3a5';
|
|
const manifest=JSON.parse(fs.readFileSync(path.join(ROOT,'outputs/investmoz-workflow-consolidated-20261011/manifesto.json')));
|
|
const nonce=crypto.randomBytes(32).toString('hex'),name='.workflow-web-'+crypto.randomBytes(12).toString('hex')+'.php',file=path.join(ROOT,'public',name);
|
|
const hash=crypto.createHash('sha256').update(nonce).digest('hex');
|
|
const source=`<?php
|
|
ini_set('display_errors','0');
|
|
if(!in_array($_SERVER['REMOTE_ADDR']??'', ['127.0.0.1','::1'],true)||!hash_equals('${hash}',hash('sha256',$_SERVER['HTTP_X_INVESTMOZ_TECHNICAL_PROBE']??''))){http_response_code(404);exit;}
|
|
header('Content-Type: application/json');header('Cache-Control: no-store');
|
|
$result=['sapi'=>PHP_SAPI,'php'=>PHP_VERSION,'upload'=>ini_get('upload_max_filesize'),'post'=>ini_get('post_max_size'),'memory'=>ini_get('memory_limit'),'time'=>ini_get('max_execution_time'),'gd'=>extension_loaded('gd'),'webp'=>function_exists('imagewebp'),'HTTPS'=>($_SERVER['HTTPS']??'')==='on','records_created'=>0];
|
|
if($_SERVER['REQUEST_METHOD']==='POST'){$f=$_FILES['probe']??null;$result['upload_error']=$f['error']??null;$result['uploaded_size']=$f['size']??0;$result['temporary_upload_valid']=$f&&$f['error']===0&&is_uploaded_file($f['tmp_name']);if($f&&$f['error']!==0)http_response_code(422);}
|
|
echo json_encode($result);
|
|
`;
|
|
assert(!fs.existsSync(file));fs.writeFileSync(file,source,{flag:'wx'});
|
|
const earlier=process.argv.includes('--remaining')?JSON.parse(fs.readFileSync(path.join(PRIV,'workflow-activation-web-proof.json'))):null;
|
|
if(earlier){assert.equal(earlier.revision,REV);assert.equal(earlier.web.upload,'20M');assert.equal(earlier.uploads.length,4);assert.equal(earlier.uploads[2].upload_error,1);}
|
|
const proof={at:new Date().toISOString(),revision:REV,result:'started',TLS_bypass:false,records_created:0,operational_flags_enabled:false};let browser;
|
|
const save=(phase)=>{proof.phase=phase;fs.writeFileSync(path.join(PRIV,'workflow-activation-web-progress.json'),JSON.stringify(proof,null,2));console.log(JSON.stringify({phase}));};
|
|
(async()=>{
|
|
try{
|
|
save('launching');
|
|
browser=await chromium.launch({headless:true,executablePath:'C:/Users/macbook/AppData/Local/ms-playwright/chromium-1243/chrome-win64/chrome.exe'});
|
|
const ctx=await browser.newContext({ignoreHTTPSErrors:false,extraHTTPHeaders:{'X-InvestMoz-Technical-Probe':nonce}}),page=await ctx.newPage();
|
|
page.setDefaultTimeout(20000);save('checking_effective_web_configuration');
|
|
const r=await page.goto('https://portal-investidor.test/'+name);assert.equal(r.status(),200);proof.tls=await r.securityDetails();proof.web=JSON.parse(await page.locator('body').innerText());
|
|
assert.equal(proof.web.sapi,'apache2handler');assert.equal(proof.web.php,'8.5.11');assert.equal(proof.web.upload,'20M');assert.equal(proof.web.post,'24M');assert.equal(proof.web.memory,'256M');assert.equal(proof.web.time,'180');assert(proof.web.gd&&proof.web.webp&&proof.web.HTTPS);
|
|
proof.secure_context=await page.evaluate(()=>isSecureContext);assert(proof.secure_context);
|
|
save('web_configuration_passed');
|
|
proof.uploads=earlier?earlier.uploads:[];if(earlier)proof.upload_evidence_reused_from=earlier.at;
|
|
for(const size of earlier?[]:[3*1024*1024,20*1024*1024,21*1024*1024,3*1024*1024]){
|
|
const v=await page.evaluate(async({name,size,nonce})=>{const data=new FormData();data.append('probe',new Blob([new Uint8Array(size)],{type:'application/octet-stream'}),'technical-probe.bin');const r=await fetch('/'+name,{method:'POST',headers:{'X-InvestMoz-Technical-Probe':nonce},body:data});return {status:r.status,value:await r.json()};},{name,size,nonce});
|
|
if(size<=20*1024*1024){assert.equal(v.status,200);assert(v.value.temporary_upload_valid);assert.equal(v.value.uploaded_size,size);}else{assert.equal(v.status,422);assert.equal(v.value.upload_error,1);}
|
|
proof.uploads.push({submitted_bytes:size,status:v.status,upload_error:v.value.upload_error,temporary_upload_valid:v.value.temporary_upload_valid});
|
|
save('upload_'+size+'_verified');
|
|
}
|
|
await page.setExtraHTTPHeaders({'X-InvestMoz-Technical-Probe':'invalid'});
|
|
const denied=await page.evaluate(async name=>(await fetch('/'+name,{signal:AbortSignal.timeout(20000)})).status,name);assert.equal(denied,404);proof.diagnostic_denies_missing_nonce=true;save('diagnostic_authorization_passed');
|
|
const redirects=[];page.on('response',r=>{if(r.request().isNavigationRequest())redirects.push({status:r.status(),origin:new URL(r.url()).origin,path:new URL(r.url()).pathname});});save('checking_portal_redirect');await page.goto('http://portal-investidor.test/login',{waitUntil:'domcontentloaded',timeout:20000});assert.equal(page.url(),'https://portal-investidor.test/login');assert(redirects.some(r=>r.status===308));proof.portal_HTTP_redirect=redirects;save('portal_redirect_passed');
|
|
const defaultResponse=await page.goto('http://localhost/',{waitUntil:'domcontentloaded',timeout:20000});proof.other_vhost={hostname:'localhost',status:defaultResponse.status(),origin:new URL(page.url()).origin};assert(defaultResponse.status()<500);assert.equal(new URL(page.url()).protocol,'http:');save('other_vhost_passed');
|
|
proof.result='passed';
|
|
}catch(e){proof.result='stopped_before_authenticated_installation';proof.error_type=e.name;proof.message=e.message.slice(0,220);process.exitCode=1;}
|
|
finally{assert(fs.readFileSync(file,'utf8')===source);fs.unlinkSync(file);proof.ephemeral_diagnostic_removed=true;fs.writeFileSync(path.join(PRIV,'workflow-activation-web-proof.json'),JSON.stringify(proof,null,2));console.log(JSON.stringify(proof));if(browser)await browser.close();}
|
|
})();
|