app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 6cc74b684653b02019a389be07316a6159a89b1a
parent 575150340626833fdf0722934a9c1f4825495e9d
Author: triesap <tyson@radroots.org>
Date:   Mon,  2 Feb 2026 19:12:58 +0000

app: add eula fingerprint to setup state

- define eula version and hash constants
- set fingerprint on new setup state
- require fingerprint for initialized state
- add validation unit tests

Diffstat:
Mapp/src/data.rs | 24+++++++++++++++++++-----
Mapp/src/lib.rs | 2++
Mapp/src/setup.rs | 17++++++++++++++---
3 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/app/src/data.rs b/app/src/data.rs @@ -32,14 +32,17 @@ pub struct RadrootsAppState { pub notifications_permission: Option<String>, } +pub const APP_EULA_VERSION: &str = "0.1.0"; +pub const APP_EULA_HASH: &str = "unknown"; + impl Default for RadrootsAppState { fn default() -> Self { Self { active_key: String::new(), role: RadrootsAppRole::default(), eula_date: String::new(), - eula_version: String::from("0.1.0"), - eula_hash: String::from("unknown"), + eula_version: String::from(APP_EULA_VERSION), + eula_hash: String::from(APP_EULA_HASH), relays: Vec::new(), nip05_key: None, notifications_permission: None, @@ -176,7 +179,10 @@ pub fn app_state_record_validate( } pub fn app_state_is_initialized(state: &RadrootsAppState) -> bool { - !state.active_key.is_empty() && !state.eula_date.is_empty() + !state.active_key.is_empty() + && !state.eula_date.is_empty() + && !state.eula_version.is_empty() + && !state.eula_hash.is_empty() } #[cfg(test)] @@ -189,6 +195,8 @@ mod tests { RadrootsAppRole, RadrootsAppState, RadrootsAppStateError, + APP_EULA_HASH, + APP_EULA_VERSION, APP_STATE_SCHEMA_VERSION, }; @@ -203,8 +211,8 @@ mod tests { assert_eq!(data.active_key, ""); assert_eq!(data.role, RadrootsAppRole::Individual); assert_eq!(data.eula_date, ""); - assert_eq!(data.eula_version, "0.1.0"); - assert_eq!(data.eula_hash, "unknown"); + assert_eq!(data.eula_version, APP_EULA_VERSION); + assert_eq!(data.eula_hash, APP_EULA_HASH); assert!(data.relays.is_empty()); assert!(data.nip05_key.is_none()); assert!(data.notifications_permission.is_none()); @@ -218,6 +226,12 @@ mod tests { data.active_key = "pub".to_string(); assert!(!app_state_is_initialized(&data)); data.eula_date = "2025-01-01T00:00:00Z".to_string(); + data.eula_version.clear(); + assert!(!app_state_is_initialized(&data)); + data.eula_version = APP_EULA_VERSION.to_string(); + data.eula_hash.clear(); + assert!(!app_state_is_initialized(&data)); + data.eula_hash = APP_EULA_HASH.to_string(); assert!(app_state_is_initialized(&data)); } diff --git a/app/src/lib.rs b/app/src/lib.rs @@ -48,6 +48,8 @@ pub use data::{ RadrootsAppSetupDraft, RadrootsAppStateError, RadrootsAppStateRecord, + APP_EULA_HASH, + APP_EULA_VERSION, APP_STATE_SCHEMA_VERSION, }; pub use health::{ diff --git a/app/src/setup.rs b/app/src/setup.rs @@ -22,6 +22,8 @@ use crate::{ RadrootsAppKeystoreError, RadrootsAppRole, RadrootsAppState, + APP_EULA_HASH, + APP_EULA_VERSION, }; #[cfg(target_arch = "wasm32")] @@ -43,8 +45,8 @@ pub fn app_setup_state_new( active_key, role, eula_date, - eula_version: String::from("0.1.0"), - eula_hash: String::from("unknown"), + eula_version: String::from(APP_EULA_VERSION), + eula_hash: String::from(APP_EULA_HASH), relays: app_default_relays(), nip05_key: None, notifications_permission: None, @@ -158,7 +160,14 @@ mod tests { app_setup_step_default, RadrootsAppSetupStep, }; - use crate::{app_datastore_key_nostr_key, app_key_maps_default, RadrootsAppRole, RadrootsAppStateRecord}; + use crate::{ + app_datastore_key_nostr_key, + app_key_maps_default, + RadrootsAppRole, + RadrootsAppStateRecord, + APP_EULA_HASH, + APP_EULA_VERSION, + }; use async_trait::async_trait; use radroots_app_core::backup::RadrootsClientBackupDatastorePayload; use radroots_app_core::datastore::{ @@ -358,6 +367,8 @@ mod tests { assert_eq!(state.active_key, "pub"); assert_eq!(state.role, RadrootsAppRole::Individual); assert_eq!(state.eula_date, "2025-01-01T00:00:00Z"); + assert_eq!(state.eula_version, APP_EULA_VERSION); + assert_eq!(state.eula_hash, APP_EULA_HASH); assert!(!state.relays.is_empty()); assert!(state.nip05_key.is_none()); assert!(state.notifications_permission.is_none());