Skip to content

Commit

Permalink
Use Vercel headers to get location
Browse files Browse the repository at this point in the history
  • Loading branch information
CRBl69 authored and xbtmatt committed Nov 28, 2024
1 parent a470875 commit d5b22f9
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 46 deletions.
4 changes: 0 additions & 4 deletions src/typescript/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ ALLOWLISTER3K_URL="http://localhost:3000"
# A list of ISO 3166-2 codes of countries and regions to geoblock.
GEOBLOCKED='{"countries":[],"regions":[]}'

# The vpnapi.io API key.
# If GEOBLOCKED is set and non-empty, this needs to be set as well.
VPNAPI_IO_API_KEY=""

# The private key of the contract publisher.
# No "0x" at the start.
# Useful in testing only.
Expand Down
5 changes: 4 additions & 1 deletion src/typescript/frontend/src/app/verify_status/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import VerifyStatusPage from "components/pages/verify_status/VerifyStatusPage";
import { headers } from "next/headers";

const Verify = async () => {
return <VerifyStatusPage />;
const country = headers().get('x-vercel-ip-country');
const region = headers().get('x-vercel-ip-country-region');
return <VerifyStatusPage country={country} region={region} />;
};

export default Verify;
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const checkmarkOrX = (checkmark: boolean) => (
/>
);

export const ClientVerifyPage = () => {
export const ClientVerifyPage = ({ country, region }: { country: string | null, region: string | null }) => {
const { account } = useAptos();
const { connected, disconnect } = useWallet();
const [galxe, setGalxe] = useState(false);
Expand Down Expand Up @@ -74,6 +74,8 @@ export const ClientVerifyPage = () => {
<div>Galxe: {checkmarkOrX(galxe)}</div>
<div>Custom allowlist: {checkmarkOrX(customAllowlisted)}</div>
<div>Passes geoblocking: {checkmarkOrX(!geoblocked)}</div>
<div>Country: {country ?? "unknown"}</div>
<div>Region: {region ?? "unknown"}</div>
<a
className="underline text-ec-blue"
href={process.env.NEXT_PUBLIC_GALXE_CAMPAIGN_REDIRECT}
Expand Down
9 changes: 0 additions & 9 deletions src/typescript/frontend/src/lib/server-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,8 @@ export const GEOBLOCKED: { countries: string[]; regions: string[] } = JSON.parse
);
export const GEOBLOCKING_ENABLED = GEOBLOCKED.countries.length > 0 || GEOBLOCKED.regions.length > 0;

if (GEOBLOCKING_ENABLED) {
if (process.env.VPNAPI_IO_API_KEY === "undefined") {
throw new Error(
"Geoblocking is enabled but environment variable VPNAPI_IO_API_KEY is undefined."
);
}
}

export const ALLOWLISTER3K_URL: string | undefined = process.env.ALLOWLISTER3K_URL;
export const REVALIDATION_TIME: number = Number(process.env.REVALIDATION_TIME);
export const VPNAPI_IO_API_KEY: string = process.env.VPNAPI_IO_API_KEY!;
export const PRE_LAUNCH_TEASER: boolean = process.env.PRE_LAUNCH_TEASER === "true";

if (
Expand Down
42 changes: 11 additions & 31 deletions src/typescript/frontend/src/utils/geolocation.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
"use server";

import { GEOBLOCKED, GEOBLOCKING_ENABLED, VPNAPI_IO_API_KEY } from "lib/server-env";
import { GEOBLOCKED, GEOBLOCKING_ENABLED } from "lib/server-env";
import { headers } from "next/headers";

export type Location = {
country: string;
region: string;
countryCode: string;
regionCode: string;
vpn: boolean;
};

const isDisallowedLocation = (location: Location) => {
Expand All @@ -23,40 +20,23 @@ const isDisallowedLocation = (location: Location) => {
};

export const isUserGeoblocked = async () => {
const ip = headers().get("x-real-ip");
if (!GEOBLOCKING_ENABLED) return false;
if (ip === "undefined" || typeof ip === "undefined" || ip === "null" || ip === null) {
const country = headers().get('x-vercel-ip-country');
const region = headers().get('x-vercel-ip-country-region');
if (country === "undefined" || typeof country === "undefined" || country === "null" || country === null) {
return true;
}
if (region === "undefined" || typeof region === "undefined" || region === "null" || region === null) {
return true;
}
let location: Location;
try {
location = await getLocation(ip);
location = {
countryCode: country,
regionCode: region,
};
} catch (_) {
return true;
}
if (location.vpn) {
return true;
}
return isDisallowedLocation(location);
};

const ONE_DAY = 604800;

const getLocation: (ip: string) => Promise<Location> = async (ip) => {
if (ip === "undefined" || typeof ip === "undefined") {
throw new Error("IP is undefined");
}
const queryResult = await fetch(`https://vpnapi.io/api/${ip}?key=${VPNAPI_IO_API_KEY}`, {
next: { revalidate: ONE_DAY },
}).then((res) => res.json());

const data = {
country: queryResult.location.country,
region: queryResult.location.region,
countryCode: queryResult.location.country_code,
regionCode: queryResult.location.region_code,
vpn: queryResult.security.vpn,
};

return data;
};

0 comments on commit d5b22f9

Please sign in to comment.