fix wasm, flutter work
This commit is contained in:
		@@ -1,5 +1,7 @@
 | 
			
		||||
use super::utils;
 | 
			
		||||
use crate::xx::*;
 | 
			
		||||
use crate::*;
 | 
			
		||||
use data_encoding::BASE64URL_NOPAD;
 | 
			
		||||
use js_sys::*;
 | 
			
		||||
use wasm_bindgen_futures::*;
 | 
			
		||||
use web_sys::*;
 | 
			
		||||
@@ -14,172 +16,246 @@ extern "C" {
 | 
			
		||||
    fn keytar_deletePassword(service: &str, account: &str) -> Result<Promise, JsValue>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn keyring_name(namespace: &str) -> String {
 | 
			
		||||
    if namespace.len() == 0 {
 | 
			
		||||
        "veilid".to_owned()
 | 
			
		||||
    } else {
 | 
			
		||||
        format!("veilid_{}", namespace)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct ProtectedStore {
 | 
			
		||||
    config: VeilidConfig,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn browser_key_name(namespace: &str, key: &str) -> String {
 | 
			
		||||
    if namespace.len() == 0 {
 | 
			
		||||
        format!("__veilid_secret_{}", key)
 | 
			
		||||
    } else {
 | 
			
		||||
        format!("__veilid_{}_secret_{}", namespace, key)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
impl ProtectedStore {
 | 
			
		||||
 | 
			
		||||
pub async fn save_user_secret_string(
 | 
			
		||||
    namespace: &str,
 | 
			
		||||
    key: &str,
 | 
			
		||||
    value: &str,
 | 
			
		||||
) -> Result<bool, String> {
 | 
			
		||||
    if utils::is_nodejs() {
 | 
			
		||||
        let prev = match JsFuture::from(
 | 
			
		||||
            keytar_getPassword(keyring_name(namespace).as_str(), key)
 | 
			
		||||
                .map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        {
 | 
			
		||||
            Ok(v) => v.is_truthy(),
 | 
			
		||||
            Err(_) => false,
 | 
			
		||||
    pub fn new(config: VeilidConfig) -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            config,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn delete_all(&self) -> Result<(), String> {
 | 
			
		||||
        // Delete all known keys
 | 
			
		||||
        if self.remove_user_secret_string("node_id").await? {
 | 
			
		||||
            debug!("deleted protected_store key 'node_id'");
 | 
			
		||||
        }
 | 
			
		||||
        if self.remove_user_secret_string("node_id_secret").await? {
 | 
			
		||||
            debug!("deleted protected_store key 'node_id_secret'");
 | 
			
		||||
        }
 | 
			
		||||
        if self.remove_user_secret_string("_test_key").await? {
 | 
			
		||||
            debug!("deleted protected_store key '_test_key'");
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn init(&self) -> Result<(), String> {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn terminate(&self) {}
 | 
			
		||||
 | 
			
		||||
    fn keyring_name(&self) -> String {
 | 
			
		||||
        let c = self.config.get();
 | 
			
		||||
        if c.namespace.is_empty() {
 | 
			
		||||
            "veilid_protected_store".to_owned()
 | 
			
		||||
        } else {
 | 
			
		||||
            format!("veilid_protected_store_{}", c.namespace)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn browser_key_name(&self, key: &str) -> String {
 | 
			
		||||
        let c = self.config.get();
 | 
			
		||||
        if c.namespace.is_empty() {
 | 
			
		||||
            format!("__veilid_protected_store_{}", key)
 | 
			
		||||
        } else {
 | 
			
		||||
            format!("__veilid_protected_store_{}_{}", c.namespace, key)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn save_user_secret_string(&self, key: &str, value: &str) -> Result<bool, String> {
 | 
			
		||||
        if utils::is_nodejs() {
 | 
			
		||||
            let prev = match JsFuture::from(
 | 
			
		||||
                keytar_getPassword(self.keyring_name().as_str(), key)
 | 
			
		||||
                    .map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            {
 | 
			
		||||
                Ok(v) => v.is_truthy(),
 | 
			
		||||
                Err(_) => false,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            match JsFuture::from(
 | 
			
		||||
                keytar_setPassword(self.keyring_name().as_str(), key, value)
 | 
			
		||||
                    .map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            {
 | 
			
		||||
                Ok(_) => {}
 | 
			
		||||
                Err(_) => return Err("Failed to set password".to_owned()),
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Ok(prev)
 | 
			
		||||
        } else if utils::is_browser() {
 | 
			
		||||
            let win = match window() {
 | 
			
		||||
                Some(w) => w,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Err("failed to get window".to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let ls = match win
 | 
			
		||||
                .local_storage()
 | 
			
		||||
                .map_err(|_| "exception getting local storage".to_owned())?
 | 
			
		||||
            {
 | 
			
		||||
                Some(l) => l,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Err("failed to get local storage".to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let vkey = self.browser_key_name(key);
 | 
			
		||||
 | 
			
		||||
            let prev = match ls
 | 
			
		||||
                .get_item(&vkey)
 | 
			
		||||
                .map_err(|_| "exception_thrown".to_owned())?
 | 
			
		||||
            {
 | 
			
		||||
                Some(_) => true,
 | 
			
		||||
                None => false,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            ls.set_item(&vkey, value)
 | 
			
		||||
                .map_err(|_| "exception_thrown".to_owned())?;
 | 
			
		||||
 | 
			
		||||
            Ok(prev)
 | 
			
		||||
        } else {
 | 
			
		||||
            Err("unimplemented".to_owned())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn load_user_secret_string(&self, key: &str) -> Result<Option<String>, String> {
 | 
			
		||||
        if utils::is_nodejs() {
 | 
			
		||||
            let prev = match JsFuture::from(
 | 
			
		||||
                keytar_getPassword(self.keyring_name().as_str(), key)
 | 
			
		||||
                    .map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            {
 | 
			
		||||
                Ok(p) => p,
 | 
			
		||||
                Err(_) => JsValue::UNDEFINED,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            if prev.is_undefined() || prev.is_null() {
 | 
			
		||||
                return Ok(None);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Ok(prev.as_string())
 | 
			
		||||
        } else if utils::is_browser() {
 | 
			
		||||
            let win = match window() {
 | 
			
		||||
                Some(w) => w,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Err("failed to get window".to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let ls = match win
 | 
			
		||||
                .local_storage()
 | 
			
		||||
                .map_err(|_| "exception getting local storage".to_owned())?
 | 
			
		||||
            {
 | 
			
		||||
                Some(l) => l,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Err("failed to get local storage".to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let vkey = self.browser_key_name(key);
 | 
			
		||||
 | 
			
		||||
            ls.get_item(&vkey)
 | 
			
		||||
                .map_err(|_| "exception_thrown".to_owned())
 | 
			
		||||
        } else {
 | 
			
		||||
            Err("unimplemented".to_owned())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn remove_user_secret_string(&self, key: &str) -> Result<bool, String> {
 | 
			
		||||
        if utils::is_nodejs() {
 | 
			
		||||
            match JsFuture::from(
 | 
			
		||||
                keytar_deletePassword(self.keyring_name().as_str(), key).map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            {
 | 
			
		||||
                Ok(v) => Ok(v.is_truthy()),
 | 
			
		||||
                Err(_) => Err("Failed to delete".to_owned()),
 | 
			
		||||
            }
 | 
			
		||||
        } else if utils::is_browser() {
 | 
			
		||||
            let win = match window() {
 | 
			
		||||
                Some(w) => w,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Err("failed to get window".to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let ls = match win
 | 
			
		||||
                .local_storage()
 | 
			
		||||
                .map_err(|_| "exception getting local storage".to_owned())?
 | 
			
		||||
            {
 | 
			
		||||
                Some(l) => l,
 | 
			
		||||
                None => {
 | 
			
		||||
                    return Err("failed to get local storage".to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            let vkey = self.browser_key_name(key);
 | 
			
		||||
 | 
			
		||||
            match ls
 | 
			
		||||
                .get_item(&vkey)
 | 
			
		||||
                .map_err(|_| "exception_thrown".to_owned())?
 | 
			
		||||
            {
 | 
			
		||||
                Some(_) => {
 | 
			
		||||
                    ls.delete(&vkey)
 | 
			
		||||
                        .map_err(|_| "exception_thrown".to_owned())?;
 | 
			
		||||
                    Ok(true)
 | 
			
		||||
                }
 | 
			
		||||
                None => Ok(false),
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            Err("unimplemented".to_owned())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    pub async fn save_user_secret(&self, key: &str, value: &[u8]) -> Result<bool, String> {
 | 
			
		||||
        let mut s = BASE64URL_NOPAD.encode(value);
 | 
			
		||||
        s.push('!');
 | 
			
		||||
 | 
			
		||||
        self.save_user_secret_string(key, s.as_str()).await
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn load_user_secret(&self, key: &str) -> Result<Option<Vec<u8>>, String> {
 | 
			
		||||
        let mut s = match self.load_user_secret_string(key).await? {
 | 
			
		||||
            Some(s) => s,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Ok(None);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        match JsFuture::from(
 | 
			
		||||
            keytar_setPassword(keyring_name(namespace).as_str(), key, value)
 | 
			
		||||
                .map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        {
 | 
			
		||||
            Ok(_) => {}
 | 
			
		||||
            Err(_) => return Err("Failed to set password".to_owned()),
 | 
			
		||||
        if s.pop() != Some('!') {
 | 
			
		||||
            return Err("User secret is not a buffer".to_owned());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(prev)
 | 
			
		||||
    } else if utils::is_browser() {
 | 
			
		||||
        let win = match window() {
 | 
			
		||||
            Some(w) => w,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Err("failed to get window".to_owned());
 | 
			
		||||
        let mut bytes = Vec::<u8>::new();
 | 
			
		||||
        let res = BASE64URL_NOPAD.decode_len(s.len());
 | 
			
		||||
        match res {
 | 
			
		||||
            Ok(l) => {
 | 
			
		||||
                bytes.resize(l, 0u8);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let ls = match win
 | 
			
		||||
            .local_storage()
 | 
			
		||||
            .map_err(|_| "exception getting local storage".to_owned())?
 | 
			
		||||
        {
 | 
			
		||||
            Some(l) => l,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Err("failed to get local storage".to_owned());
 | 
			
		||||
            Err(_) => {
 | 
			
		||||
                return Err("Failed to decode".to_owned());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let vkey = browser_key_name(namespace, key);
 | 
			
		||||
 | 
			
		||||
        let prev = match ls
 | 
			
		||||
            .get_item(&vkey)
 | 
			
		||||
            .map_err(|_| "exception_thrown".to_owned())?
 | 
			
		||||
        {
 | 
			
		||||
            Some(_) => true,
 | 
			
		||||
            None => false,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        ls.set_item(&vkey, value)
 | 
			
		||||
            .map_err(|_| "exception_thrown".to_owned())?;
 | 
			
		||||
 | 
			
		||||
        Ok(prev)
 | 
			
		||||
    } else {
 | 
			
		||||
        Err("unimplemented".to_owned())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn load_user_secret_string(namespace: &str, key: &str) -> Result<Option<String>, String> {
 | 
			
		||||
    if utils::is_nodejs() {
 | 
			
		||||
        let prev = match JsFuture::from(
 | 
			
		||||
            keytar_getPassword(keyring_name(namespace).as_str(), key)
 | 
			
		||||
                .map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        {
 | 
			
		||||
            Ok(p) => p,
 | 
			
		||||
            Err(_) => JsValue::UNDEFINED,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if prev.is_undefined() || prev.is_null() {
 | 
			
		||||
            return Ok(None);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Ok(prev.as_string())
 | 
			
		||||
    } else if utils::is_browser() {
 | 
			
		||||
        let win = match window() {
 | 
			
		||||
            Some(w) => w,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Err("failed to get window".to_owned());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let ls = match win
 | 
			
		||||
            .local_storage()
 | 
			
		||||
            .map_err(|_| "exception getting local storage".to_owned())?
 | 
			
		||||
        {
 | 
			
		||||
            Some(l) => l,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Err("failed to get local storage".to_owned());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let vkey = browser_key_name(namespace, key);
 | 
			
		||||
 | 
			
		||||
        ls.get_item(&vkey)
 | 
			
		||||
            .map_err(|_| "exception_thrown".to_owned())
 | 
			
		||||
    } else {
 | 
			
		||||
        Err("unimplemented".to_owned())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn remove_user_secret_string(namespace: &str, key: &str) -> Result<bool, String> {
 | 
			
		||||
    if utils::is_nodejs() {
 | 
			
		||||
        match JsFuture::from(
 | 
			
		||||
            keytar_deletePassword("veilid", key).map_err(|_| "exception thrown".to_owned())?,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        {
 | 
			
		||||
            Ok(v) => Ok(v.is_truthy()),
 | 
			
		||||
            Err(_) => Err("Failed to delete".to_owned()),
 | 
			
		||||
        let res = BASE64URL_NOPAD.decode_mut(s.as_bytes(), &mut bytes);
 | 
			
		||||
        match res {
 | 
			
		||||
            Ok(_) => Ok(Some(bytes)),
 | 
			
		||||
            Err(_) => Err("Failed to decode".to_owned()),
 | 
			
		||||
        }
 | 
			
		||||
    } else if utils::is_browser() {
 | 
			
		||||
        let win = match window() {
 | 
			
		||||
            Some(w) => w,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Err("failed to get window".to_owned());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let ls = match win
 | 
			
		||||
            .local_storage()
 | 
			
		||||
            .map_err(|_| "exception getting local storage".to_owned())?
 | 
			
		||||
        {
 | 
			
		||||
            Some(l) => l,
 | 
			
		||||
            None => {
 | 
			
		||||
                return Err("failed to get local storage".to_owned());
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let vkey = browser_key_name(namespace, key);
 | 
			
		||||
 | 
			
		||||
        match ls
 | 
			
		||||
            .get_item(&vkey)
 | 
			
		||||
            .map_err(|_| "exception_thrown".to_owned())?
 | 
			
		||||
        {
 | 
			
		||||
            Some(_) => {
 | 
			
		||||
                ls.delete(&vkey)
 | 
			
		||||
                    .map_err(|_| "exception_thrown".to_owned())?;
 | 
			
		||||
                Ok(true)
 | 
			
		||||
            }
 | 
			
		||||
            None => Ok(false),
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        Err("unimplemented".to_owned())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    pub async fn remove_user_secret(&self, key: &str) -> Result<bool, String> {
 | 
			
		||||
        self.remove_user_secret_string(key).await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -54,7 +54,7 @@ impl TableStore {
 | 
			
		||||
        {
 | 
			
		||||
            return Err(format!("table name '{}' is invalid", table));
 | 
			
		||||
        }
 | 
			
		||||
        let c = inner.config.get();
 | 
			
		||||
        let c = self.config.get();
 | 
			
		||||
        let namespace = c.namespace.clone();
 | 
			
		||||
        Ok(if namespace.len() == 0 {
 | 
			
		||||
            format!("{}", table)
 | 
			
		||||
 
 | 
			
		||||
@@ -64,7 +64,13 @@ wFAbkZY9eS/x6P7qrpd7dUA=
 | 
			
		||||
cfg_if! {
 | 
			
		||||
 | 
			
		||||
    if #[cfg(target_arch = "wasm32")] {
 | 
			
		||||
        pub fn get_tablestore_path() -> String {
 | 
			
		||||
        pub fn get_table_store_path() -> String {
 | 
			
		||||
            String::new()
 | 
			
		||||
        }
 | 
			
		||||
        pub fn get_block_store_path() -> String {
 | 
			
		||||
            String::new()
 | 
			
		||||
        }
 | 
			
		||||
        pub fn get_protected_store_path() -> String {
 | 
			
		||||
            String::new()
 | 
			
		||||
        }
 | 
			
		||||
        pub fn get_certfile_path() -> String {
 | 
			
		||||
@@ -103,6 +109,15 @@ cfg_if! {
 | 
			
		||||
            out.into_os_string().into_string().unwrap()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn get_block_store_path() -> String {
 | 
			
		||||
            let mut out = get_data_dir();
 | 
			
		||||
            std::fs::create_dir_all(&out).unwrap();
 | 
			
		||||
 | 
			
		||||
            out.push("block_store");
 | 
			
		||||
 | 
			
		||||
            out.into_os_string().into_string().unwrap()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pub fn get_protected_store_path() -> String {
 | 
			
		||||
            let mut out = get_data_dir();
 | 
			
		||||
            std::fs::create_dir_all(&out).unwrap();
 | 
			
		||||
@@ -156,7 +171,7 @@ pub fn setup_veilid_core() -> VeilidCoreSetup {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn config_callback(key: String) -> Result<Box<dyn core::any::Any>, String> {
 | 
			
		||||
pub fn config_callback(key: String) -> ConfigCallbackReturn {
 | 
			
		||||
    match key.as_str() {
 | 
			
		||||
        "program_name" => Ok(Box::new(String::from("Veilid"))),
 | 
			
		||||
        "namespace" => Ok(Box::new(String::from(""))),
 | 
			
		||||
@@ -168,9 +183,13 @@ pub fn config_callback(key: String) -> Result<Box<dyn core::any::Any>, String> {
 | 
			
		||||
        "capabilities.protocol_connect_wss" => Ok(Box::new(true)),
 | 
			
		||||
        "capabilities.protocol_accept_wss" => Ok(Box::new(true)),
 | 
			
		||||
        "table_store.directory" => Ok(Box::new(get_table_store_path())),
 | 
			
		||||
        "table_store.delete" => Ok(Box::new(false)),
 | 
			
		||||
        "block_store.directory" => Ok(Box::new(get_block_store_path())),
 | 
			
		||||
        "block_store.delete" => Ok(Box::new(false)),
 | 
			
		||||
        "protected_store.allow_insecure_fallback" => Ok(Box::new(true)),
 | 
			
		||||
        "protected_store.always_use_insecure_storage" => Ok(Box::new(false)),
 | 
			
		||||
        "protected_store.insecure_fallback_directory" => Ok(Box::new(get_protected_store_path())),
 | 
			
		||||
        "protected_store.delete" => Ok(Box::new(false)),
 | 
			
		||||
        "network.max_connections" => Ok(Box::new(16u32)),
 | 
			
		||||
        "network.connection_initial_timeout" => Ok(Box::new(2_000_000u64)),
 | 
			
		||||
        "network.node_id" => Ok(Box::new(dht::key::DHTKey::default())),
 | 
			
		||||
@@ -264,12 +283,16 @@ pub async fn test_config() {
 | 
			
		||||
    assert_eq!(inner.capabilities.protocol_connect_wss, true);
 | 
			
		||||
    assert_eq!(inner.capabilities.protocol_accept_wss, true);
 | 
			
		||||
    assert_eq!(inner.table_store.directory, get_table_store_path());
 | 
			
		||||
    assert_eq!(inner.table_store.delete, false);
 | 
			
		||||
    assert_eq!(inner.block_store.directory, get_block_store_path());
 | 
			
		||||
    assert_eq!(inner.block_store.delete, false);
 | 
			
		||||
    assert_eq!(inner.protected_store.allow_insecure_fallback, true);
 | 
			
		||||
    assert_eq!(inner.protected_store.always_use_insecure_storage, false);
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        inner.protected_store.insecure_fallback_directory,
 | 
			
		||||
        get_protected_store_path()
 | 
			
		||||
    );
 | 
			
		||||
    assert_eq!(inner.protected_store.delete, false);
 | 
			
		||||
    assert_eq!(inner.network.max_connections, 16);
 | 
			
		||||
    assert_eq!(inner.network.connection_initial_timeout, 2_000_000u64);
 | 
			
		||||
    assert!(!inner.network.node_id.valid);
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,12 @@ use crate::xx::*;
 | 
			
		||||
 | 
			
		||||
cfg_if! {
 | 
			
		||||
    if #[cfg(target_arch = "wasm32")] {
 | 
			
		||||
        pub type ConfigCallback = Arc<dyn Fn(String) -> Result<Box<dyn core::any::Any>, String>>;
 | 
			
		||||
        pub type ConfigCallbackReturn = Result<Box<dyn core::any::Any>, String>;
 | 
			
		||||
        pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn>;
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        pub type ConfigCallback = Arc<dyn Fn(String) -> Result<Box<dyn core::any::Any>, String> + Send>;
 | 
			
		||||
        pub type ConfigCallbackReturn = Result<Box<dyn core::any::Any + Send>, String>;
 | 
			
		||||
        pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send>;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user