Porkbun CDS record diff

Display diff of DNSSEC config and CDS records for Porkbun with buttons to fix diffs.

Устаревшая версия за 27.08.2024. Перейдите к последней версии.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name        Porkbun CDS record diff
// @namespace   teiken.dev
// @description Display diff of DNSSEC config and CDS records for Porkbun with buttons to fix diffs.
// @version     1
// @match       https://porkbun.com/account/dnssec/*
// @author      2024, Wilfried Teiken
// @license     MIT
// ==/UserScript==

var domain=window.location.pathname.split("/").pop();
console.log("domain: "+domain);

const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
  if (this.readyState == 4 && this.status == 200) {
    var response = JSON.parse(this.responseText);
    if (response.Status != 0) {
      console.log("Error getting CDS: "+response.Status);
      return;
    }
    if (!response.AD) {
      console.log("CDS was not verified using DNSSEC");
      return;
    }

    // Answer is verified, which means an existing DS was used to sign the CDS and it can be trusted.

    // Extract the CDS entries
    var cds = new Map();
    for (i = 0; i < response.Answer.length; ++i) {
      if (response.Answer[i].type == 59) {
        var record = response.Answer[i].data.split(" ");
        cds.set(record[0], record);
      }
    }

    // Determine which items are already existing
    var existing = new Map();
    var buttons = document.getElementsByTagName("button");
    for (i = 0; i < buttons.length; ++i) {
      if (buttons[i].hasAttributes() && buttons[i].hasAttribute("data-keytag")) {
        existing.set(buttons[i].getAttribute("data-keytag"), buttons[i]);
      }
    }

    // Find the right element to insert the items at.
    var insertPoint;
    var titles = document.getElementsByClassName("lead");
    for (i = 0; i < titles.length; ++i) {
      if (titles[i].textContent == "Current DNSSEC Configuration") {
        insertPoint = titles[i].parentNode;
      }
    }
    if (!insertPoint) {
      for (i = 0; i < titles.length; ++i) {
        if (titles[i].textContent == "Create DNSSEC Record") {
          insertPoint = titles[i].parentNode;
        }
      }
    }

    if (insertPoint) {
      // Create an entry for every key found in the CDS set.
      var newSection = document.createElement("div");
      newSection.setAttribute("class", "alert alert-info");
      newSection.setAttribute("style", "word-break: break-word;");

      var newHeader = document.createElement("p");
      newHeader.setAttribute("class", "lead");
      newHeader.appendChild(document.createTextNode("Target DNSSEC Configuration"));
      newSection.appendChild(newHeader);

      var mismatches = 0;

      for (const [key, value] of cds) {
        var newItem = document.createElement("div");
        newItem.appendChild(document.createElement("br"));
        newItem.appendChild(document.createTextNode("keyTag: "+value[0]));
        newItem.appendChild(document.createElement("br"));
        newItem.appendChild(document.createTextNode("alg: "+value[1]));
        newItem.appendChild(document.createElement("br"));
        newItem.appendChild(document.createTextNode("digestType: "+value[2]));
        newItem.appendChild(document.createElement("br"));
        newItem.appendChild(document.createTextNode("digest: "+value[3]));
        newItem.appendChild(document.createElement("br"));
        if (existing.has(key)) {
          newItem.setAttribute("style", "background-color:#5cb85c; color:#fff; margin:5pt;");
          newItem.appendChild(document.createTextNode("Status: Already in DS"));
        } else {
          newItem.appendChild(document.createTextNode("Status: Missing in DS"));
          newItem.appendChild(document.createElement("br"));
          var newButton = document.createElement("button");
          newButton.textContent = "Add to DS set";
          newButton.setAttribute("class", "btn btn-success");
          newButton.onclick = () => {
            document.getElementById("keyTag").value=value[0];
            document.getElementById("alg").value=value[1];
            document.getElementById("digestType").value=value[2];
            document.getElementById("digest").value=value[3];
            document.getElementById("dnssecCreateButton").click();
          };
          newItem.setAttribute("style", "background-color:#c9302c; color:#fff; margin:5pt;");
          newItem.appendChild(newButton);
          ++mismatches;
        }
        newSection.appendChild(newItem);
      }

      // Replicate the sections from the "current configuration" for all keys not in CDS.
      for (const [key, button] of existing) {
        if (!cds.has(key)) {
          var newItem = document.createElement("div");
          var toCopy = button;
          for(i = 0; i < 9; ++i) {
            if (toCopy.previousSibling) {
              toCopy = toCopy.previousSibling;
            }
          }
          while (toCopy != button) {
            newItem.appendChild(toCopy.cloneNode());
            toCopy = toCopy.nextSibling;
          }
          newItem.appendChild(document.createTextNode("Status: Should be removed from DS"));
          newItem.appendChild(document.createElement("br"));
          var newButton = button.cloneNode();
          newButton.textContent = "DELETE";
          newItem.appendChild(newButton);
          newItem.setAttribute("style", "background-color:#c9302c; color:#fff; margin:5pt;");
          newSection.appendChild(newItem);
          ++mismatches;
        }
      }
      if (mismatches > 0) {
        insertPoint.parentNode.insertBefore(newSection, insertPoint);
      }
    }
  }
}
xhttp.open("GET", "https://dns.google/resolve?name="+domain+"&type=CDS", true);
xhttp.send();