Reformat /old.tsx

This commit is contained in:
2023-05-23 20:00:26 -05:00
parent ece0ffc7a0
commit f907537042

View File

@@ -1,14 +1,14 @@
import {type NextPage} from "next"; import { type NextPage } from "next";
import Head from "next/head"; import Head from "next/head";
import type {Register, TargetType} from "@/types"; import type { Register, TargetType } from "@/types";
import {placeholders, registryURLs} from "@/constants"; import { placeholders, registryURLs } from "@/constants";
import {domainMatch, getBestURL, getType} from "@/rdap"; import { domainMatch, getBestURL, getType } from "@/rdap";
import type {FormEvent} from "react"; import type { FormEvent } from "react";
import {useEffect, useMemo, useState} from "react"; import { useEffect, useMemo, useState } from "react";
import {truthy} from "@/helpers"; import { truthy } from "@/helpers";
import Generic, {type ParsedGeneric} from "@/components/lookup/Generic"; import Generic, { type ParsedGeneric } from "@/components/lookup/Generic";
import type {ZodSchema} from "zod"; import type { ZodSchema } from "zod";
import {DomainSchema, RegisterSchema} from "@/schema"; import { DomainSchema, RegisterSchema } from "@/schema";
const Old: NextPage = () => { const Old: NextPage = () => {
const [requestJSContact, setRequestJSContact] = useState(false); const [requestJSContact, setRequestJSContact] = useState(false);
@@ -17,32 +17,40 @@ const Old: NextPage = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [response, setResponse] = useState<ParsedGeneric | null>(null); const [response, setResponse] = useState<ParsedGeneric | null>(null);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [registryData, setRegistryData] = useState<Record<string, Register> | null>(null); const [registryData, setRegistryData] = useState<Record<
string,
Register
> | null>(null);
// Change the selected type automatically // Change the selected type automatically
const uriType = useMemo<TargetType>(function () { const uriType = useMemo<TargetType>(
return getType(object) ?? 'domain'; function () {
}, [object]); return getType(object) ?? "domain";
},
[object]
);
async function loadRegistryData() { async function loadRegistryData() {
setLoading(true); setLoading(true);
let registersLoaded = 0; let registersLoaded = 0;
const totalRegisters = Object.keys(registryURLs).length; const totalRegisters = Object.keys(registryURLs).length;
const responses = await Promise.all(Object.entries(registryURLs).map(async ([registryType, url]) => { const responses = await Promise.all(
Object.entries(registryURLs).map(async ([registryType, url]) => {
const response = await fetch(url); const response = await fetch(url);
registersLoaded++; registersLoaded++;
return { return {
registryType, registryType,
response: RegisterSchema.parse(await response.json()) response: RegisterSchema.parse(await response.json()),
}; };
})) })
);
setRegistryData(() => { setRegistryData(() => {
return Object.fromEntries( return Object.fromEntries(
responses.map(({registryType, response}) => [registryType, response]) responses.map(({ registryType, response }) => [registryType, response])
) as Record<string, Register> ) as Record<string, Register>;
}) });
setLoading(false); setLoading(false);
} }
@@ -51,22 +59,21 @@ const Old: NextPage = () => {
let urls: string[] = []; let urls: string[] = [];
if (registryData == null) { if (registryData == null) {
console.log('Registry data not loaded.') console.log("Registry data not loaded.");
return null; return null;
} }
const service = registryData[uriType]?.services; const service = registryData[uriType]?.services;
if (service == undefined) return null; if (service == undefined) return null;
services: services: for (const serviceItem of service) {
for (const serviceItem of service) {
// special case for object tags, since the registrant email address is in the 0th position // special case for object tags, since the registrant email address is in the 0th position
const [rangeIndex, urlIndex] = uriType == 'entity' ? [1, 2] : [0, 1]; const [rangeIndex, urlIndex] = uriType == "entity" ? [1, 2] : [0, 1];
for (const tld of serviceItem[rangeIndex]!) { for (const tld of serviceItem[rangeIndex]!) {
let match = false; let match = false;
switch (uriType) { switch (uriType) {
case 'domain': case "domain":
match = domainMatch(tld, object); match = domainMatch(tld, object);
break; break;
// case "autnum": // case "autnum":
@@ -87,23 +94,22 @@ const Old: NextPage = () => {
} }
} }
// no match // no match
if (urls.length == 0) return null; if (urls.length == 0) return null;
let url = getBestURL(urls); let url = getBestURL(urls);
// some bootstrap entries have a trailing slash, some don't // some bootstrap entries have a trailing slash, some don't
if (!url.endsWith('/')) url += '/'; if (!url.endsWith("/")) url += "/";
return `${url + uriType}/${object}`; return `${url + uriType}/${object}`;
} }
async function submit(e?: FormEvent) { async function submit(e?: FormEvent) {
e?.preventDefault(); e?.preventDefault();
console.log(`Submit invoked. ${uriType}/${JSON.stringify(object)}`) console.log(`Submit invoked. ${uriType}/${JSON.stringify(object)}`);
const queryParams = requestJSContact ? '?jscard=1' : ''; const queryParams = requestJSContact ? "?jscard=1" : "";
const [url, schema]: [string, ZodSchema<ParsedGeneric>] | [null, null] = (function () { const [url, schema]: [string, ZodSchema<ParsedGeneric>] | [null, null] =
(function () {
switch (uriType) { switch (uriType) {
// case 'url': // case 'url':
// return [object]; // return [object];
@@ -113,42 +119,43 @@ const Old: NextPage = () => {
// return `https://registrars.rdap.org/entity/${object}-IANA${queryParams}`; // return `https://registrars.rdap.org/entity/${object}-IANA${queryParams}`;
// case 'json': // case 'json':
// return `json://${object}` // return `json://${object}`
case 'domain': case "domain":
const temp = getRDAPURL(object); const temp = getRDAPURL(object);
if (temp) return [`${temp}${queryParams}`, DomainSchema] if (temp) return [`${temp}${queryParams}`, DomainSchema];
return [null, null]; return [null, null];
default: default:
setError(`No RDAP URL available for ${uriType} ${object}.`); setError(`No RDAP URL available for ${uriType} ${object}.`);
return [null, null]; return [null, null];
} }
})() })();
console.log(`URL: ${url ?? "null"}`) console.log(`URL: ${url ?? "null"}`);
if (url != null) if (url != null) await sendQuery(url, schema, followReferral);
await sendQuery(url, schema, followReferral);
} }
async function sendQuery(url: string, schema: ZodSchema<ParsedGeneric>, followReferral = false) { async function sendQuery(
url: string,
schema: ZodSchema<ParsedGeneric>,
followReferral = false
) {
setLoading(true); setLoading(true);
let data: ParsedGeneric | null = null; let data: ParsedGeneric | null = null;
if (url.startsWith('json://')) { if (url.startsWith("json://")) {
console.log('Mock JSON query detected.') console.log("Mock JSON query detected.");
// run the callback with a mock XHR // run the callback with a mock XHR
data = schema.parse(JSON.parse(url.substring(7))) data = schema.parse(JSON.parse(url.substring(7)));
} else { } else {
try { try {
const response = await fetch(url) const response = await fetch(url);
if (response.status == 404) if (response.status == 404) setError("This object does not exist.");
setError('This object does not exist.');
else if (response.status != 200) else if (response.status != 200)
setError(`Error ${response.status}: ${response.statusText}`) setError(`Error ${response.status}: ${response.statusText}`);
data = schema.parse(await response.json()); data = schema.parse(await response.json());
} catch (e) { } catch (e) {
console.log(e); console.log(e);
setLoading(false); setLoading(false);
if (e instanceof Error) if (e instanceof Error) setError(e.toString());
setError(e.toString())
return; return;
} }
} }
@@ -167,14 +174,15 @@ const Old: NextPage = () => {
console.log(data); console.log(data);
try { try {
setResponse(data); setResponse(data);
const url = `${window.location.origin}?type=${encodeURIComponent(uriType)}&object=${object}&request-jscontact=${requestJSContact ? 1 : 0}&follow-referral=${followReferral ? 1 : 0}` const url = `${window.location.origin}?type=${encodeURIComponent(
uriType
)}&object=${object}&request-jscontact=${
requestJSContact ? 1 : 0
}&follow-referral=${followReferral ? 1 : 0}`;
window.history.pushState(null, document.title, url); window.history.pushState(null, document.title, url);
} catch (e) { } catch (e) {
if (e instanceof Error) if (e instanceof Error) setError(`Exception: ${e.message}`);
setError(`Exception: ${e.message}`); else setError("Unknown error.");
else
setError('Unknown error.')
} }
} }
@@ -185,30 +193,35 @@ const Old: NextPage = () => {
// if (params.has('type')) // if (params.has('type'))
// setUriType(params.get('type') as ObjectType); // setUriType(params.get('type') as ObjectType);
if (params.has('object')) if (params.has("object")) setObject(params.get("object")!);
setObject(params.get('object')!);
if (params.has('request-jscontact') && truthy(params.get('request-jscontact'))) if (
params.has("request-jscontact") &&
truthy(params.get("request-jscontact"))
)
setRequestJSContact(true); setRequestJSContact(true);
if (params.has('follow-referral') && truthy(params.get('follow-referral'))) if (params.has("follow-referral") && truthy(params.get("follow-referral")))
setFollowReferral(true); setFollowReferral(true);
loadRegistryData().catch(console.error); loadRegistryData().catch(console.error);
if (params.has('object') && (params.get('object')?.length ?? 0) > 0) { if (params.has("object") && (params.get("object")?.length ?? 0) > 0) {
setObject(params.get('object')!); setObject(params.get("object")!);
// submit().catch(console.error); // submit().catch(console.error);
} }
}, []) }, []);
return ( return (
<> <>
<Head> <Head>
<title>rdap.xevion.dev</title> <title>rdap.xevion.dev</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="shortcut icon" href="/shortcut-icon.svg"/> <link rel="shortcut icon" href="/shortcut-icon.svg" />
<meta name="description" content=""/> <meta name="description" content="" />
<meta name="keywords" content="xevion, rdap, whois, rdap, domain name, dns, ip address"/> <meta
name="keywords"
content="xevion, rdap, whois, rdap, domain name, dns, ip address"
/>
</Head> </Head>
<> <>
<style jsx>{` <style jsx>{`
@@ -224,7 +237,8 @@ const Old: NextPage = () => {
margin: 0; margin: 0;
} }
.rdap-status-code, .rdap-event-time { .rdap-status-code,
.rdap-event-time {
border-bottom: 1px dashed silver; border-bottom: 1px dashed silver;
} }
@@ -238,26 +252,33 @@ const Old: NextPage = () => {
margin: -0.25em 0 0 0; margin: -0.25em 0 0 0;
padding: 0.25em 0 0 0; padding: 0.25em 0 0 0;
} }
`}</style> `}</style>
<nav className="navbar navbar-expand-lg navbar-dark shadow-sm"> <nav className="navbar navbar-expand-lg navbar-dark shadow-sm">
<span className="text-white" style={{fontSize: 'larger'}}> <span className="text-white" style={{ fontSize: "larger" }}>
<a className="navbar-brand" href="#">rdap.xevion.dev</a> <a className="navbar-brand" href="#">
rdap.xevion.dev
</a>
</span> </span>
</nav> </nav>
<div className="container py-12 mx-auto max-w-screen-lg"> <div className="container mx-auto max-w-screen-lg py-12">
<form onSubmit={(e) => { <form
void submit(e) onSubmit={(e) => {
}} className="form-inline"> void submit(e);
}}
className="form-inline"
>
<div className="col p-0"> <div className="col p-0">
<div className="input-group"> <div className="input-group">
<div className="input-group-prepend"> <div className="input-group-prepend">
<select onChange={() => { <select
onChange={() => {
return false; return false;
}} className="custom-select bg-zinc-800 border-zinc-700 text-zinc-200" id="type" }}
className="custom-select border-zinc-700 bg-zinc-800 text-zinc-200"
id="type"
name="type" name="type"
value={uriType}> value={uriType}
>
<option value="domain">Domain</option> <option value="domain">Domain</option>
<option value="tld">TLD</option> <option value="tld">TLD</option>
<option value="ip">IP/CIDR</option> <option value="ip">IP/CIDR</option>
@@ -270,87 +291,131 @@ const Old: NextPage = () => {
</div> </div>
<input <input
className="form-control bg-zinc-800 focus:bg-zinc-700 focus:border-zinc-600 border-zinc-700 text-zinc-200" className="form-control border-zinc-700 bg-zinc-800 text-zinc-200 focus:border-zinc-600 focus:bg-zinc-700"
type="text" type="text"
placeholder={placeholders[uriType]} placeholder={placeholders[uriType]}
disabled={loading} disabled={loading}
onChange={(e) => { onChange={(e) => {
setObject(e.target.value); setObject(e.target.value);
}} required/> }}
required
/>
<div className="input-group-append"> <div className="input-group-append">
<input id="button" type="button" value="Submit" onClick={(event) => { <input
void submit(event) id="button"
type="button"
value="Submit"
onClick={(event) => {
void submit(event);
}} }}
className="btn btn-primary" className="btn btn-primary"
disabled={loading}/> disabled={loading}
/>
</div> </div>
</div> </div>
</div> </div>
</form> </form>
<div className="container p-0 italic text-[#aaa]" style={{fontSize: "small"}}> <div
className="container p-0 italic text-[#aaa]"
style={{ fontSize: "small" }}
>
<div className="col pt-3 pb-1"> <div className="col pt-3 pb-1">
Options:&nbsp; Options:&nbsp;
<label htmlFor="request-jscontact"> <label htmlFor="request-jscontact">
<input name="request-jscontact" id="request-jscontact" type="checkbox"/> <input
name="request-jscontact"
id="request-jscontact"
type="checkbox"
/>
Request JSContact Request JSContact
</label> </label>
&nbsp; &nbsp;
<label htmlFor="follow-referral"> <label htmlFor="follow-referral">
<input name="follow-referral" id="follow-referral" type="checkbox"/> <input
name="follow-referral"
id="follow-referral"
type="checkbox"
/>
Follow referral to registrar&apos;s RDAP record Follow referral to registrar&apos;s RDAP record
</label> </label>
</div> </div>
</div> </div>
<div id="output-div"> <div id="output-div">
{response != null ? <Generic data={response}/> : null} {response != null ? <Generic data={response} /> : null}
</div> </div>
<p>This page implements a <em>completely private lookup tool</em> for domain names, IP addresses and <p>
Autonymous System Numbers (ASNs). Only the relevant registry sees your query: your browser will This page implements a <em>completely private lookup tool</em> for
directly domain names, IP addresses and Autonymous System Numbers (ASNs).
connect to the registry&apos;s RDAP server using an encrypted HTTPS connection to protect the Only the relevant registry sees your query: your browser will
confidentiality of directly connect to the registry&apos;s RDAP server using an
your query. If you click the &quot;Follow referral to registrar&apos;s RDAP encrypted HTTPS connection to protect the confidentiality of your
record&quot; checkbox, then the query. If you click the &quot;Follow referral to registrar&apos;s
sponsoring RDAP record&quot; checkbox, then the sponsoring registrar may also
registrar may also see your query.</p> see your query.
</p>
<ul> <ul>
<li><a href="https://about.rdap.org" target="_new">Click here</a> for more information about <li>
what RDAP is <a href="https://about.rdap.org" target="_new">
and how it differs from traditional Whois. Click here
</a>{" "}
for more information about what RDAP is and how it differs from
traditional Whois.
</li> </li>
<li>Most generic TLDs now support RDAP, but only a few ccTLDs have deployed RDAP so far. To see <li>
which TLDs Most generic TLDs now support RDAP, but only a few ccTLDs have
support RDAP, <a href="https://deployment.rdap.org" target="_new">click here</a>. deployed RDAP so far. To see which TLDs support RDAP,{" "}
<a href="https://deployment.rdap.org" target="_new">
click here
</a>
.
</li> </li>
<li>There is no bootstrap registry for top-level domains or ICANN-accredited registrars; instead <li>
these queries are sent to the There is no bootstrap registry for top-level domains or
<a href="https://about.rdap.org/#additional" ICANN-accredited registrars; instead these queries are sent to the
target="_new"> <a href="https://about.rdap.org/#additional" target="_new">
{"{"}root,registrars{"}"}.rdap.org servers {"{"}root,registrars{"}"}.rdap.org servers
</a>. </a>
.
</li> </li>
<li>To submit feedback, <a href="mailto:feedback@rdap.org">click here</a>. Please contact the <li>
relevant To submit feedback,{" "}
registry or registrar if you have an issue with the content of an RDAP response. <a href="mailto:feedback@rdap.org">click here</a>. Please contact
the relevant registry or registrar if you have an issue with the
content of an RDAP response.
</li> </li>
<li>This tool is Free Software; for the license, <a href="LICENSE">click here</a>. To fork a <li>
copy of the git This tool is Free Software; for the license,{" "}
repository, <a rel="noopener" target="_new" <a href="LICENSE">click here</a>. To fork a copy of the git
href="https://gitlab.centralnic.com/centralnic/rdap-web-client">click repository,{" "}
here</a>. <a
</li>
<li>This page uses <a rel="noopener" target="_new"
href="https://github.com/whitequark/ipaddr.js/">ipaddr.js</a> by <a
rel="noopener" rel="noopener"
target="_new" target="_new"
href="https://whitequark.org/">whitequark</a>. href="https://gitlab.centralnic.com/centralnic/rdap-web-client"
>
click here
</a>
.
</li>
<li>
This page uses{" "}
<a
rel="noopener"
target="_new"
href="https://github.com/whitequark/ipaddr.js/"
>
ipaddr.js
</a>{" "}
by{" "}
<a rel="noopener" target="_new" href="https://whitequark.org/">
whitequark
</a>
.
</li> </li>
</ul> </ul>
</div> </div>
</> </>
</> </>