From 4761c9f15d0c62b1256abf3d02630e9a566011f3 Mon Sep 17 00:00:00 2001 From: Felix Wotschofsky Date: Sun, 5 Nov 2023 16:46:13 +0100 Subject: [PATCH] =?UTF-8?q?Add=20Whois=20quick=20info=20=F0=9F=91=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/error.tsx | 25 +++++++++++ app/lookup/[domain]/certs/page.tsx | 4 -- app/lookup/[domain]/layout.tsx | 9 +++- components/WhoisQuickInfo.tsx | 68 ++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 app/error.tsx create mode 100644 components/WhoisQuickInfo.tsx diff --git a/app/error.tsx b/app/error.tsx new file mode 100644 index 0000000..f9fd18b --- /dev/null +++ b/app/error.tsx @@ -0,0 +1,25 @@ +'use client'; + +import { type FC, useEffect } from 'react'; + +type GlobalErrorProps = { + error: Error & { digest?: string }; + reset: () => void; +}; + +const GlobalError: FC = ({ error }) => { + useEffect(() => { + console.error(error); + }, [error]); + + return ( +
+

Something went VERY wrong!

+

+ Digest: {error.digest} +

+
+ ); +}; + +export default GlobalError; diff --git a/app/lookup/[domain]/certs/page.tsx b/app/lookup/[domain]/certs/page.tsx index 10d2421..7082f8c 100644 --- a/app/lookup/[domain]/certs/page.tsx +++ b/app/lookup/[domain]/certs/page.tsx @@ -45,10 +45,6 @@ type CertsResultsPageProps = { }; }; -export const runtime = 'edge'; -// crt.sh located in GB, always use LHR1 for lowest latency -export const preferredRegion = 'lhr1'; - const CertsResultsPage: FC = async ({ params: { domain }, }) => { diff --git a/app/lookup/[domain]/layout.tsx b/app/lookup/[domain]/layout.tsx index 3541790..41f344f 100644 --- a/app/lookup/[domain]/layout.tsx +++ b/app/lookup/[domain]/layout.tsx @@ -1,10 +1,13 @@ import { ExternalLinkIcon } from 'lucide-react'; import type { Metadata } from 'next'; -import type { FC, ReactNode } from 'react'; +import { type FC, type ReactNode, Suspense } from 'react'; import RelatedDomains from '@/components/RelatedDomains'; import ResultsTabs from '@/components/ResultsTabs'; import SearchForm from '@/components/SearchForm'; +import WhoisQuickInfo, { + WhoisQuickInfoPlaceholder, +} from '@/components/WhoisQuickInfo'; type LookupLayoutProps = { children: ReactNode; @@ -54,6 +57,10 @@ const LookupLayout: FC = ({ + }> + {/* TODO Add error boundary */} + + {children} diff --git a/components/WhoisQuickInfo.tsx b/components/WhoisQuickInfo.tsx new file mode 100644 index 0000000..a6a2f91 --- /dev/null +++ b/components/WhoisQuickInfo.tsx @@ -0,0 +1,68 @@ +import { FC } from 'react'; +import whoiser, { type WhoisSearchResult } from 'whoiser'; + +import { Skeleton } from './ui/skeleton'; + +type WhoisQuickInfoProps = { + domain: string; +}; + +const WhoisQuickInfo: FC = async ({ domain }) => { + const results = await whoiser(domain, { + timeout: 5000, + }); + const firstResult = results[ + // @ts-expect-error + Object.keys(results).filter((key) => !('error' in results[key]))[0] + ] as WhoisSearchResult; + + return ( +
+
+

Registrar

+

+ {firstResult && 'Registrar' in firstResult + ? firstResult['Registrar'].toString() + : 'Unavailable'} +

+
+
+

Creation Date

+

+ {firstResult && 'Created Date' in firstResult + ? new Date( + firstResult['Created Date'].toString() + ).toLocaleDateString('en-US') + : 'Unavailable'} +

+
+
+

DNSSEC

+

+ {firstResult && 'DNSSEC' in firstResult + ? firstResult['DNSSEC'].toString() + : 'Unavailable'} +

+
+
+ ); +}; + +export default WhoisQuickInfo; + +export const WhoisQuickInfoPlaceholder: FC = () => ( +
+
+

Registrar

+ +
+
+

Creation Date

+ +
+
+

DNSSEC

+ +
+
+);