import {type NextPage} from "next"; import Head from "next/head"; import type {Register, TargetType} from "@/types"; import {placeholders, registryURLs} from "@/constants"; import {domainMatch, getBestURL, getType} from "@/rdap"; import type {FormEvent} from "react"; import {useEffect, useMemo, useState} from "react"; import {truthy} from "@/helpers"; import Generic, {type ParsedGeneric} from "@/components/lookup/Generic"; import type {ZodSchema} from "zod"; import {DomainSchema, RegisterSchema} from "@/schema"; const Old: NextPage = () => { const [requestJSContact, setRequestJSContact] = useState(false); const [followReferral, setFollowReferral] = useState(false); const [object, setObject] = useState(""); const [loading, setLoading] = useState(false); const [response, setResponse] = useState(null); const [error, setError] = useState(null); const [registryData, setRegistryData] = useState | null>(null); // Change the selected type automatically const uriType = useMemo(function () { return getType(object) ?? 'domain'; }, [object]); async function loadRegistryData() { setLoading(true); let registersLoaded = 0; const totalRegisters = Object.keys(registryURLs).length; const responses = await Promise.all(Object.entries(registryURLs).map(async ([registryType, url]) => { const response = await fetch(url); registersLoaded++; return { registryType, response: RegisterSchema.parse(await response.json()) }; })) setRegistryData(() => { return Object.fromEntries( responses.map(({registryType, response}) => [registryType, response]) ) as Record }) setLoading(false); } // construct an RDAP URL for the given object function getRDAPURL(object: string): string | null { let urls: string[] = []; if (registryData == null) { console.log('Registry data not loaded.') return null; } const service = registryData[uriType]?.services; if (service == undefined) return null; services: for (const serviceItem of service) { // special case for object tags, since the registrant email address is in the 0th position const [rangeIndex, urlIndex] = uriType == 'entity' ? [1, 2] : [0, 1]; for (const tld of serviceItem[rangeIndex]!) { let match = false; switch (uriType) { case 'domain': match = domainMatch(tld, object); break; // case "autnum": // match = asnMatch(range, object); // break; // case "entity": // match = entityMatch(range, object); // break; // case "ip": // match = ipMatch(range, object); // break; } if (match) { urls = serviceItem[urlIndex]!; break services; } } } // no match if (urls.length == 0) return null; let url = getBestURL(urls); // some bootstrap entries have a trailing slash, some don't if (!url.endsWith('/')) url += '/'; return `${url + uriType}/${object}`; } async function submit(e?: FormEvent) { e?.preventDefault(); console.log(`Submit invoked. ${uriType}/${JSON.stringify(object)}`) const queryParams = requestJSContact ? '?jscard=1' : ''; const [url, schema]: [string, ZodSchema] | [null, null] = (function () { switch (uriType) { // case 'url': // return [object]; // case 'tld': // return `https://root.rdap.org/domain/${object}${queryParams}`; // case 'registrar': // return `https://registrars.rdap.org/entity/${object}-IANA${queryParams}`; // case 'json': // return `json://${object}` case 'domain': const temp = getRDAPURL(object); if (temp) return [`${temp}${queryParams}`, DomainSchema] return [null, null]; default: setError(`No RDAP URL available for ${uriType} ${object}.`); return [null, null]; } })() console.log(`URL: ${url ?? "null"}`) if (url != null) await sendQuery(url, schema, followReferral); } async function sendQuery(url: string, schema: ZodSchema, followReferral = false) { setLoading(true); let data: ParsedGeneric | null = null; if (url.startsWith('json://')) { console.log('Mock JSON query detected.') // run the callback with a mock XHR data = schema.parse(JSON.parse(url.substring(7))) } else { try { const response = await fetch(url) if (response.status == 404) setError('This object does not exist.'); else if (response.status != 200) setError(`Error ${response.status}: ${response.statusText}`) data = schema.parse(await response.json()); } catch (e) { console.log(e); setLoading(false); if (e instanceof Error) setError(e.toString()) return; } } // if (followReferral && data.hasOwnProperty('links') != undefined) { // console.log('Using followReferral.') // for (const link of data.links) { // if ('related' == link.rel && 'application/rdap+json' == link.type && link.href.match(/^(https?:|)\/\//i)) { // await sendQuery(link.href, false) // return; // } // } // } setLoading(false); console.log(data); try { setResponse(data); 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); } catch (e) { if (e instanceof Error) setError(`Exception: ${e.message}`); else setError('Unknown error.') } } useEffect(() => { // Load parameters from URL query string on page load const params = new URLSearchParams(window.location.search); // if (params.has('type')) // setUriType(params.get('type') as ObjectType); if (params.has('object')) setObject(params.get('object')!); if (params.has('request-jscontact') && truthy(params.get('request-jscontact'))) setRequestJSContact(true); if (params.has('follow-referral') && truthy(params.get('follow-referral'))) setFollowReferral(true); loadRegistryData().catch(console.error); if (params.has('object') && (params.get('object')?.length ?? 0) > 0) { setObject(params.get('object')!); // submit().catch(console.error); } }, []) return ( <> rdap.xevion.dev <>
{ void submit(e) }} className="form-inline">
{ setObject(e.target.value); }} required/>
{ void submit(event) }} className="btn btn-primary" disabled={loading}/>
Options:   
{response != null ? : null}

This page implements a completely private lookup tool for domain names, IP addresses and Autonymous System Numbers (ASNs). Only the relevant registry sees your query: your browser will directly connect to the registry's RDAP server using an encrypted HTTPS connection to protect the confidentiality of your query. If you click the "Follow referral to registrar's RDAP record" checkbox, then the sponsoring registrar may also see your query.

  • Click here for more information about what RDAP is and how it differs from traditional Whois.
  • Most generic TLDs now support RDAP, but only a few ccTLDs have deployed RDAP so far. To see which TLDs support RDAP, click here.
  • There is no bootstrap registry for top-level domains or ICANN-accredited registrars; instead these queries are sent to the {"{"}root,registrars{"}"}.rdap.org servers .
  • To submit feedback, click here. Please contact the relevant registry or registrar if you have an issue with the content of an RDAP response.
  • This tool is Free Software; for the license, click here. To fork a copy of the git repository, click here.
  • This page uses ipaddr.js by whitequark.
); }; export default Old;