f281425b45
Replaces the four KeychainUnavailable stubs in auth_tokens.rs with a
real Android Keystore implementation:
- Device-bound AES-256/GCM/NoPadding key under alias
'solitaire_quest_token_key'; generated on first use, survives
restarts, destroyed on uninstall.
- Tokens serialised as JSON, encrypted to
{data_dir}/auth_tokens.bin as [12-byte IV][ciphertext+GCM-tag];
writes are atomic (tmp → rename).
- Key invalidation (biometric/lock change) surfaces as
TokenError::KeychainUnavailable, matching desktop fallback semantics.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
40 lines
1.4 KiB
TOML
40 lines
1.4 KiB
TOML
[package]
|
|
name = "solitaire_data"
|
|
version.workspace = true
|
|
license.workspace = true
|
|
edition.workspace = true
|
|
|
|
[dependencies]
|
|
solitaire_core = { workspace = true }
|
|
solitaire_sync = { workspace = true }
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
chrono = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
async-trait = { workspace = true }
|
|
dirs = { workspace = true }
|
|
reqwest = { workspace = true }
|
|
tokio = { workspace = true }
|
|
|
|
# `keyring-core` is the typed Entry/Error API used by
|
|
# `auth_tokens`. The crate's own dependency tree pulls in
|
|
# `rpassword` which uses `libc::__errno_location` — a symbol the
|
|
# Android NDK doesn't expose (`__errno` lives at a different path
|
|
# on bionic). On Android `auth_tokens` falls back to a stub
|
|
# implementation that always returns `KeychainUnavailable`; the
|
|
# real backend lands when we wire Android Keystore via JNI.
|
|
[target.'cfg(not(target_os = "android"))'.dependencies]
|
|
keyring-core = { workspace = true }
|
|
|
|
[target.'cfg(target_os = "android")'.dependencies]
|
|
jni = { workspace = true }
|
|
|
|
[dev-dependencies]
|
|
solitaire_server = { path = "../solitaire_server" }
|
|
solitaire_sync = { workspace = true }
|
|
axum = { workspace = true }
|
|
sqlx = { workspace = true }
|
|
jsonwebtoken = { workspace = true }
|
|
uuid = { workspace = true }
|
|
chrono = { workspace = true }
|