# SDK 3.2.0 login-view update

See [LOGIN_VIEW.md](./LOGIN_VIEW.md) for required/optional login, guest callbacks and every platform example. Existing calls remain required by default. The profile API is unchanged from 3.0.0.

# ExtremeX ONE SDK 3.2.0

Profile reads use only the named helpers shown in Client → Documentation. The generic `one.auth.data.get` and legacy `isUserVarified` alias were removed. Sign-in/session methods remain for authentication; `one.auth.signOut()` ends the app session. Phone pairs remain strings.

`isUserAgeVarified()` returns null for missing/denied data, true for trusted verification, or false for an unverified profile. For false, the supplied UI offers verification at https://one.extremextechnology.com/account. Headless/custom UI hosts receive `age_verification` through the existing missing-data handler and must display the dialog themselves. The callback URL is always the ONE account URL. Save/verify in ONE, return, and retry. No raw date of birth is returned.

# ExtremeX ONE Auth + Data 3.2.0

Start at https://client.extremextechnology.com/docs.

## Files

- Maven: `com.extremex.one:exone-android:3.2.0` (Android auth/data, native layout/dialog, Keystore persistence), `exone-data:3.2.0` (JVM auth/data facade), `exone-auth:3.2.0` (low-level auth).
- `exone.js`: browser and Node ES module, auth/data and browser layout/dialog.
- `react-native.jsx`: React Native views and `react-native-app-auth` adapter. Install/link AppAuth and use a Keychain/Keystore storage adapter implementing async getItem/setItem/removeItem.
- `apple/`: local Swift package for iOS/macOS, Objective-C-callable client, SwiftUI view and UIKit example. Uses ASWebAuthenticationSession and Keychain. Call on the main thread.
- `kmp/`: Kotlin Multiplatform source module. `OneLoginView.kt` is an optional Compose Multiplatform view/dialog; copy it into a project already using Compose Material 3. Ktor HTTP client must disable redirects (`HttpClient(engine) { followRedirects = false }`).
- `exone.py`, `exone.rb`, `go/`, `rust/`: source libraries with auth/data clients.
- `nextjs/`: server-only adapter and route examples. Copy files to paths described in their comments; set ONE_APP_ID, ONE_CLIENT_ID, ONE_CLIENT_SECRET, ONE_REDIRECT_URL and ONE_SESSION_KEY (32 random bytes encoded as 64 hex characters). One SDK client per request/user, never one global server session. For horizontally scaled or parallel-refresh web backends use a shared server-side session store with per-session refresh locking; the cookie adapter is a minimal single-request integration.
- `desktop/`: Swing and Tkinter login layouts/dialogs. The host application registers and receives OS callbacks, forwarding them to the same client instance.

## Flow and registration

Native/browser-only applications select Public client (stored as app_type=other). Confidential web backends select Web app. Required parameters: APP_ID and CLIENT_ID. Native libraries default REDIRECT_URL to https://client.extremextechnology.com/callback/APP_ID, relaying to APP_ID://callback. Register APP_ID as the OS URL scheme. For React Native AppAuth, add APP_ID://callback to Client's redirect URLs. For browser-only or server apps, supply the exact HTTPS callback as both redirectUri and callbackUri.

The library opens ONE's external browser login, not an embedded password WebView. Signup opens https://one.extremextechnology.com/signup. ONE hosts the authoritative permission and missing-profile-data views, so every language uses the same required/optional choices and field validation. App code receives a profile only after code/state/PKCE validation. Persist pending state/verifier securely if your app/process will be recreated during sign-in.

Enable App data (`attributes`) and Stay signed in (`offline`) in the registered app's Data access tab as needed. SDKs honor the manifest selected there. Data supports raw JSON only, compressed before encryption: 16 KiB uncompressed UTF-8 JSON per value, 100 keys/write, depth 20 and 1.7 MB/request. No file/media upload API; recognized file encodings are rejected. Arbitrary text cannot reliably be distinguished from deliberately disguised binary content; do not use string fields to store files. ONE profile photos are the only image-upload exception.

## Sessions

Native clients use S256 PKCE and never include CLIENT_SECRET. Only confidential backend clients use it. Code/state/verifier are single-use and time-bounded. Refresh tokens rotate; save every replacement. Python/Ruby/Go/Rust/JVM expose secure-storage hooks; browser examples use sessionStorage. Android and Apple persist tokens in Keystore/Keychain. `signOut` clears the local app session; disconnect in ONE's Connected apps to revoke server access.

## Verification

See `VERIFICATION.md` for the release checks and platform limitations. Native OS browser/callback behavior must also be verified on your target devices with your registered app.

## SDK 3.2.0 API

