prompt.js raw

   1  // Shadow DOM prompt for non-smesh sites.
   2  // Loaded by content-script when extension needs approval and no onPrompt handler is registered.
   3  
   4  (function() {
   5    const host = document.createElement("div");
   6    const shadow = host.attachShadow({ mode: "closed" });
   7    document.body.appendChild(host);
   8  
   9    let currentResolve = null;
  10  
  11    // Build DOM safely (no innerHTML).
  12    const style = document.createElement("style");
  13    style.textContent = `
  14      .backdrop { position:fixed; inset:0; z-index:2147483647; background:rgba(0,0,0,.5);
  15        display:flex; align-items:center; justify-content:center; font-family:system-ui }
  16      .card { background:#1a1a2e; color:#e0e0e0; padding:24px; border-radius:12px;
  17        max-width:380px; width:90%; box-shadow:0 8px 32px rgba(0,0,0,.4) }
  18      h3 { margin:0 0 8px; font-size:16px; color:#fff }
  19      p { margin:0 0 16px; font-size:14px; line-height:1.4 }
  20      .origin { color:#7b68ee; font-weight:600 }
  21      .kind { color:#ffa500 }
  22      .buttons { display:flex; gap:8px; justify-content:flex-end }
  23      button { padding:8px 20px; border:none; border-radius:6px; font-size:14px; cursor:pointer }
  24      .allow { background:#4caf50; color:#fff }
  25      .allow:hover { background:#45a049 }
  26      .deny { background:#444; color:#ccc }
  27      .deny:hover { background:#555 }`;
  28    shadow.appendChild(style);
  29  
  30    const backdrop = document.createElement("div");
  31    backdrop.className = "backdrop";
  32    backdrop.style.display = "none";
  33  
  34    const card = document.createElement("div");
  35    card.className = "card";
  36  
  37    const h3 = document.createElement("h3");
  38    h3.textContent = "Signing Request";
  39    card.appendChild(h3);
  40  
  41    const p = document.createElement("p");
  42    const originEl = document.createElement("span");
  43    originEl.className = "origin";
  44    const text1 = document.createTextNode(" wants to ");
  45    const kindEl = document.createElement("span");
  46    kindEl.className = "kind";
  47    p.appendChild(originEl);
  48    p.appendChild(text1);
  49    p.appendChild(kindEl);
  50    card.appendChild(p);
  51  
  52    const buttons = document.createElement("div");
  53    buttons.className = "buttons";
  54    const denyBtn = document.createElement("button");
  55    denyBtn.className = "deny";
  56    denyBtn.textContent = "Deny";
  57    const allowBtn = document.createElement("button");
  58    allowBtn.className = "allow";
  59    allowBtn.textContent = "Allow";
  60    buttons.appendChild(denyBtn);
  61    buttons.appendChild(allowBtn);
  62    card.appendChild(buttons);
  63  
  64    backdrop.appendChild(card);
  65    shadow.appendChild(backdrop);
  66  
  67    function show(msg) {
  68      originEl.textContent = msg.origin || location.hostname;
  69      kindEl.textContent = "sign a kind " + (msg.kind || "?") + " event";
  70      backdrop.style.display = "flex";
  71  
  72      return new Promise((resolve) => {
  73        currentResolve = resolve;
  74        setTimeout(() => { resolve(false); hide(); }, 60000);
  75      });
  76    }
  77  
  78    function hide() {
  79      backdrop.style.display = "none";
  80      currentResolve = null;
  81    }
  82  
  83    allowBtn.addEventListener("click", () => { if (currentResolve) { currentResolve(true); hide(); } });
  84    denyBtn.addEventListener("click", () => { if (currentResolve) { currentResolve(false); hide(); } });
  85  
  86    // Listen for PROMPT messages from content-script.
  87    window.addEventListener("message", async (e) => {
  88      if (e.source !== window || !e.data?.broadcast || e.data.payload?.type !== "PROMPT") return;
  89      const allowed = await show(e.data.payload);
  90      window.postMessage({
  91        target: "smesh-signer",
  92        id: e.data.payload.promptId,
  93        payload: { method: "smesh.promptResponse", params: { allowed } }
  94      }, "*");
  95    });
  96  })();
  97