Volver al índice

docs/publicacion/check-published-gallery.cjs

const fs = require('node:fs');
const crypto = require('node:crypto');
const hash = value => crypto.createHash('sha256').update(value).digest('hex');
const files = ['viewer.js', 'media/parasito-crawl3-paredes.mp4', 'media/parasito-crawl3-paredes.png',
  'media/parasito-climb-pared.mp4', 'media/parasito-climb-pared.png',
  'media/parasito-crawl.mp4', 'media/parasito-lore.mp4', 'media/parasito-attack.mp4',
  'auditoria/manifest.json', 'auditoria/codigo/src--main--java--ar--com--companeros--horror--client--ParasiteRig.java.txt'];

// PUBLICACIÓN: comparar bytes anónimos del servidor con los archivos preparados.
(async () => {
  const origins = ['https://raps-huesped.pages.dev/', 'https://preview.raps-huesped.pages.dev/'];
  if (!process.argv.includes('--cloudflare-only')) origins.push('https://raps-galeria-auditoria.jgf1509.chatgpt.site/');
  const version = hash(fs.readFileSync('dist/visor/auditoria/manifest.json')).slice(0, 12);
  const results = await Promise.allSettled(origins.map(async origin => {
    for (const file of files) {
      const response = await fetch(origin + file + '?v=' + version, {signal: AbortSignal.timeout(20000)});
      if (!response.ok) throw new Error(origin + file + ' HTTP ' + response.status);
      const remote = Buffer.from(await response.arrayBuffer());
      if (hash(remote) !== hash(fs.readFileSync('dist/visor/' + file))) throw new Error('Contenido desactualizado: ' + origin + file);
    }
    return {origin, verified_files: files.length, status: 'public bytes match current files'};
  }));
  for (const result of results) {
    if (result.status === 'fulfilled') console.log(JSON.stringify(result.value));
    else {console.error(result.reason.message); process.exitCode = 1;}
  }

  // AUDITORÍA: el manifiesto debe corresponder al texto que recibe el lector.
  const manifest = JSON.parse(fs.readFileSync('dist/visor/auditoria/manifest.json', 'utf8'));
  for (const entry of manifest) {
    const text = fs.readFileSync('dist/visor/auditoria/codigo/' + entry.path.replaceAll('/', '--') + '.txt');
    if (hash(text) !== entry.sha256 || text.length !== entry.bytes) throw new Error('Manifest mismatch: ' + entry.path);
  }
  console.log('Public manifest verified: ' + manifest.length + ' files');
})().catch(error => {console.error(error.message); process.exitCode = 1;});