// Dashboard screenshots for felhom.eu (2026-10-08): demo-hp's household guest 9201 (read only; run from 9202), controller 0.303.0, through traefik with the // real host name, headless Chrome. The session cookie comes from a 0600 file (never printed); each page's visible text // is saved beside its picture for the privacy scan. const puppeteer = require('puppeteer'); const fs = require('fs'); const sleep = ms => new Promise(r => setTimeout(r, ms)); const HOST = 'felhom.enkisfelhom.hu', BASE = 'https://' + HOST; const sess = fs.readFileSync('/out/session.txt', 'utf8').trim(); // felhom_session=… const APP = process.env.APP || 'immich'; const PAGES = (process.env.PAGES ? process.env.PAGES.split(',').map(x => x.split('=')) : [['start', '/launcher'], ['apps', '/stacks'], ['app', '/apps/' + APP], ['backups', '/backups'], ['system', '/settings']]); async function setLang(p, lang) { await p.goto(BASE + '/launcher', {waitUntil: 'networkidle2'}); const btn = await p.$(`button.lang-globe-item[value="${lang}"]`); if (!btn) throw new Error('no globe item ' + lang); await p.evaluate(b => b.closest('form').submit(), btn); await p.waitForNavigation({waitUntil: 'networkidle2'}).catch(() => {}); const got = await p.$eval('html', e => e.lang); console.log('language now', got); } async function shot(p, name) { await sleep(1500); await p.screenshot({path: `/out/${name}.png`}); const t = await p.evaluate(() => document.body.innerText + '\n' + Array.from(document.querySelectorAll('[title],[alt],[placeholder],input[value]')).map(e => [e.title, e.alt, e.placeholder, e.value].join(' ')).join('\n')); fs.writeFileSync(`/out/${name}.txt`, t); console.log('shot', name); } (async () => { const b = await puppeteer.launch({args: ['--no-sandbox', '--ignore-certificate-errors', `--host-resolver-rules=MAP * ${process.env.TRAEFIK}`]}); const p = await b.newPage(); const [k, v] = sess.split('='); await p.setCookie({name: k, value: v, domain: HOST, path: '/', secure: true, httpOnly: true}); for (const lang of (process.env.LANGS || 'hu,en').split(',')) { await p.setViewport({width: 1440, height: 900, deviceScaleFactor: 1}); for (const [name, path] of PAGES) { await p.goto(BASE + path, {waitUntil: 'networkidle2'}); await shot(p, `${name}-${lang}`); } if (process.env.NOPHONE) continue; await p.setViewport({width: 390, height: 844, deviceScaleFactor: 2, isMobile: true, hasTouch: true}); await p.goto(BASE + '/launcher', {waitUntil: 'networkidle2'}); await shot(p, `phone-${lang}`); } await b.close(); })().catch(e => { console.error(e); process.exit(1); });