commit 2f2a6d787d3a44c962d4cb9b724e6318dec40c71
parent 25d9dccc1574274d217d6592e206f9369dfa5388
Author: triesap <triesap@radroots.dev>
Date: Mon, 19 Jan 2026 19:39:13 +0000
app: add keystore reset to init reset
- extend app_init_reset to accept a keystore reference
- clear keystore on reset alongside bootstrap data
- map keystore reset errors into init errors
- add unit tests for reset error handling
Diffstat:
2 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/app/src/app.rs b/app/src/app.rs
@@ -137,7 +137,13 @@ pub fn App() -> impl IntoView {
let datastore = radroots_app_core::datastore::RadrootsClientWebDatastore::new(
Some(config.datastore.idb_config),
);
- match app_init_reset(Some(&datastore), Some(&config.datastore.key_maps)).await {
+ match app_init_reset(
+ Some(&datastore),
+ Some(&config.datastore.key_maps),
+ None::<&radroots_app_core::keystore::RadrootsClientWebKeystoreNostr>,
+ )
+ .await
+ {
Ok(()) => reset_status.set(Some("reset_done".to_string())),
Err(err) => reset_status.set(Some(err.to_string())),
}
diff --git a/app/src/init.rs b/app/src/init.rs
@@ -12,7 +12,11 @@ use radroots_app_core::idb::{
RadrootsClientIdbStoreError,
RADROOTS_IDB_DATABASE,
};
-use radroots_app_core::keystore::{RadrootsClientKeystoreError, RadrootsClientWebKeystoreNostr};
+use radroots_app_core::keystore::{
+ RadrootsClientKeystoreError,
+ RadrootsClientKeystoreNostr,
+ RadrootsClientWebKeystoreNostr,
+};
use crate::{
app_datastore_clear_bootstrap,
@@ -156,13 +160,17 @@ pub fn app_init_mark_completed() {
}
}
-pub async fn app_init_reset<T: RadrootsClientDatastore>(
+pub async fn app_init_reset<T: RadrootsClientDatastore, K: RadrootsClientKeystoreNostr>(
datastore: Option<&T>,
key_maps: Option<&AppKeyMapConfig>,
+ keystore: Option<&K>,
) -> AppInitResult<()> {
if let (Some(datastore), Some(key_maps)) = (datastore, key_maps) {
app_datastore_clear_bootstrap(datastore, key_maps).await?;
}
+ if let Some(keystore) = keystore {
+ keystore.reset().await.map_err(AppInitError::Keystore)?;
+ }
#[cfg(target_arch = "wasm32")]
{
let window = window();
@@ -240,7 +248,12 @@ mod tests {
use crate::app_config_default;
use radroots_app_core::datastore::RadrootsClientDatastoreError;
use radroots_app_core::idb::RadrootsClientIdbStoreError;
- use radroots_app_core::keystore::RadrootsClientKeystoreError;
+ use radroots_app_core::keystore::{
+ RadrootsClientKeystoreError,
+ RadrootsClientKeystoreNostr,
+ RadrootsClientKeystoreResult,
+ };
+ use async_trait::async_trait;
use crate::AppConfigError;
#[test]
@@ -291,10 +304,54 @@ mod tests {
super::app_init_mark_completed();
let result = futures::executor::block_on(super::app_init_reset::<
radroots_app_core::datastore::RadrootsClientWebDatastore,
- >(None, None));
+ TestKeystore,
+ >(None, None, None));
assert!(result.is_ok());
}
+ struct TestKeystore;
+
+ #[async_trait(?Send)]
+ impl RadrootsClientKeystoreNostr for TestKeystore {
+ async fn generate(&self) -> RadrootsClientKeystoreResult<String> {
+ Err(RadrootsClientKeystoreError::IdbUndefined)
+ }
+
+ async fn add(&self, _secret_key: &str) -> RadrootsClientKeystoreResult<String> {
+ Err(RadrootsClientKeystoreError::IdbUndefined)
+ }
+
+ async fn read(&self, _public_key: &str) -> RadrootsClientKeystoreResult<String> {
+ Err(RadrootsClientKeystoreError::IdbUndefined)
+ }
+
+ async fn keys(&self) -> RadrootsClientKeystoreResult<Vec<String>> {
+ Err(RadrootsClientKeystoreError::IdbUndefined)
+ }
+
+ async fn remove(&self, _public_key: &str) -> RadrootsClientKeystoreResult<String> {
+ Err(RadrootsClientKeystoreError::IdbUndefined)
+ }
+
+ async fn reset(&self) -> RadrootsClientKeystoreResult<()> {
+ Err(RadrootsClientKeystoreError::IdbUndefined)
+ }
+ }
+
+ #[test]
+ fn app_init_reset_maps_keystore_errors() {
+ let keystore = TestKeystore;
+ let err = futures::executor::block_on(super::app_init_reset::<
+ radroots_app_core::datastore::RadrootsClientWebDatastore,
+ TestKeystore,
+ >(None, None, Some(&keystore)))
+ .expect_err("keystore reset should error on native");
+ assert_eq!(
+ err,
+ AppInitError::Keystore(RadrootsClientKeystoreError::IdbUndefined)
+ );
+ }
+
#[test]
fn app_init_stage_roundtrip() {
let stage = AppInitStage::Ready;