Bluesky app fork with some witchin' additions 💫

fix age assurance and geolocation breaking things

xan.lol 62334b9f 70b84206

verified
+33 -85
+17 -28
src/ageAssurance/data.tsx
··· 3 3 type AppBskyAgeassuranceDefs, 4 4 type AppBskyAgeassuranceGetConfig, 5 5 type AppBskyAgeassuranceGetState, 6 - AtpAgent, 6 + type AtpAgent, 7 7 getAgeAssuranceRegionConfig, 8 8 } from '@atproto/api' 9 9 import AsyncStorage from '@react-native-async-storage/async-storage' ··· 13 13 import debounce from 'lodash.debounce' 14 14 15 15 import {networkRetry} from '#/lib/async/retry' 16 - import {PUBLIC_BSKY_SERVICE} from '#/lib/constants' 17 16 import {getAge} from '#/lib/strings/time' 18 17 import { 19 18 hasSnoozedBirthdateUpdateForDid, ··· 91 90 export const configQueryKey = ['config'] 92 91 export async function getConfig() { 93 92 if (debug.enabled) return debug.resolve(debug.config) 94 - const agent = new AtpAgent({ 95 - service: PUBLIC_BSKY_SERVICE, 96 - }) 97 - const res = await agent.app.bsky.ageassurance.getConfig() 98 - return res.data 93 + return { 94 + regions: [], 95 + } 99 96 } 100 97 export function getConfigFromCache(): 101 98 | AppBskyAgeassuranceGetConfig.OutputSchema ··· 179 176 export function createServerStateQueryKey({did}: {did: string}) { 180 177 return ['serverState', did] 181 178 } 182 - export async function getServerState({agent}: {agent: AtpAgent}) { 179 + export async function getServerState() { 183 180 if (debug.enabled && debug.serverState) 184 181 return debug.resolve(debug.serverState) 185 - const geolocation = device.get(['mergedGeolocation']) 186 - if (!geolocation || !geolocation.countryCode) { 187 - logger.error(`getServerState: missing geolocation countryCode`) 188 - return 182 + return { 183 + state: { 184 + lastInitiatedAt: '2025-07-14T14:22:43.912Z', 185 + status: 'assured' as const, 186 + access: 'full' as const, 187 + }, 188 + metadata: { 189 + accountCreatedAt: '2022-11-17T00:35:16.391Z', 190 + }, 189 191 } 190 - const {data} = await agent.app.bsky.ageassurance.getState({ 191 - countryCode: geolocation.countryCode, 192 - regionCode: geolocation.regionCode, 193 - }) 194 - const did = getDidFromAgentSession(agent) 195 - if (data && did && createdAtCache.has(did)) { 196 - /* 197 - * If account was just created, just use the local cache if available. On 198 - * subsequent reloads, the server should have the correct value. 199 - */ 200 - data.metadata.accountCreatedAt = createdAtCache.get(did) 201 - } 202 - return data ?? null 203 192 } 204 193 export function getServerStateFromCache({ 205 194 did, ··· 226 215 227 216 try { 228 217 logger.debug(`prefetchServerState: resolving...`) 229 - const res = await networkRetry(3, () => getServerState({agent})) 218 + const res = await networkRetry(3, () => getServerState()) 230 219 qc.setQueryData<AppBskyAgeassuranceGetState.OutputSchema>(qk, res) 231 220 } catch (e: any) { 232 221 logger.warn(`prefetchServerState: failed`, { ··· 238 227 const did = getDidFromAgentSession(agent) 239 228 if (!did) return 240 229 logger.debug(`refetchServerState: fetching...`) 241 - const res = await networkRetry(3, () => getServerState({agent})) 230 + const res = await networkRetry(3, () => getServerState()) 242 231 qc.setQueryData<AppBskyAgeassuranceGetState.OutputSchema>( 243 232 createServerStateQueryKey({did}), 244 233 res, ··· 277 266 }, 278 267 queryKey: createServerStateQueryKey({did: did!}), 279 268 async queryFn() { 280 - return getServerState({agent}) 269 + return getServerState() 281 270 }, 282 271 }, 283 272 qc,
+5 -10
src/env/common.ts
··· 123 123 : Number(process.env.EXPO_PUBLIC_GCP_PROJECT_ID) 124 124 125 125 /** 126 - * URLs for the app config web worker. Can be a 127 - * locally running server, see `env.example` for more. 128 - */ 129 - export const GEOLOCATION_DEV_URL = process.env.GEOLOCATION_DEV_URL 130 - export const GEOLOCATION_PROD_URL = `https://ip.bsky.app` 131 - export const GEOLOCATION_URL = IS_DEV 132 - ? (GEOLOCATION_DEV_URL ?? GEOLOCATION_PROD_URL) 133 - : GEOLOCATION_PROD_URL 134 - 135 - /** 136 126 * URLs for the live-event config web worker. Can be a 137 127 * locally running server, see `env.example` for more. 138 128 */ 129 + export const LIVE_EVENTS_DEV_URL = process.env.LIVE_EVENTS_DEV_URL 130 + export const LIVE_EVENTS_PROD_URL = `https://live-events.workers.bsky.app` 131 + export const LIVE_EVENTS_URL = IS_DEV 132 + ? (LIVE_EVENTS_DEV_URL ?? LIVE_EVENTS_PROD_URL) 133 + : LIVE_EVENTS_PROD_URL
+1 -2
src/geolocation/const.ts
··· 1 - import {GEOLOCATION_URL} from '#/env' 2 1 import {type Geolocation} from '#/geolocation/types' 3 2 4 - export const GEOLOCATION_SERVICE_URL = `${GEOLOCATION_URL}/geolocation` 3 + export const GEOLOCATION_SERVICE_URL = '' // No longer needed 5 4 6 5 /** 7 6 * Default geolocation config.
+10 -45
src/geolocation/service.ts
··· 1 1 import {useEffect, useState} from 'react' 2 2 import EventEmitter from 'eventemitter3' 3 3 4 - import {networkRetry} from '#/lib/async/retry' 5 - import { 6 - FALLBACK_GEOLOCATION_SERVICE_RESPONSE, 7 - GEOLOCATION_SERVICE_URL, 8 - } from '#/geolocation/const' 4 + import {FALLBACK_GEOLOCATION_SERVICE_RESPONSE} from '#/geolocation/const' 9 5 import * as debug from '#/geolocation/debug' 10 6 import {logger} from '#/geolocation/logger' 11 7 import {type Geolocation} from '#/geolocation/types' 12 8 import {device} from '#/storage' 13 9 10 + const geolocationData = FALLBACK_GEOLOCATION_SERVICE_RESPONSE 14 11 const events = new EventEmitter() 15 12 const EVENT = 'geolocation-service-response-updated' 16 13 const emitGeolocationServiceResponseUpdate = (data: Geolocation) => { ··· 25 22 } 26 23 } 27 24 28 - async function fetchGeolocationServiceData( 29 - url: string, 30 - ): Promise<Geolocation | undefined> { 25 + async function fetchGeolocationServiceData(): Promise<Geolocation | undefined> { 31 26 if (debug.enabled) return debug.resolve(debug.geolocation) 32 - const res = await fetch(url) 33 - if (!res.ok) { 34 - throw new Error(`fetchGeolocationServiceData failed ${res.status}`) 35 - } 36 - return res.json() as Promise<Geolocation> 27 + // Return local geolocation data instead of making HTTP request 28 + return geolocationData as Geolocation 37 29 } 38 30 39 31 /** ··· 63 55 } else { 64 56 logger.debug(`resolve(): initiating`) 65 57 66 - /** 67 - * THIS PROMISE SHOULD NEVER `reject()`! We want the app to proceed with 68 - * startup, even if geolocation resolution fails. 69 - */ 70 58 geolocationServicePromise = new Promise(async resolvePromise => { 71 59 let success = false 72 60 ··· 75 63 device.set(['geolocationServiceResponse'], response) 76 64 emitGeolocationServiceResponseUpdate(response) 77 65 } else { 78 - // endpoint should throw on all failures, this is insurance 79 66 throw new Error(`fetchGeolocationServiceData returned no data`) 80 67 } 81 68 } 82 69 83 70 try { 84 - // Try once, fail fast 85 - const config = await fetchGeolocationServiceData( 86 - GEOLOCATION_SERVICE_URL, 87 - ) 71 + // Use local data - no need to retry or handle network errors 72 + const config = await fetchGeolocationServiceData() 88 73 cacheResponseOrThrow(config) 89 74 success = true 90 75 } catch (e: any) { 91 - logger.debug( 92 - `resolve(): fetchGeolocationServiceData failed initial request`, 93 - { 94 - safeMessage: e.message, 95 - }, 96 - ) 97 - 98 - // retry 3 times, but don't await, proceed with default 99 - networkRetry(3, () => 100 - fetchGeolocationServiceData(GEOLOCATION_SERVICE_URL), 101 - ) 102 - .then(config => { 103 - cacheResponseOrThrow(config) 104 - }) 105 - .catch((err: any) => { 106 - // complete fail closed 107 - logger.debug( 108 - `resolve(): fetchGeolocationServiceData failed retries`, 109 - { 110 - safeMessage: err.message, 111 - }, 112 - ) 113 - }) 76 + logger.debug(`resolve(): fetchGeolocationServiceData failed`, { 77 + safeMessage: e.message, 78 + }) 114 79 } finally { 115 80 resolvePromise({success}) 116 81 }