Skip to content

Commit a8b4423

Browse files
committed
add "report..." button
1 parent cf0fad4 commit a8b4423

File tree

3 files changed

+154
-4
lines changed

3 files changed

+154
-4
lines changed

assets/spa.js

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import rdapValidator from "../lib/rdap-validator.js";
22

33
rdapValidator.punycode = punycode;
44

5+
const canReport = function() {
6+
return (
7+
"domain" === rdapValidator.lastTestedResponseType &&
8+
["gtld-registry", "gtld-registrar"].includes(rdapValidator.lastTestedServerType)
9+
);
10+
};
11+
512
rdapValidator.setTestCompleteCallback(function() {
613
const testedURL = new URL(rdapValidator.lastTestedURL);
714
window.title = "RDAP Validator : " + testedURL.pathname.split("/").pop() + " : " + rdapValidator.lastTestedResponseType + " : " + rdapValidator.lastTestedServerType;
@@ -17,6 +24,10 @@ rdapValidator.setTestCompleteCallback(function() {
1724
window.history.pushState(null, window.title, url.href);
1825

1926
document.getElementById("tree").appendChild(jsonToHTML(rdapValidator.lastTestedResponse, "response-$"));
27+
28+
if (canReport()) {
29+
document.getElementById("report-button").disabled = false;
30+
}
2031
});
2132

2233
function jsonToHTML(value, path, objectIsReallyArray) {
@@ -224,6 +235,8 @@ Object.keys(rdapValidator.serverTypes).forEach(function(type) {
224235

225236
const clickFunction = function() {
226237

238+
document.getElementById("report-button").disabled = true;
239+
227240
document.getElementById("result-container").removeAttribute("hidden");
228241

229242
const el = document.getElementById("results");
@@ -262,4 +275,120 @@ let doTest = false;
262275
}
263276
});
264277

265-
if (doTest) document.getElementById("button").click();
278+
const button = document.getElementById("button");
279+
280+
button.disabled = false;
281+
282+
if (doTest) button.click();
283+
284+
const sendEmailTo = function(entity) {
285+
let lastTestedURL = rdapValidator.testedURL;
286+
287+
try {
288+
lastTestedURL = rdapValidator.lastTestedResponse.links.filter(l => "self" == l.rel && "application/rdap+json" == l.type).shift().href;
289+
290+
} catch (e) {
291+
console.log(e);
292+
293+
}
294+
295+
try {
296+
const email = entity.vcardArray[1].filter(p => "EMAIL" === p[0].toUpperCase()).shift()[3];
297+
298+
const url = new URL("mailto:"+email);
299+
300+
let subject, body;
301+
302+
if (rdapValidator.errors < 1) {
303+
subject = 'No issues with your RDAP server';
304+
body = [
305+
"Hey there, I tested your RDAP server using the RDAP Validator at this URL:",
306+
"",
307+
document.location.href,
308+
"",
309+
"And everything looks fine! Thanks for your care and attention.",
310+
];
311+
312+
} else {
313+
subject = `I found ${self.errors} error(s) with your RDAP server`;
314+
315+
body = [
316+
"***NOTE TO SENDER: PLEASE BE POLITE!***",
317+
"",
318+
"Hey there, I found an issue with your RDAP server using the RDAP Validator at this URL:",
319+
"",
320+
document.location.href,
321+
"",
322+
`Tested URL: ${lastTestedURL}`,
323+
`Response Type: ${rdapValidator.responseTypes[rdapValidator.lastTestedResponseType]}`,
324+
`Server Type: ${rdapValidator.serverTypes[rdapValidator.lastTestedServerType]}`,
325+
"",
326+
"List of errors:",
327+
"",
328+
];
329+
330+
rdapValidator.log.forEach(function(msg) {
331+
if (false === msg[0]) {
332+
body.push(`Error: ${msg[1]}`);
333+
if ("$" !== msg[2]) body.push(`JSON Path: ${msg[2]}`);
334+
if (msg[3]) body.push(`Reference: ${msg[3]}`);
335+
body.push("");
336+
}
337+
});
338+
339+
body.push("Server response:", "");
340+
341+
Object.keys(rdapValidator.lastTestedResponseHeaders).forEach(function(k) {
342+
body.push(k + ": " + rdapValidator.lastTestedResponseHeaders[k]);
343+
});
344+
body.push("");
345+
body = body.concat(JSON.stringify(rdapValidator.lastTestedResponse, null, " ").split("\n"));
346+
}
347+
348+
subject = escape(subject);
349+
body = escape(body.join("\n"));
350+
351+
url.search = `?subject=${subject}&body=${body}`;
352+
353+
const iframe = document.createElement('iframe');
354+
iframe.setAttribute('src', url.toString());
355+
iframe.style.setProperty('display', 'none');
356+
357+
document.body.appendChild(iframe);
358+
359+
} catch (e) {
360+
console.log(e);
361+
362+
}
363+
};
364+
365+
document.getElementById("report-button").addEventListener("click", function() {
366+
if (canReport()) {
367+
if ("gtld-registry" === rdapValidator.lastTestedServerType) {
368+
const tld = rdapValidator.lastTestedObject.split(".").pop();
369+
fetch(`https://rdap.iana.org/domain/${tld}`).then(
370+
res => res.json().then(function (record) {
371+
try {
372+
const entity = record.entities.filter(e => e.roles.includes("technical")).shift();
373+
sendEmailTo(entity);
374+
375+
} catch (e) {
376+
console.log(e);
377+
378+
}
379+
})
380+
);
381+
} else if ("gtld-registrar" === rdapValidator.lastTestedServerType) {
382+
try {
383+
const rar = rdapValidator.lastTestedResponse.entities.filter(e => e.roles.includes("registrar")).shift();
384+
const gurid = rar.publicIds.filter(id => "IANA Registrar ID" === id.type).shift().identifier;
385+
386+
fetch(`https://registrars.rdap.org/entity/${gurid}-iana`).then(res => res.json().then(entity => sendEmailTo(entity)));
387+
388+
} catch (e) {
389+
console.log(e);
390+
391+
}
392+
}
393+
}
394+
});

index.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131

3232
<br>
3333

34-
<p><input class="btn btn-secondary" id="button" type="button" value="Test"></p>
34+
<p>
35+
<input class="btn btn-secondary" id="button" type="button" value="Test" disabled>
36+
<input class="btn btn-secondary" id="report-button" type="button" value="Report..." disabled title="Send a copy of this report to the registry/registrar...">
37+
</p>
3538
</form>
3639

3740
<div id="result-container" hidden>

lib/rdap-validator.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ self.version = '0.0.1';
1515
self.testURL = function(url, type, serverType) {
1616

1717
self.errors = 0;
18+
self.log = [];
1819

1920
if (!self.responseTypes.hasOwnProperty(type)) {
2021
self.add(false, "Invalid response type '" + type + "'.");
@@ -37,6 +38,7 @@ self.testURL = function(url, type, serverType) {
3738
self.lastTestedURL = url;
3839
self.lastTestedResponseType = type;
3940
self.lastTestedServerType = serverType;
41+
self.lastTestedObject = null;
4042

4143
self.msg("Sending request...");
4244

@@ -134,6 +136,8 @@ self.validateResponse = function(record, url, type, serverType) {
134136

135137
name = self.nameFromPath(url);
136138

139+
self.lastTestedObject = name;
140+
137141
switch (serverType) {
138142
case "gtld-registry": self.validateGTLDRegistryDomain(record, name); break;
139143
case "gtld-registrar": self.validateGTLDRegistrarDomain(record, name); break;
@@ -147,6 +151,8 @@ self.validateResponse = function(record, url, type, serverType) {
147151

148152
name = self.nameFromPath(url);
149153

154+
self.lastTestedObject = name;
155+
150156
switch (serverType) {
151157
case "gtld-registry": self.validateGTLDNameserver(record, name); break;
152158
case "rir": self.validateRIRNameserver(record, name); break;
@@ -159,6 +165,8 @@ self.validateResponse = function(record, url, type, serverType) {
159165

160166
const handle = decodeURI((new URL(url)).pathname.split("/").pop());
161167

168+
self.lastTestedObject = handle;
169+
162170
switch (serverType) {
163171
case "gtld-registry": self.validateGTLDEntity(record, handle); break;
164172
case "rir": self.validateRIREntity(record, handle); break;
@@ -2727,11 +2735,21 @@ self.setTestCompleteCallback = function(callback) {
27272735
self.add = function(result, message, ref) {
27282736
if (false === result) self.errors++;
27292737

2738+
const path = self.getPath();
2739+
const refURL = null === result ? null : self.ref(ref);
2740+
2741+
self.log.push([
2742+
result,
2743+
message,
2744+
path,
2745+
refURL,
2746+
]);
2747+
27302748
self.resultCallback(
27312749
result,
27322750
message,
2733-
self.getPath(),
2734-
null === result ? null : self.ref(ref),
2751+
path,
2752+
refURL,
27352753
);
27362754

27372755
return result;

0 commit comments

Comments
 (0)