19 lines
2.3 KiB
JavaScript
19 lines
2.3 KiB
JavaScript
/** Exact avatar recovery from formal public REA binary export; no original FS access here. */
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import crypto from 'node:crypto'
|
|
import {spawnSync} from 'node:child_process'
|
|
const analysis=JSON.parse(fs.readFileSync('.tmp/rea-cpp-expert-package-analysis-20261016.json','utf8'))
|
|
const inventory=JSON.parse(fs.readFileSync('.tmp/rea-cpp-inventory-ev_d8bab73f2bffe8f99a6af2e4d50f9a820ec3ec8a4ea8cff3a4ef4bc9063a4a83.json','utf8')).normalized_result
|
|
const member=inventory.members.find(m=>m.path==='avatars/expert.png'),pin='b90023e9622bd74c55d583051bee3625eb491b552baeea17ae10ac792a352498'
|
|
if(inventory.root_sha256!==pin||analysis.normalized_result.root_artifact_sha256!==pin||member?.size_bytes!==420773)throw Error('Pinned inventory mismatch')
|
|
const r=spawnSync(process.execPath,['.tmp/rea-css-runtime/scripts/rea.mjs','export-selected-directory-binary',analysis.normalized_result.input_path,pin,JSON.stringify([{path:member.path,sha256:member.sha256}])],{encoding:'utf8',maxBuffer:8*1024*1024})
|
|
if(r.status!==0)throw Error(r.stderr||r.stdout)
|
|
const evidence=JSON.parse(r.stdout),file=evidence.normalized_result.files[0],bytes=Buffer.from(file.data_base64,'base64'),hash=b=>crypto.createHash('sha256').update(b).digest('hex')
|
|
if(evidence.normalized_result.root_sha256!==pin||file.sha256!==member.sha256||hash(bytes)!==member.sha256||bytes.length!==420773)throw Error('REA binary SHA/size mismatch')
|
|
const exportPath=`.tmp/rea-cpp-binary-${evidence.evidence_id}.json`;fs.writeFileSync(exportPath,JSON.stringify(evidence))
|
|
const recovered='.tmp/rea-cpp-expert-recovered-20261016',output=path.join(recovered,member.path);fs.mkdirSync(path.dirname(output),{recursive:true});fs.writeFileSync(output,bytes)
|
|
if(hash(fs.readFileSync(output))!==member.sha256)throw Error('Recovered binary SHA mismatch')
|
|
const manifestPath=path.join(recovered,'evidence-manifest.json'),manifest=JSON.parse(fs.readFileSync(manifestPath,'utf8'));manifest.files=manifest.files.filter(f=>f.path!==member.path);manifest.files.push({path:member.path,bytes:bytes.length,sha256:file.sha256,evidenceId:evidence.evidence_id,encoding:'base64',mediaType:'image/png',retainedExport:exportPath});fs.writeFileSync(manifestPath,JSON.stringify(manifest,null,2)+'\n')
|
|
console.log(JSON.stringify({output,evidenceId:evidence.evidence_id,sha256:file.sha256,bytes:bytes.length,exportPath}))
|