From 13ddf307811d115e3b62da75e78dd7e667a5e0a0 Mon Sep 17 00:00:00 2001 From: Owen Date: Sat, 20 Dec 2025 12:01:50 -0500 Subject: [PATCH] Add hybrid route --- server/private/routers/hybrid.ts | 65 ++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/server/private/routers/hybrid.ts b/server/private/routers/hybrid.ts index 3accc500..751a1a0c 100644 --- a/server/private/routers/hybrid.ts +++ b/server/private/routers/hybrid.ts @@ -76,6 +76,7 @@ import { checkExitNodeOrg, resolveExitNodes } from "#private/lib/exitNodes"; import { maxmindLookup } from "@server/db/maxmind"; import { verifyResourceAccessToken } from "@server/auth/verifyResourceAccessToken"; import semver from "semver"; +import { maxmindAsnLookup } from "@server/db/maxmindAsn"; // Zod schemas for request validation const getResourceByDomainParamsSchema = z.strictObject({ @@ -1238,6 +1239,70 @@ hybridRouter.get( } ); +const asnIpLookupParamsSchema = z.object({ + ip: z.union([z.ipv4(), z.ipv6()]) +}); +hybridRouter.get( + "/asnip/:ip", + async (req: Request, res: Response, next: NextFunction) => { + try { + const parsedParams = asnIpLookupParamsSchema.safeParse(req.params); + if (!parsedParams.success) { + return next( + createHttpError( + HttpCode.BAD_REQUEST, + fromError(parsedParams.error).toString() + ) + ); + } + + const { ip } = parsedParams.data; + + if (!maxmindAsnLookup) { + return next( + createHttpError( + HttpCode.SERVICE_UNAVAILABLE, + "ASNIP service is not available" + ) + ); + } + + const result = maxmindAsnLookup.get(ip); + + if (!result || !result.autonomous_system_number) { + return next( + createHttpError( + HttpCode.NOT_FOUND, + "ASNIP information not found" + ) + ); + } + + const { autonomous_system_number } = result; + + logger.debug( + `ASNIP lookup successful for IP ${ip}: ${autonomous_system_number}` + ); + + return response(res, { + data: { asn: autonomous_system_number }, + success: true, + error: false, + message: "GeoIP lookup successful", + status: HttpCode.OK + }); + } catch (error) { + logger.error(error); + return next( + createHttpError( + HttpCode.INTERNAL_SERVER_ERROR, + "Failed to validate resource session token" + ) + ); + } + } +); + // GERBIL ROUTERS const getConfigSchema = z.object({ publicKey: z.string(),