From a070cfcc1fc95a33cdcfa325c44cefc92e786006 Mon Sep 17 00:00:00 2001 From: aedes Date: Wed, 22 Apr 2026 02:46:00 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20radical=20=E2=80=94=20serve=20full-page?= =?UTF-8?q?=20screenshot=20instead=20of=20fragile=20DOM=20clone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/mirror.js | 88 ++++++++++++++++------------------------------- 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/scripts/mirror.js b/scripts/mirror.js index 2541fd9..f217857 100644 --- a/scripts/mirror.js +++ b/scripts/mirror.js @@ -104,7 +104,8 @@ async function main() { const browser = await chromium.launch({ headless: true }); const ctx = await browser.newContext({ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', - viewport: { width: 1440, height: 900 }, + viewport: { width: 1600, height: 900 }, + deviceScaleFactor: 2, }); await ctx.addCookies([{ name: 'MoodleSession', @@ -115,71 +116,42 @@ async function main() { sameSite: 'None', }]); - const resources = new Map(); const page = await ctx.newPage(); - - page.on('response', async (resp) => { - const rurl = resp.url(); - if (!rurl.startsWith('http')) return; - try { - const buf = await resp.body(); - const ct = resp.headers()['content-type'] || ''; - if (buf && buf.length > 0) resources.set(rurl, { buf, ct }); - } catch (e) { /* redirect/204/etc */ } - }); - await page.goto(targetUrl, { waitUntil: 'networkidle', timeout: 90000 }); console.log(`[mirror] networkidle reached. extra settle…`); await page.waitForTimeout(4000); - // Re-inline all CSS into + + +
+${CHAT_OVERLAY} + +`; - // 3. Strip CSP / XFO meta - finalHtml = finalHtml.replace(/]+http-equiv=["']?(Content-Security-Policy|X-Frame-Options)["']?[^>]*>/gi, ''); - - // 4. Strip ALL scripts — static snapshot, no dynamic code that'd break on our domain - finalHtml = finalHtml.replace(/)<[^<]*)*<\/script>/gi, ''); - - // 5. Neutralize - finalHtml = finalHtml.replace(/]*>/gi, ''); - - // 6. Inject chat overlay (AFTER script strip so overlay scripts survive) - finalHtml = finalHtml.replace(/<\/body>/i, CHAT_OVERLAY + ''); - - fs.writeFileSync(path.join(OUT, 'index.html'), finalHtml, 'utf8'); - console.log(`[mirror] wrote ${path.join(OUT, 'index.html')} (${finalHtml.length} bytes)`); + fs.writeFileSync(path.join(OUT, 'index.html'), wrapperHtml, 'utf8'); + console.log(`[mirror] wrote ${path.join(OUT, 'index.html')}`); await browser.close(); console.log('[mirror] done');