From 45dffe0d9f14ed86d2c0c5aaec893d0cd2fa3b3f Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Mon, 8 Sep 2025 14:54:02 -0400 Subject: [PATCH] Use VeilidAPIError type for ProtectedStore functions --- CHANGELOG.md | 1 + .../src/intf/native/protected_store.rs | 49 +++++++------ veilid-core/src/intf/wasm/protected_store.rs | 71 +++++++++---------- 3 files changed, 61 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25ba948f..dd715195 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ - Eliminated 'best' CryptoKind concept, crypto kinds must now be explicitly stated, otherwise upgrades of veilid-core that change the 'best' CryptoKind could break functionality silently. - Encryption is enabled by default for all DHT operations, closes [#300](https://gitlab.com/veilid/veilid/-/issues/300) (@neequ57) - Deprecation of WSS config and removal of Application config + - Use VeilidAPIError type for ProtectedStore functions [#480](https://gitlab.com/veilid/veilid/-/issues/480) - veilid-core: - Hop counts removed from private routes [#466](https://gitlab.com/veilid/veilid/-/issues/466) diff --git a/veilid-core/src/intf/native/protected_store.rs b/veilid-core/src/intf/native/protected_store.rs index 4b55f3f7..f484dfb5 100644 --- a/veilid-core/src/intf/native/protected_store.rs +++ b/veilid-core/src/intf/native/protected_store.rs @@ -37,8 +37,8 @@ impl ProtectedStore { } } - #[instrument(level = "trace", skip(self), err)] - pub fn delete_all(&self) -> EyreResult<()> { + #[instrument(level = "trace", skip(self))] + pub fn delete_all(&self) { for kpsk in &KNOWN_PROTECTED_STORE_KEYS { if let Err(e) = self.remove_user_secret(kpsk) { veilid_log!(self error "failed to delete '{}': {}", kpsk, e); @@ -46,7 +46,6 @@ impl ProtectedStore { veilid_log!(self debug "deleted protected store key '{}'", kpsk); } } - Ok(()) } #[instrument(level = "debug", skip(self), err)] @@ -103,7 +102,7 @@ impl ProtectedStore { }; if delete { - self.delete_all()?; + self.delete_all(); } Ok(()) @@ -137,50 +136,53 @@ impl ProtectedStore { &self, key: K, value: V, - ) -> EyreResult { + ) -> VeilidAPIResult { let inner = self.inner.lock(); inner .keyring_manager .as_ref() - .ok_or_else(|| eyre!("Protected store not initialized"))? + .ok_or_else(VeilidAPIError::not_initialized)? .with_keyring(&self.service_name(), key.as_ref(), |kr| { let existed = kr.get_value().is_ok(); kr.set_value(value.as_ref())?; Ok(existed) }) - .wrap_err("failed to save user secret") + .map_err(VeilidAPIError::generic) } #[instrument(level = "trace", skip(self), err)] pub fn load_user_secret_string + fmt::Debug>( &self, key: K, - ) -> EyreResult> { + ) -> VeilidAPIResult> { let inner = self.inner.lock(); match inner .keyring_manager .as_ref() - .ok_or_else(|| eyre!("Protected store not initialized"))? + .ok_or_else(VeilidAPIError::not_initialized)? .with_keyring(&self.service_name(), key.as_ref(), |kr| kr.get_value()) { Ok(v) => Ok(Some(v)), Err(KeyringError::NoPasswordFound) => Ok(None), - Err(e) => Err(eyre!("Failed to load user secret: {}", e)), + Err(e) => Err(VeilidAPIError::generic(format!( + "Failed to load user secret: {}", + e + ))), } } #[instrument(level = "trace", skip(self, value))] - pub fn save_user_secret_json(&self, key: K, value: &T) -> EyreResult + pub fn save_user_secret_json(&self, key: K, value: &T) -> VeilidAPIResult where K: AsRef + fmt::Debug, T: serde::Serialize, { - let v = serde_json::to_vec(value)?; + let v = serde_json::to_vec(value).map_err(VeilidAPIError::generic)?; self.save_user_secret(&key, &v) } #[instrument(level = "trace", skip(self))] - pub fn load_user_secret_json(&self, key: K) -> EyreResult> + pub fn load_user_secret_json(&self, key: K) -> VeilidAPIResult> where K: AsRef + fmt::Debug, T: for<'de> serde::de::Deserialize<'de>, @@ -193,7 +195,7 @@ impl ProtectedStore { } }; - let obj = serde_json::from_slice(&b)?; + let obj = serde_json::from_slice(&b).map_err(VeilidAPIError::generic)?; Ok(Some(obj)) } @@ -202,7 +204,7 @@ impl ProtectedStore { &self, key: K, value: &[u8], - ) -> EyreResult { + ) -> VeilidAPIResult { let mut s = BASE64URL_NOPAD.encode(value); s.push('!'); @@ -213,7 +215,7 @@ impl ProtectedStore { pub fn load_user_secret + fmt::Debug>( &self, key: K, - ) -> EyreResult>> { + ) -> VeilidAPIResult>> { let mut s = match self.load_user_secret_string(key)? { Some(s) => s, None => { @@ -222,7 +224,7 @@ impl ProtectedStore { }; if s.pop() != Some('!') { - bail!("User secret is not a buffer"); + apibail_generic!("User secret is not a buffer"); } let mut bytes = Vec::::new(); @@ -232,29 +234,32 @@ impl ProtectedStore { bytes.resize(l, 0u8); } Err(_) => { - bail!("Failed to decode"); + apibail_generic!("Failed to decode"); } } let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes); match res { Ok(_) => Ok(Some(bytes)), - Err(_) => bail!("Failed to decode"), + Err(_) => apibail_generic!("Failed to decode"), } } #[instrument(level = "trace", skip(self), ret, err)] - pub fn remove_user_secret + fmt::Debug>(&self, key: K) -> EyreResult { + pub fn remove_user_secret + fmt::Debug>(&self, key: K) -> VeilidAPIResult { let inner = self.inner.lock(); match inner .keyring_manager .as_ref() - .ok_or_else(|| eyre!("Protected store not initialized"))? + .ok_or_else(VeilidAPIError::not_initialized)? .with_keyring(&self.service_name(), key.as_ref(), |kr| kr.delete_value()) { Ok(_) => Ok(true), Err(KeyringError::NoPasswordFound) => Ok(false), - Err(e) => Err(eyre!("Failed to remove user secret: {}", e)), + Err(e) => Err(VeilidAPIError::generic(format!( + "Failed to remove user secret: {}", + e + ))), } } } diff --git a/veilid-core/src/intf/wasm/protected_store.rs b/veilid-core/src/intf/wasm/protected_store.rs index f26cfe48..6c2db2a5 100644 --- a/veilid-core/src/intf/wasm/protected_store.rs +++ b/veilid-core/src/intf/wasm/protected_store.rs @@ -13,13 +13,17 @@ pub struct ProtectedStore { impl_veilid_component!(ProtectedStore); +fn map_js_error_generic(message: M) -> impl FnOnce(JsValue) -> VeilidAPIError { + move |x| VeilidAPIError::generic(format!("{}: {}", message.to_string(), map_jsvalue_error(x))) +} + impl ProtectedStore { pub(crate) fn new(registry: VeilidComponentRegistry) -> Self { Self { registry } } - #[instrument(level = "trace", skip(self), err)] - pub fn delete_all(&self) -> EyreResult<()> { + #[instrument(level = "trace", skip(self))] + pub fn delete_all(&self) { for kpsk in &KNOWN_PROTECTED_STORE_KEYS { if let Err(e) = self.remove_user_secret(kpsk) { veilid_log!(self error "failed to delete protected store key '{}': {}", kpsk, e); @@ -27,13 +31,12 @@ impl ProtectedStore { veilid_log!(self debug "deleted protected store key '{}'", kpsk); } } - Ok(()) } #[instrument(level = "debug", skip(self), err)] async fn init_async(&self) -> EyreResult<()> { if self.config().with(|c| c.protected_store.delete) { - self.delete_all()?; + self.delete_all(); } Ok(()) @@ -65,23 +68,22 @@ impl ProtectedStore { &self, key: K, value: V, - ) -> EyreResult { + ) -> VeilidAPIResult { if is_browser() { let win = match window() { Some(w) => w, None => { - bail!("failed to get window"); + apibail_generic!("failed to get window"); } }; let ls = match win .local_storage() - .map_err(map_jsvalue_error) - .wrap_err("exception getting local storage")? + .map_err(map_js_error_generic("exception getting local storage"))? { Some(l) => l, None => { - bail!("failed to get local storage"); + apibail_generic!("failed to get local storage"); } }; @@ -89,13 +91,11 @@ impl ProtectedStore { let prev = ls .get_item(&vkey) - .map_err(map_jsvalue_error) - .wrap_err("exception_thrown")? + .map_err(map_js_error_generic("exception thrown"))? .is_some(); ls.set_item(&vkey, value.as_ref()) - .map_err(map_jsvalue_error) - .wrap_err("exception_thrown")?; + .map_err(map_js_error_generic("exception thrown"))?; Ok(prev) } else { @@ -107,47 +107,45 @@ impl ProtectedStore { pub fn load_user_secret_string + fmt::Debug>( &self, key: K, - ) -> EyreResult> { + ) -> VeilidAPIResult> { if is_browser() { let win = match window() { Some(w) => w, None => { - bail!("failed to get window"); + apibail_generic!("failed to get window"); } }; let ls = match win .local_storage() - .map_err(map_jsvalue_error) - .wrap_err("exception getting local storage")? + .map_err(map_js_error_generic("exception getting local storage"))? { Some(l) => l, None => { - bail!("failed to get local storage"); + apibail_generic!("failed to get local storage"); } }; let vkey = self.browser_key_name(key.as_ref()); ls.get_item(&vkey) - .map_err(map_jsvalue_error) - .wrap_err("exception_thrown") + .map_err(map_js_error_generic("exception thrown")) } else { unimplemented!(); } } #[instrument(level = "trace", skip(self, value))] - pub fn save_user_secret_json(&self, key: K, value: &T) -> EyreResult + pub fn save_user_secret_json(&self, key: K, value: &T) -> VeilidAPIResult where K: AsRef + fmt::Debug, T: serde::Serialize, { - let v = serde_json::to_vec(value)?; + let v = serde_json::to_vec(value).map_err(VeilidAPIError::generic)?; self.save_user_secret(key, &v) } #[instrument(level = "trace", skip(self))] - pub fn load_user_secret_json(&self, key: K) -> EyreResult> + pub fn load_user_secret_json(&self, key: K) -> VeilidAPIResult> where K: AsRef + fmt::Debug, T: for<'de> serde::de::Deserialize<'de>, @@ -160,7 +158,7 @@ impl ProtectedStore { } }; - let obj = serde_json::from_slice(&b)?; + let obj = serde_json::from_slice(&b).map_err(VeilidAPIError::generic)?; Ok(Some(obj)) } @@ -169,7 +167,7 @@ impl ProtectedStore { &self, key: K, value: &[u8], - ) -> EyreResult { + ) -> VeilidAPIResult { let mut s = BASE64URL_NOPAD.encode(value); s.push('!'); @@ -180,7 +178,7 @@ impl ProtectedStore { pub fn load_user_secret + fmt::Debug>( &self, key: K, - ) -> EyreResult>> { + ) -> VeilidAPIResult>> { let mut s = match self.load_user_secret_string(key)? { Some(s) => s, None => { @@ -189,7 +187,7 @@ impl ProtectedStore { }; if s.pop() != Some('!') { - bail!("User secret is not a buffer"); + apibail_generic!("User secret is not a buffer"); } let mut bytes = Vec::::new(); @@ -199,35 +197,34 @@ impl ProtectedStore { bytes.resize(l, 0u8); } Err(_) => { - bail!("Failed to decode"); + apibail_generic!("Failed to decode"); } } let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes); match res { Ok(_) => Ok(Some(bytes)), - Err(_) => bail!("Failed to decode"), + Err(_) => apibail_generic!("Failed to decode"), } } #[instrument(level = "trace", skip(self), ret, err)] - pub fn remove_user_secret + fmt::Debug>(&self, key: K) -> EyreResult { + pub fn remove_user_secret + fmt::Debug>(&self, key: K) -> VeilidAPIResult { if is_browser() { let win = match window() { Some(w) => w, None => { - bail!("failed to get window"); + apibail_generic!("failed to get window"); } }; let ls = match win .local_storage() - .map_err(map_jsvalue_error) - .wrap_err("exception getting local storage")? + .map_err(map_js_error_generic("exception getting local storage"))? { Some(l) => l, None => { - bail!("failed to get local storage"); + apibail_generic!("failed to get local storage"); } }; @@ -235,13 +232,11 @@ impl ProtectedStore { match ls .get_item(&vkey) - .map_err(map_jsvalue_error) - .wrap_err("exception_thrown")? + .map_err(map_js_error_generic("exception thrown"))? { Some(_) => { ls.delete(&vkey) - .map_err(map_jsvalue_error) - .wrap_err("exception_thrown")?; + .map_err(map_js_error_generic("exception thrown"))?; Ok(true) } None => Ok(false),