Rename to additionalVerificationMethods, assume KWS always supported

Model only the methods permitted *in addition to* the always-supported
KWS flow, rather than a full method list. This prevents a region from
being configured as device-only, which would lock out web and any
platform without the native age API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Eric Bailey
2026-06-29 18:50:28 -05:00
parent d7f3ba36f0
commit fc7aefc2b4
3 changed files with 25 additions and 18 deletions
+3 -2
View File
@@ -12,7 +12,8 @@ import {type Geolocation} from '#/geolocation'
/** /**
* Debug-only config shape. Mirrors {@link AppBskyAgeassuranceDefs.Config} but * Debug-only config shape. Mirrors {@link AppBskyAgeassuranceDefs.Config} but
* uses {@link AgeAssuranceConfigRegion}, which carries the not-yet-in-lexicon * uses {@link AgeAssuranceConfigRegion}, which carries the not-yet-in-lexicon
* `verificationMethods` field so we can prototype on-device verification. * `additionalVerificationMethods` field so we can prototype on-device
* verification.
*/ */
export type DebugConfig = { export type DebugConfig = {
regions: AgeAssuranceConfigRegion[] regions: AgeAssuranceConfigRegion[]
@@ -76,7 +77,7 @@ export const config: DebugConfig = {
countryCode: 'US', countryCode: 'US',
regionCode: 'TX', regionCode: 'TX',
minAccessAge: 18, minAccessAge: 18,
verificationMethods: ['device', 'kws'], additionalVerificationMethods: ['device'],
rules: [ rules: [
{ {
age: 18, age: 18,
+11 -8
View File
@@ -7,25 +7,28 @@ import {
import {logger} from '#/ageAssurance/logger' import {logger} from '#/ageAssurance/logger'
/** /**
* The ways a user can satisfy age assurance within a given region. * Verification methods permitted in a region *in addition to* the third-party
* (KWS) flow, which is always supported. We deliberately don't model `kws` here
* so a region can never be configured as device-only (which would lock out web
* and any platform without the native age API).
* *
* - `kws`: the third-party (KWS) verification flow.
* - `device`: native on-device age APIs (Apple Declared Age Range / Google * - `device`: native on-device age APIs (Apple Declared Age Range / Google
* Play Age Signals), surfaced via `expo-age-range`. * Play Age Signals), surfaced via `expo-age-range`.
* *
* NOTE: this is not yet part of the `app.bsky.ageassurance` lexicon. It's * NOTE: this is not yet part of the `app.bsky.ageassurance` lexicon. It's
* modeled client-side (see {@link AgeAssuranceConfigRegion}) while we prototype * modeled client-side (see {@link AgeAssuranceConfigRegion}) while we prototype
* the shape. Once the lexicon adds `verificationMethods`, this can be removed in * the shape. Once the lexicon adds `additionalVerificationMethods`, this can be
* favor of the generated type. * removed in favor of the generated type.
*/ */
export type AgeAssuranceVerificationMethod = 'device' | 'kws' export type AgeAssuranceVerificationMethod = 'device'
/** /**
* A region config extended with the (not-yet-in-lexicon) `verificationMethods` * A region config extended with the (not-yet-in-lexicon)
* field. Regions without the field are treated as KWS-only. * `additionalVerificationMethods` field. Regions without the field support only
* the always-available KWS flow.
*/ */
export type AgeAssuranceConfigRegion = AppBskyAgeassuranceDefs.ConfigRegion & { export type AgeAssuranceConfigRegion = AppBskyAgeassuranceDefs.ConfigRegion & {
verificationMethods?: AgeAssuranceVerificationMethod[] additionalVerificationMethods?: AgeAssuranceVerificationMethod[]
} }
/** /**
+11 -8
View File
@@ -40,17 +40,20 @@ export function getAgeAssuranceRegionConfigWithFallback(
} }
/** /**
* Returns the verification methods permitted for a region, defaulting to * Returns the verification methods permitted for a region *in addition to* the
* `['kws']` when the region doesn't specify any (the historical behavior). * always-supported KWS flow. Empty when the region doesn't specify any (the
* historical KWS-only behavior).
* *
* NOTE: `verificationMethods` is not yet part of the lexicon, so we read it via * NOTE: `additionalVerificationMethods` is not yet part of the lexicon, so we
* {@link AgeAssuranceConfigRegion}. See that type for the migration note. * read it via {@link AgeAssuranceConfigRegion}. See that type for the migration
* note.
*/ */
export function getRegionVerificationMethods( export function getRegionAdditionalVerificationMethods(
region: AppBskyAgeassuranceDefs.ConfigRegion, region: AppBskyAgeassuranceDefs.ConfigRegion,
): AgeAssuranceVerificationMethod[] { ): AgeAssuranceVerificationMethod[] {
const methods = (region as AgeAssuranceConfigRegion).verificationMethods return (
return methods && methods.length > 0 ? methods : ['kws'] (region as AgeAssuranceConfigRegion).additionalVerificationMethods ?? []
)
} }
/** /**
@@ -60,7 +63,7 @@ export function getRegionVerificationMethods(
export function regionAllowsDeviceVerification( export function regionAllowsDeviceVerification(
region: AppBskyAgeassuranceDefs.ConfigRegion, region: AppBskyAgeassuranceDefs.ConfigRegion,
): boolean { ): boolean {
return getRegionVerificationMethods(region).includes('device') return getRegionAdditionalVerificationMethods(region).includes('device')
} }
/** /**