mirror of
https://github.com/Xevion/rdap.git
synced 2025-12-08 16:08:10 -06:00
Add bootstrap file load check, use registry URL lookup properly, getAndParse
- Clear error before returning submit - ParsedGeneric types
This commit is contained in:
@@ -6,6 +6,7 @@ import axios from "axios";
|
|||||||
import {AutonomousNumberSchema, DomainSchema, IpNetworkSchema, RegisterSchema, RootRegistryEnum} from "@/schema";
|
import {AutonomousNumberSchema, DomainSchema, IpNetworkSchema, RegisterSchema, RootRegistryEnum} from "@/schema";
|
||||||
import {truncated} from "@/helpers";
|
import {truncated} from "@/helpers";
|
||||||
import {ZodSchema} from "zod";
|
import {ZodSchema} from "zod";
|
||||||
|
import {ParsedGeneric} from "@/components/Generic";
|
||||||
|
|
||||||
export type WarningHandler = (warning: { message: string }) => void;
|
export type WarningHandler = (warning: { message: string }) => void;
|
||||||
type BootstrapMatcher = (value: string) => boolean;
|
type BootstrapMatcher = (value: string) => boolean;
|
||||||
@@ -20,7 +21,11 @@ const useLookup = (warningHandler?: WarningHandler) => {
|
|||||||
}, [target]);
|
}, [target]);
|
||||||
|
|
||||||
// Fetch & load a specific registry's data into memory.
|
// Fetch & load a specific registry's data into memory.
|
||||||
async function loadBootstrap(type: RootRegistryType) {
|
async function loadBootstrap(type: RootRegistryType, force = false) {
|
||||||
|
// Early preload exit condition
|
||||||
|
if (registryData[type] != null && !force)
|
||||||
|
return;
|
||||||
|
|
||||||
// Fetch the bootstrapping file from the registry
|
// Fetch the bootstrapping file from the registry
|
||||||
const response = await axios.get(registryURLs[type]);
|
const response = await axios.get(registryURLs[type]);
|
||||||
if (response.status != 200)
|
if (response.status != 200)
|
||||||
@@ -38,32 +43,37 @@ const useLookup = (warningHandler?: WarningHandler) => {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURL(type: RootRegistryType, lookupTarget: string): string {
|
function getRegistryURL(type: RootRegistryType, lookupTarget: string): string {
|
||||||
const bootstrap = registryData[type];
|
const bootstrap = registryData[type];
|
||||||
if (bootstrap == null) throw new Error(`Cannot acquire RDAP URL without bootstrap data for ${type} lookup.`)
|
if (bootstrap == null) throw new Error(`Cannot acquire RDAP URL without bootstrap data for ${type} lookup.`)
|
||||||
|
|
||||||
|
let url: string | null = null;
|
||||||
|
|
||||||
|
typeSwitch:
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "domain":
|
case "domain":
|
||||||
for (const bootstrapItem of bootstrap.services) {
|
for (const bootstrapItem of bootstrap.services) {
|
||||||
if (bootstrapItem[0].some(domainMatchPredicate))
|
if (bootstrapItem[0].some(domainMatchPredicate(lookupTarget))) {
|
||||||
return getBestURL(bootstrapItem[1]);
|
url = getBestURL(bootstrapItem[1]);
|
||||||
|
break typeSwitch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
throw new Error(`No matching domain found.`)
|
throw new Error(`No matching domain found.`)
|
||||||
case "ip4":
|
case "ip4":
|
||||||
throw new Error(`No matching ip4 found.`)
|
throw new Error(`No matching ip4 found.`)
|
||||||
break;
|
|
||||||
case "ip6":
|
case "ip6":
|
||||||
throw new Error(`No matching ip6 found.`)
|
throw new Error(`No matching ip6 found.`)
|
||||||
break;
|
|
||||||
case "entity":
|
case "entity":
|
||||||
throw new Error(`No matching entity found.`)
|
throw new Error(`No matching entity found.`)
|
||||||
break;
|
|
||||||
case "autnum":
|
case "autnum":
|
||||||
throw new Error(`No matching autnum found.`)
|
throw new Error(`No matching autnum found.`)
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
throw new Error("")
|
throw new Error("Invalid lookup target provided.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (url == null) throw new Error('No lookup target was resolved.')
|
||||||
|
|
||||||
|
return `${url}${type}/${lookupTarget}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -95,7 +105,7 @@ const useLookup = (warningHandler?: WarningHandler) => {
|
|||||||
return schema.parse(response.data) as T
|
return schema.parse(response.data) as T
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submitInternal() {
|
async function submitInternal(): Promise<ParsedGeneric | undefined> {
|
||||||
if (target == null)
|
if (target == null)
|
||||||
throw new Error("A target must be given in order to execute a lookup.")
|
throw new Error("A target must be given in order to execute a lookup.")
|
||||||
|
|
||||||
@@ -105,23 +115,23 @@ const useLookup = (warningHandler?: WarningHandler) => {
|
|||||||
// Block scoped case to allow url const reuse
|
// Block scoped case to allow url const reuse
|
||||||
case "ip4": {
|
case "ip4": {
|
||||||
await loadBootstrap("ip4");
|
await loadBootstrap("ip4");
|
||||||
const url = getURL(targetType, target);
|
const url = getRegistryURL(targetType, target);
|
||||||
return getAndParse<IpNetwork>(url, IpNetworkSchema)
|
return await getAndParse<IpNetwork>(url, IpNetworkSchema)
|
||||||
}
|
}
|
||||||
case "ip6": {
|
case "ip6": {
|
||||||
await loadBootstrap("ip6");
|
await loadBootstrap("ip6");
|
||||||
const url = getURL(targetType, target);
|
const url = getRegistryURL(targetType, target);
|
||||||
return getAndParse<IpNetwork>(url, IpNetworkSchema);
|
return await getAndParse<IpNetwork>(url, IpNetworkSchema);
|
||||||
}
|
}
|
||||||
case "domain": {
|
case "domain": {
|
||||||
await loadBootstrap("domain");
|
await loadBootstrap("domain");
|
||||||
const url = getURL(targetType, target);
|
const url = getRegistryURL(targetType, target);
|
||||||
return getAndParse<Domain>(url, DomainSchema);
|
return await getAndParse<Domain>(url, DomainSchema);
|
||||||
}
|
}
|
||||||
case "autnum": {
|
case "autnum": {
|
||||||
await loadBootstrap("autnum");
|
await loadBootstrap("autnum");
|
||||||
const url = getURL(targetType, target);
|
const url = getRegistryURL(targetType, target);
|
||||||
return getAndParse<AutonomousNumber>(url, AutonomousNumberSchema);
|
return await getAndParse<AutonomousNumber>(url, AutonomousNumberSchema);
|
||||||
}
|
}
|
||||||
case null:
|
case null:
|
||||||
throw new Error("The type could not be detected given the target.")
|
throw new Error("The type could not be detected given the target.")
|
||||||
@@ -134,13 +144,18 @@ const useLookup = (warningHandler?: WarningHandler) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function submit() {
|
async function submit(): Promise<ParsedGeneric | undefined> {
|
||||||
try {
|
try {
|
||||||
const data = await submitInternal();
|
const response = await submitInternal();
|
||||||
|
if (response == undefined)
|
||||||
|
throw new Error("Internal submission failed to yield any data.")
|
||||||
|
|
||||||
|
setError(null);
|
||||||
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (!(e instanceof Error))
|
if (!(e instanceof Error))
|
||||||
return setError("An unknown, unprocessable error has occurred.");
|
setError("An unknown, unprocessable error has occurred.");
|
||||||
return setError(e.message);
|
setError((e as Error).message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user