/** * Country-code suggestion for a country-routed Popcorn browser session, when * the caller doesn't name one explicitly. `attach_browser` returns this as the * suggestion to confirm with the developer — the calling machine's own * public-IP country, resolved the same way reclaim-portal's `ip-geolocation` * util does. */ import { LOGGER } from '../logger.ts' export interface IpGeolocation { countryCode: string country?: string region?: string city?: string } const IPINFO_URL = 'https://ipinfo.io/json' const FALLBACK_COUNTRY_CODE = 'US' /** Resolve the calling machine's own public-IP country. Never throws — a * lookup failure just loses the "best guess" convenience, falling back to * {@link FALLBACK_COUNTRY_CODE} rather than blocking applying a proxy. */ export async function suggestCountryFromIp( fetchImpl: typeof fetch = fetch, ): Promise { try { const res = await fetchImpl(IPINFO_URL) if(!res.ok) { throw new Error(`ipinfo.io ${res.status}`) } const data = await res.json() as { country?: string region?: string city?: string } const countryCode = data.country?.toUpperCase() if(!countryCode) { throw new Error('ipinfo.io response had no country') } return { countryCode, country: data.country, region: data.region, city: data.city, } } catch(err) { LOGGER.warn({ err }, 'suggestCountryFromIp failed; using fallback') return { countryCode: FALLBACK_COUNTRY_CODE } } }