Porkbun CDS record diff

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

目前為 2024-08-31 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name Porkbun CDS record diff
  3. // @namespace teiken.dev
  4. // @description Display diff of DNSSEC config and CDS records for Porkbun with buttons to fix diffs.
  5. // @version 1.01
  6. // @match https://porkbun.com/account/dnssec/*
  7. // @author 2024, Wilfried Teiken
  8. // @license MIT
  9. // ==/UserScript==
  10.  
  11. var domain=window.location.pathname.split("/").pop();
  12. console.log("domain: "+domain);
  13.  
  14. const xhttp = new XMLHttpRequest();
  15. xhttp.onload = function() {
  16. if (this.readyState == 4 && this.status == 200) {
  17. var response = JSON.parse(this.responseText);
  18. if (response.Status != 0) {
  19. console.log("Error getting CDS: "+response.Status);
  20. return;
  21. }
  22. if (!response.AD) {
  23. console.log("CDS was not verified using DNSSEC");
  24. return;
  25. }
  26.  
  27. // Answer is verified, which means an existing DS was used to sign the CDS and it can be trusted.
  28.  
  29. // Extract the CDS entries
  30. var cds = new Map();
  31. for (i = 0; i < response.Answer.length; ++i) {
  32. if (response.Answer[i].type == 59) {
  33. var record = response.Answer[i].data.split(" ");
  34. cds.set(record[0], record);
  35. }
  36. }
  37.  
  38. // Determine which items are already existing
  39. var existing = new Map();
  40. var buttons = document.getElementsByTagName("button");
  41. for (i = 0; i < buttons.length; ++i) {
  42. if (buttons[i].hasAttributes() && buttons[i].hasAttribute("data-keytag")) {
  43. existing.set(buttons[i].getAttribute("data-keytag"), buttons[i]);
  44. }
  45. }
  46.  
  47. // Find the right element to insert the items at.
  48. var insertPoint;
  49. var titles = document.getElementsByClassName("lead");
  50. for (i = 0; i < titles.length; ++i) {
  51. if (titles[i].textContent == "Create DNSSEC Record") {
  52. insertPoint = titles[i].parentNode;
  53. }
  54. }
  55.  
  56. if (insertPoint) {
  57. // Create an entry for every key found in the CDS set.
  58. var newSection = document.createElement("div");
  59. newSection.setAttribute("class", "alert alert-info");
  60. newSection.setAttribute("style", "word-break: break-word;");
  61.  
  62. var newHeader = document.createElement("p");
  63. newHeader.setAttribute("class", "lead");
  64. newHeader.appendChild(document.createTextNode("Target DNSSEC Configuration (based on CDS records)"));
  65. newSection.appendChild(newHeader);
  66.  
  67. for (const [key, value] of cds) {
  68. var newItem = document.createElement("div");
  69. newItem.appendChild(document.createElement("br"));
  70. newItem.appendChild(document.createTextNode("keyTag: "+value[0]));
  71. newItem.appendChild(document.createElement("br"));
  72. newItem.appendChild(document.createTextNode("alg: "+value[1]));
  73. newItem.appendChild(document.createElement("br"));
  74. newItem.appendChild(document.createTextNode("digestType: "+value[2]));
  75. newItem.appendChild(document.createElement("br"));
  76. newItem.appendChild(document.createTextNode("digest: "+value[3]));
  77. newItem.appendChild(document.createElement("br"));
  78. if (existing.has(key)) {
  79. newItem.appendChild(document.createTextNode("Status: Already in DS set"));
  80. newItem.setAttribute("style", "background-color:#D8E2D2; margin:5pt;");
  81. } else {
  82. newItem.appendChild(document.createTextNode("Status: Should be added to DS set"));
  83.  
  84. newItem.appendChild(document.createElement("br"));
  85. var newButton = document.createElement("button");
  86. newButton.textContent = "Add to DS set";
  87. newButton.setAttribute("class", "btn btn-success");
  88. newButton.onclick = () => {
  89. document.getElementById("keyTag").value=value[0];
  90. document.getElementById("alg").value=value[1];
  91. document.getElementById("digestType").value=value[2];
  92. document.getElementById("digest").value=value[3];
  93. document.getElementById("dnssecCreateButton").click();
  94. };
  95. newItem.appendChild(newButton);
  96. newItem.setAttribute("style", "background-color:#F9A2A2; margin:5pt;");
  97. }
  98.  
  99. newSection.appendChild(newItem);
  100. }
  101.  
  102. // Replicate the sections from the "current configuration" for all keys not in CDS.
  103. for (const [key, button] of existing) {
  104. if (!cds.has(key)) {
  105. var newItem = document.createElement("div");
  106. var toCopy = button;
  107. for(i = 0; i < 9; ++i) {
  108. if (toCopy.previousSibling) {
  109. toCopy = toCopy.previousSibling;
  110. }
  111. }
  112. while (toCopy != button) {
  113. newItem.appendChild(toCopy.cloneNode());
  114. toCopy = toCopy.nextSibling;
  115. }
  116. newItem.appendChild(document.createTextNode("Status: Should be removed from DS set"));
  117.  
  118. newItem.appendChild(document.createElement("br"));
  119. var newButton = button.cloneNode();
  120. newButton.textContent = "DELETE from DS set";
  121. newItem.appendChild(newButton);
  122. newItem.setAttribute("style", "background-color:#F9A2A2; margin:5pt;");
  123.  
  124. newSection.appendChild(newItem);
  125. }
  126. }
  127. insertPoint.parentNode.insertBefore(newSection, insertPoint);
  128. }
  129. }
  130. }
  131. xhttp.open("GET", "https://dns.google/resolve?name="+domain+"&type=CDS", true);
  132. xhttp.send();