diff --git a/src/ageAssurance/components/NoAccessScreen.tsx b/src/ageAssurance/components/NoAccessScreen.tsx index 1f0bbb051a..91f63f4da4 100644 --- a/src/ageAssurance/components/NoAccessScreen.tsx +++ b/src/ageAssurance/components/NoAccessScreen.tsx @@ -42,7 +42,7 @@ import { import {logger} from '#/ageAssurance/logger' import {useComputeAgeAssuranceRegionAccess} from '#/ageAssurance/useComputeAgeAssuranceRegionAccess' import { - getAssuredAgeFromDeviceSignals, + getAgeAssuranceDataFromDeviceSignals, isLegacyBirthdateBug, regionAllowsDeviceVerification, useAgeAssuranceRegionConfig, @@ -360,7 +360,10 @@ function AccessSection() { setIsVerifyingDevice(false) } if (signals && did) { - const assuredAge = getAssuredAgeFromDeviceSignals(region, signals) + const {assuredAge} = getAgeAssuranceDataFromDeviceSignals( + region, + signals, + ) if (assuredAge !== undefined) { // Sufficient device signals: persist (keyed by this region) and let // the AA state recompute from the cache write unlock access. Nothing diff --git a/src/ageAssurance/state.ts b/src/ageAssurance/state.ts index 7d31da2706..677937b781 100644 --- a/src/ageAssurance/state.ts +++ b/src/ageAssurance/state.ts @@ -25,8 +25,8 @@ import { } from '#/ageAssurance/types' import { computeAgeAssuranceFlags, + getAgeAssuranceDataFromDeviceSignals, getAgeAssuranceRegionConfigWithFallback, - getAssuredAgeFromDeviceSignals, } from '#/ageAssurance/util' import {type Geolocation, useGeolocation} from '#/geolocation' import {device} from '#/storage' @@ -103,7 +103,10 @@ function computeAgeAssuranceState({ * is treated as an assured age and fed into the rule engine, where it * matches `IfAssuredOverAge`/`IfAssuredUnderAge` rules. */ - const assuredAge = getAssuredAgeFromDeviceSignals(region, deviceSignals) + const {assuredAge} = getAgeAssuranceDataFromDeviceSignals( + region, + deviceSignals, + ) const result = computeAgeAssuranceRegionAccess(region, { accountCreatedAt: metadata?.accountCreatedAt, declaredAge: metadata?.declaredAge, diff --git a/src/ageAssurance/types.ts b/src/ageAssurance/types.ts index 50ef68eaa2..9d841f67df 100644 --- a/src/ageAssurance/types.ts +++ b/src/ageAssurance/types.ts @@ -38,7 +38,7 @@ export type AgeAssuranceConfigRegion = AppBskyAgeassuranceDefs.ConfigRegion & { * attestation, only age bounds), so we persist it client-side only and bind it * to its capture region via the key. A grant captured in TX is only ever read * back for TX — it can't silently unlock another region. See - * `getAssuredAgeFromDeviceSignals`. + * `getAgeAssuranceDataFromDeviceSignals`. */ export type AgeAssuranceDeviceSignals = { [regionKey: string]: AgeRange.AgeRangeResponse diff --git a/src/ageAssurance/util.ts b/src/ageAssurance/util.ts index 2292c630cf..6128e4a620 100644 --- a/src/ageAssurance/util.ts +++ b/src/ageAssurance/util.ts @@ -79,26 +79,31 @@ export function createRegionKey(region: { } /** - * Derives an assured age from native device signals for the given region, but - * only when the region permits device verification. The signals are expected to - * already be resolved to the user's current region (see + * Derives age assurance data from native device signals for the given region, + * but only when the region permits device verification. The signals are + * expected to already be resolved to the user's current region (see * `getDeviceSignalsFromCacheForCurrentRegion`), so a grant captured in another * region won't reach here. * * The OS-provided `lowerBound` is the minimum age the platform will attest to, - * which maps directly onto the `assuredAge` input of the rule engine (i.e. + * which maps onto the `assuredAge` input of the rule engine (i.e. * `IfAssuredOverAge`/`IfAssuredUnderAge` rules). * - * Returns undefined when device verification doesn't apply or the OS didn't - * provide a usable lower bound. + * Always returns an object (so callers can spread it unconditionally); fields + * are populated only when device verification applies and the OS provided + * usable data. */ -export function getAssuredAgeFromDeviceSignals( +export function getAgeAssuranceDataFromDeviceSignals( region: AppBskyAgeassuranceDefs.ConfigRegion, deviceSignals: AgeRange.AgeRangeResponse | undefined, -): number | undefined { - if (!regionAllowsDeviceVerification(region)) return undefined +): { + assuredAge?: number +} { + if (!regionAllowsDeviceVerification(region)) return {} const lowerBound = deviceSignals?.lowerBound - return typeof lowerBound === 'number' ? lowerBound : undefined + return { + assuredAge: typeof lowerBound === 'number' ? lowerBound : undefined, + } } /**