Synced app settings: colour theme and appearance (beta)
ci / test (push) Waiting to run
ci / wasm (push) Waiting to run
ci / deny (push) Waiting to run
ci / fuzz (push) Waiting to run

One encrypted settings item per account (a secure note carrying
app_settings, at a fixed per-account id) holds the theme and light/dark
appearance, so it syncs like any item and the server can't read it. Lists
hide it; older apps see a note that explains itself. app_theme /
set_app_theme in kv-ffi and kv-wasm. Also fixes a flaky test that checked
random ciphertext for the letters K1.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-27 00:12:08 +07:00
co-authored by Claude Opus 5.5
parent 203bd9044d
commit 7c8a5b668f
10 changed files with 298 additions and 5 deletions
+23
View File
@@ -420,3 +420,26 @@ async fn removed_web_vault_reenrols_with_the_same_ticket() {
web.forget_revoked_device().unwrap();
assert!(matches!(app.approve_device(old.to_string()).await, Err(kv_ffi::CoreError::NotFound)));
}
#[tokio::test]
async fn theme_set_in_the_app_reaches_the_web_vault_and_back() {
let server = TestServer::start().await;
let (app, _sk, _) = app_with_item(&server).await;
app.set_app_theme(Some("amber".into()), Some("light".into())).unwrap();
app.sync_now().await.unwrap();
let add = app.add_device_payload().await.unwrap();
let setup = kv_wasm::core::parse_setup_payload(&add.payload).unwrap();
let (_store, web) = new_web(&server);
web.login_with_setup(&setup, PW).await.unwrap();
web.sync_now().await.unwrap();
let t = web.app_theme().unwrap();
assert_eq!((t.theme.as_deref(), t.appearance.as_deref()), (Some("amber"), Some("light")));
assert_eq!(web.list_items().unwrap().len(), 1, "only Bank; the settings item is hidden");
web.set_app_theme(Some("rose".into()), Some("dark".into())).unwrap();
web.sync_now().await.unwrap();
app.sync_now().await.unwrap();
assert_eq!(app.app_theme().unwrap().theme.as_deref(), Some("rose"));
assert_eq!(app.list_items().unwrap().len(), 1);
}