[object Object]

← back to Domain Landings

5x/contrarian fixes: goLive blocked-embed feedback + LIVE-set restore on re-render + auth-gate /thumbs

995c73738ab87871ed86fcac6cea6eb33bf04bd6 · 2026-08-17 17:09:59 -0700 · Steve Abrams

Files touched

Diff

commit 995c73738ab87871ed86fcac6cea6eb33bf04bd6
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Aug 17 17:09:59 2026 -0700

    5x/contrarian fixes: goLive blocked-embed feedback + LIVE-set restore on re-render + auth-gate /thumbs
---
 server.js | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/server.js b/server.js
index a122ff8..971bce4 100644
--- a/server.js
+++ b/server.js
@@ -241,11 +241,16 @@ sortEl.value=LS('sort','name'); typeEl.value=LS('type','all'); densEl.value=LS('
 function applyDens(){document.documentElement.style.setProperty('--cols',densEl.value);
   const cw=grid.querySelector('.frame'); if(cw){const s=cw.clientWidth/1280;
     document.querySelectorAll('.frame iframe').forEach(f=>f.style.transform='scale('+s+')');}}
-// click a tile -> swap the thumbnail for the LIVE iframe
-function goLive(f){ if(f.dataset.live)return; f.dataset.live=1;
-  const if_=document.createElement('iframe'); if_.src='https://'+f.dataset.dom+'/';
+// click a tile -> swap the thumbnail for the LIVE iframe (with blocked-embed detection)
+const LIVE=new Set();
+function goLive(f){ if(f.dataset.live)return; f.dataset.live=1; const dom=f.dataset.dom; LIVE.add(dom);
+  const if_=document.createElement('iframe'); if_.src='https://'+dom+'/';
   if_.sandbox='allow-scripts allow-same-origin'; if_.style.transform='scale('+(f.clientWidth/1280)+')';
-  f.innerHTML=''; f.appendChild(if_); }
+  let loaded=false; if_.addEventListener('load',()=>loaded=true);
+  f.innerHTML=''; f.appendChild(if_);
+  // X-Frame-Options / frame-ancestors block => load never fires. Give feedback + a way out.
+  setTimeout(()=>{ if(!loaded){ f.dataset.live=''; LIVE.delete(dom);
+    f.innerHTML='<div class=ph>'+dom+'<br><small>⚠ blocks embedding — <a href="https://'+dom+'/" target=_blank rel=noopener style="color:#58a6ff">open directly ↗</a></small></div>'; } },3000); }
 function render(){
   const t=typeEl.value; let list=SITES.filter(s=>t==='all'||s.type===t);
   const sv=sortEl.value;
@@ -259,7 +264,9 @@ function render(){
     '<span class=live>▶ live</span></div>'+
     '<div class=meta><span class=dom><a href="https://'+s.domain+'/" target=_blank rel=noopener>'+s.domain+'</a></span>'+
     '<span class="badge b-'+s.type+'">'+s.type+'</span></div></div>').join('');
-  grid.querySelectorAll('.frame').forEach(f=>f.addEventListener('click',()=>goLive(f))); applyDens();
+  grid.querySelectorAll('.frame').forEach(f=>{f.addEventListener('click',()=>goLive(f));
+    if(LIVE.has(f.dataset.dom)){f.dataset.live='';goLive(f);}}); // restore live iframes after re-render
+  applyDens();
 }
 sortEl.onchange=()=>{localStorage.setItem('wall_sort',sortEl.value);render()};
 typeEl.onchange=()=>{localStorage.setItem('wall_type',typeEl.value);render()};
@@ -274,6 +281,10 @@ const server = http.createServer((req, res) => {
     return adminWall(req, res);
   }
   if (req.method === 'GET' && req.url.startsWith('/thumbs/')) {
+    // same gate as the wall — the authenticated wall page's <img> requests carry the creds
+    if ((req.headers.authorization || '') !== 'Basic ' + Buffer.from(BASIC_AUTH).toString('base64')) {
+      res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="wall"' }).end('auth required'); return;
+    }
     const name = path.basename(req.url.split('?')[0]);           // <domain>.jpg
     if (!/^[a-z0-9.\-]+\.jpg$/i.test(name)) { res.writeHead(400).end(); return; }
     const fp = path.join(__dirname, 'data/thumbs', name);

← ce67c54 5x: portfolio wall clean twice (sweeps 2-3); report  ·  back to Domain Landings  ·  5x/contrarian: server-side frame-block detection (58 sites) a5fd5d4 →