feat: get ip info

This commit is contained in:
hamster1963 2024-12-12 00:31:06 +08:00
parent f28f559a0b
commit b573b62452
7 changed files with 86 additions and 1 deletions

View File

@ -5,12 +5,23 @@ import ServerDetailChartClient from "@/app/(main)/ClientComponents/ServerDetailC
import ServerDetailClient from "@/app/(main)/ClientComponents/ServerDetailClient"; import ServerDetailClient from "@/app/(main)/ClientComponents/ServerDetailClient";
import TabSwitch from "@/components/TabSwitch"; import TabSwitch from "@/components/TabSwitch";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import { use, useState } from "react"; import GetIPInfo from "@/lib/GetIPInfo";
import { use, useEffect, useState } from "react";
export default function Page(props: { params: Promise<{ id: string }> }) { export default function Page(props: { params: Promise<{ id: string }> }) {
const params = use(props.params); const params = use(props.params);
const tabs = ["Detail", "Network"]; const tabs = ["Detail", "Network"];
const [currentTab, setCurrentTab] = useState(tabs[0]); const [currentTab, setCurrentTab] = useState(tabs[0]);
useEffect(() => {
const updateViews = async () => {
const ipInfo = await GetIPInfo({ server_id: params.id });
console.log(ipInfo);
}
updateViews()
}, [])
return ( return (
<div className="mx-auto grid w-full max-w-5xl gap-2"> <div className="mx-auto grid w-full max-w-5xl gap-2">
<ServerDetailClient server_id={Number(params.id)} /> <ServerDetailClient server_id={Number(params.id)} />

BIN
bun.lockb

Binary file not shown.

BIN
lib/GeoLite2-ASN.mmdb Normal file

Binary file not shown.

BIN
lib/GeoLite2-City.mmdb Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 MiB

22
lib/GetIPInfo.ts Normal file
View File

@ -0,0 +1,22 @@
"use server";
import maxmind, { CityResponse, AsnResponse } from 'maxmind';
import { GetServerIP } from './serverFetch';
type IPInfo = {
city: CityResponse;
asn: AsnResponse;
}
export default async function GetIPInfo({ server_id }: { server_id: string }): Promise<IPInfo> {
const ip = await GetServerIP({ server_id: Number(server_id) })
const cityLookup = await maxmind.open<CityResponse>('./lib/GeoLite2-City.mmdb')
const asnLookup = await maxmind.open<AsnResponse>('./lib/GeoLite2-ASN.mmdb')
return {
city: cityLookup.get(ip) as CityResponse,
asn: asnLookup.get(ip) as AsnResponse
}
}

View File

@ -130,6 +130,57 @@ export async function GetServerMonitor({ server_id }: { server_id: number }) {
} }
} }
export async function GetServerIP({ server_id }: { server_id: number }): Promise<string> {
let nezhaBaseUrl = getEnv("NezhaBaseUrl");
if (!nezhaBaseUrl) {
console.error("NezhaBaseUrl is not set");
throw new Error("NezhaBaseUrl is not set");
}
// Remove trailing slash
nezhaBaseUrl = nezhaBaseUrl.replace(/\/$/, "");
try {
const response = await fetch(`${nezhaBaseUrl}/api/v1/server/details`, {
headers: {
Authorization: getEnv("NezhaAuth") as string,
},
next: {
revalidate: 0,
},
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Failed to fetch data: ${response.status} ${errorText}`);
}
const resData = await response.json();
if (!resData.result) {
throw new Error("NezhaData fetch failed: 'result' field is missing");
}
const nezhaData = resData.result as NezhaAPI[];
// Find the server with the given ID
const server = nezhaData.find((element) => element.id === server_id);
if (!server) {
throw new Error(`Server with ID ${server_id} not found`);
}
return server?.valid_ip || server?.ipv4 || server?.ipv6 || "";
} catch (error) {
console.error("GetNezhaData error:", error);
throw error; // Rethrow the error to be caught by the caller
}
}
export async function GetServerDetail({ server_id }: { server_id: number }) { export async function GetServerDetail({ server_id }: { server_id: number }) {
let nezhaBaseUrl = getEnv("NezhaBaseUrl"); let nezhaBaseUrl = getEnv("NezhaBaseUrl");
if (!nezhaBaseUrl) { if (!nezhaBaseUrl) {

View File

@ -39,6 +39,7 @@
"framer-motion": "^12.0.0-alpha.2", "framer-motion": "^12.0.0-alpha.2",
"lucide-react": "^0.454.0", "lucide-react": "^0.454.0",
"luxon": "^3.5.0", "luxon": "^3.5.0",
"maxmind": "^4.3.23",
"next": "^15.1.0", "next": "^15.1.0",
"next-auth": "^5.0.0-beta.25", "next-auth": "^5.0.0-beta.25",
"next-intl": "^3.26.0", "next-intl": "^3.26.0",