App-created variables use `one.data.set`, `one.data.get`, `one.data.del`, and `one.data.rep`. `rep` rejects null and writes a replacement (creates the key if missing). Old remove/update/Async aliases remain compatible. Android exposes both data and auth directly; callback overloads run on workers, so dispatch UI changes to the main thread. Synchronous JVM calls must run off Android's main thread.


Go uses exported names (`one.Auth.Data.IsUserTeen`). Rust uses borrowing facades and snake case (`one.auth().data().is_user_teen().await?`). Python uses `one.data.del_` because del is a keyword. Swift/Objective-C use completion callbacks.

## Easier installation

- Android/JVM: Maven coordinates above.
- KMP JVM/JS: `implementation("com.extremex.one:exone-kmp:3.2.0")` from the ONE Maven repository. Native/source projects can use the installer; Apple targets require macOS.
- Swift/Objective-C: Xcode Add Package Dependencies → `https://client.extremextechnology.com/sdk/3.2.0/apple-spm`, version 3.2.0.
- JS/Node: `npm install https://client.extremextechnology.com/sdk/3.2.0/extremex-one-3.2.0.tgz`; import createClient from @extremex/one. Websites may import the hosted exone.js directly.
- Python: `python -m pip install https://client.extremextechnology.com/sdk/3.2.0/extremex_one-3.2.0-py3-none-any.whl`; import ExOne from extremex_one.
- Go: run the source installer with `init go`, then `go mod edit -require=client.extremextechnology.com/sdk/go/v3@v3.2.0` and `go mod edit -replace=client.extremextechnology.com/sdk/go/v3=./extremex-sdk/go`. The public checksum service is currently blocked by host protection; the verified local-source installer is the supported default.
- Source installer (Node 20+): `npx --yes https://client.extremextechnology.com/sdk/3.2.0/extremex-one-3.2.0.tgz init rust`. Other targets: kmp, apple, go, nextjs, react-native. It verifies hashes and preserves existing files.
- The full SDK ZIP remains an optional source archive.

## App moderation

Client → Users supports temporary/permanent bans with a reason, unban, connection deletion, and validated JSON rules. ONE enforces these checks on approval, token exchange/refresh, profile reads, data reads/deletes and proposed data writes. Reasons appear in ONE's screen and SDK errors. A deleted connection removes only that app's stored values and invalidates its tokens; the ONE account and other apps remain. Existing bans survive connection deletion.

Rules evaluate consented profile fields or this app's raw data. Each rule version applies once per user; expired bans do not immediately reapply that version. Unban overrides current rule versions. Changes to a rule create a new version. App-data inputs are user-controlled, so use a trusted backend for authoritative abuse signals. See the Users tab for the exact JSON schema.


## Profile helpers in 3.2.0

All user-requested helpers are under `one.auth.data`. They include avatar, name, email, home/work phone and address, nationality, country of birth, languages, 13+/18+/25+, birthday, verified age, and email/phone verification flags. See https://client.extremextechnology.com/docs#profile-helpers for the complete table and platform examples.

Phone helpers return **string pairs** `[country_code, phone_number]`, preserving significant zeros. Name arrays have two fixed positions; address arrays have six. Unavailable components remain null. Dates of birth and exact ages are never exposed to apps. Birthday uses UTC. Age thresholds describe the saved date; require `isUserAgeVarified() == true` as well when verified age is necessary.

`getAvatar()` returns Android Bitmap, Apple UIImage/NSImage, browser ImageBitmap, Go image.RGBA, JVM AvatarBitmap (ARGB pixels), or an RGBA bitmap in KMP/Python/Ruby/Rust/Node/React Native. Maximum dimensions are 256 × 256. It returns null without consent or a usable ONE photo.

Missing-data hooks are `onMissingData` on Java/KMP/Swift profile data, `onMissingData` in JS client options, `on_missing_data` on Python/Ruby profile data, `OnMissingData` on Go ProfileData, and `on_missing_data` on the Rust client. Hooks receive fields and the ONE completion URL (JS uses an event object). Headless clients must forward the event to their UI; no desktop is opened from a server. Built-in browser, Android, Apple, React Native and supplied desktop/Compose views provide prompts. Call `one.attach(activity)` when an Android Activity is recreated. Compose installs its handler only while its view is mounted. Save in ONE and retry the getter after returning. Denied fields never trigger completion.

### Migration

Flags are nullable: Java `Boolean`, Kotlin `Boolean?`, Swift/Objective-C `NSNumber?`, Go `*bool`, Rust `Option<bool>`, and JS/Python/Ruby null/None/nil. Never unbox without checking. Swift uses `.boolValue` after unwrapping. Generic profile getters and the legacy `isUserVarified` alias are removed. Go 3.x imports use `client.extremextechnology.com/sdk/go/v3`. Existing 1.x and 2.x releases remain available.
