about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/logger/metrics.ts2
-rw-r--r--src/state/geolocation.tsx54
2 files changed, 50 insertions, 6 deletions
diff --git a/src/logger/metrics.ts b/src/logger/metrics.ts
index 4a09d8593..e51905f84 100644
--- a/src/logger/metrics.ts
+++ b/src/logger/metrics.ts
@@ -480,4 +480,6 @@ export type MetricEvents = {
    * Specifically for the `BlockedGeoOverlay`
    */
   'blockedGeoOverlay:shown': {}
+
+  'geo:debug': {}
 }
diff --git a/src/state/geolocation.tsx b/src/state/geolocation.tsx
index a69161324..6229c6f2c 100644
--- a/src/state/geolocation.tsx
+++ b/src/state/geolocation.tsx
@@ -5,6 +5,9 @@ import {networkRetry} from '#/lib/async/retry'
 import {logger} from '#/logger'
 import {type Device, device} from '#/storage'
 
+const IPCC_URL = `https://bsky.app/ipcc`
+const BAPP_CONFIG_URL = `https://bapp-config.bsky.workers.dev/config`
+
 const events = new EventEmitter()
 const EVENT = 'geolocation-updated'
 const emitGeolocationUpdate = (geolocation: Device['geolocation']) => {
@@ -29,8 +32,18 @@ export const DEFAULT_GEOLOCATION: Device['geolocation'] = {
   isAgeRestrictedGeo: false,
 }
 
-async function getGeolocation(): Promise<Device['geolocation']> {
-  const res = await fetch(`https://bsky.app/ipcc`)
+function sanitizeGeolocation(
+  geolocation: Device['geolocation'],
+): Device['geolocation'] {
+  return {
+    countryCode: geolocation?.countryCode ?? undefined,
+    isAgeBlockedGeo: geolocation?.isAgeBlockedGeo ?? false,
+    isAgeRestrictedGeo: geolocation?.isAgeRestrictedGeo ?? false,
+  }
+}
+
+async function getGeolocation(url: string): Promise<Device['geolocation']> {
+  const res = await fetch(url)
 
   if (!res.ok) {
     throw new Error(`geolocation: lookup failed ${res.status}`)
@@ -43,12 +56,39 @@ async function getGeolocation(): Promise<Device['geolocation']> {
       countryCode: json.countryCode,
       isAgeBlockedGeo: json.isAgeBlockedGeo ?? false,
       isAgeRestrictedGeo: json.isAgeRestrictedGeo ?? false,
+      // @ts-ignore
+      regionCode: json.regionCode ?? undefined,
     }
   } else {
     return undefined
   }
 }
 
+async function compareWithIPCC(bapp: Device['geolocation']) {
+  try {
+    const ipcc = await getGeolocation(IPCC_URL)
+
+    if (!ipcc || !bapp) return
+
+    logger.metric(
+      'geo:debug',
+      {
+        bappCountryCode: bapp.countryCode,
+        // @ts-ignore
+        bappRegionCode: bapp.regionCode,
+        bappIsAgeBlockedGeo: bapp.isAgeBlockedGeo,
+        bappIsAgeRestrictedGeo: bapp.isAgeRestrictedGeo,
+        ipccCountryCode: ipcc.countryCode,
+        ipccIsAgeBlockedGeo: ipcc.isAgeBlockedGeo,
+        ipccIsAgeRestrictedGeo: ipcc.isAgeRestrictedGeo,
+      },
+      {
+        statsig: false,
+      },
+    )
+  } catch {}
+}
+
 /**
  * Local promise used within this file only.
  */
@@ -81,11 +121,12 @@ export function beginResolveGeolocation() {
 
     try {
       // Try once, fail fast
-      const geolocation = await getGeolocation()
+      const geolocation = await getGeolocation(BAPP_CONFIG_URL)
       if (geolocation) {
-        device.set(['geolocation'], geolocation)
+        device.set(['geolocation'], sanitizeGeolocation(geolocation))
         emitGeolocationUpdate(geolocation)
         logger.debug(`geolocation: success`, {geolocation})
+        compareWithIPCC(geolocation)
       } else {
         // endpoint should throw on all failures, this is insurance
         throw new Error(`geolocation: nothing returned from initial request`)
@@ -101,13 +142,14 @@ export function beginResolveGeolocation() {
       device.set(['geolocation'], DEFAULT_GEOLOCATION)
 
       // retry 3 times, but don't await, proceed with default
-      networkRetry(3, getGeolocation)
+      networkRetry(3, () => getGeolocation(BAPP_CONFIG_URL))
         .then(geolocation => {
           if (geolocation) {
-            device.set(['geolocation'], geolocation)
+            device.set(['geolocation'], sanitizeGeolocation(geolocation))
             emitGeolocationUpdate(geolocation)
             logger.debug(`geolocation: success`, {geolocation})
             success = true
+            compareWithIPCC(geolocation)
           } else {
             // endpoint should throw on all failures, this is insurance
             throw new Error(`geolocation: nothing returned from retries`)