Implement iPhone TOTP tab and Watch sharing
This commit is contained in:
@@ -19,6 +19,7 @@ use url::Url;
|
||||
use crate::authentication::{AuthenticationTimeout, DEFAULT_AUTHENTICATION_TIMEOUT};
|
||||
use crate::mobile::MobileTab;
|
||||
use crate::presentation::{ClipboardTimeout, DEFAULT_CLIPBOARD_TIMEOUT};
|
||||
use crate::repository::EntryPath;
|
||||
|
||||
const APPLICATION_DIRECTORY: &str = "ironstorage";
|
||||
const CONFIG_FILE: &str = "config.toml";
|
||||
@@ -38,6 +39,7 @@ pub struct Config {
|
||||
biometric_unlock_enabled: bool,
|
||||
mobile_tab: MobileTab,
|
||||
mobile_home_refreshed_at: Option<i64>,
|
||||
watch_shared_totp_entries: BTreeSet<EntryPath>,
|
||||
git_remotes: Vec<GitRemote>,
|
||||
}
|
||||
|
||||
@@ -135,6 +137,10 @@ impl Config {
|
||||
self.mobile_home_refreshed_at
|
||||
}
|
||||
|
||||
pub fn watch_shared_totp_entries(&self) -> &BTreeSet<EntryPath> {
|
||||
&self.watch_shared_totp_entries
|
||||
}
|
||||
|
||||
pub fn git_remotes(&self) -> &[GitRemote] {
|
||||
&self.git_remotes
|
||||
}
|
||||
@@ -154,7 +160,7 @@ impl Config {
|
||||
}
|
||||
|
||||
pub fn update_mobile_tab(&self, tab: MobileTab) -> Result<(), ConfigError> {
|
||||
let mut document = self.document.clone();
|
||||
let mut document = self.current_document()?;
|
||||
let root = document
|
||||
.as_table_mut()
|
||||
.ok_or_else(|| ConfigError::Malformed {
|
||||
@@ -178,13 +184,46 @@ impl Config {
|
||||
validate_config(self.source.clone(), document, raw)?.persist()
|
||||
}
|
||||
|
||||
pub fn update_watch_shared_totp_entries(
|
||||
&self,
|
||||
entries: &BTreeSet<EntryPath>,
|
||||
) -> Result<(), ConfigError> {
|
||||
let mut document = self.current_document()?;
|
||||
let root = document
|
||||
.as_table_mut()
|
||||
.ok_or_else(|| ConfigError::Malformed {
|
||||
path: self.source.clone(),
|
||||
})?;
|
||||
let ui = root
|
||||
.entry("ui")
|
||||
.or_insert_with(|| toml::Value::Table(toml::Table::new()))
|
||||
.as_table_mut()
|
||||
.ok_or(ConfigError::InvalidField { field: "ui" })?;
|
||||
ui.insert(
|
||||
"watch_shared_totp_entries".to_owned(),
|
||||
toml::Value::Array(
|
||||
entries
|
||||
.iter()
|
||||
.map(|entry| toml::Value::String(entry.to_string()))
|
||||
.collect(),
|
||||
),
|
||||
);
|
||||
let raw = document
|
||||
.clone()
|
||||
.try_into::<RawConfig>()
|
||||
.map_err(|_| ConfigError::Malformed {
|
||||
path: self.source.clone(),
|
||||
})?;
|
||||
validate_config(self.source.clone(), document, raw)?.persist()
|
||||
}
|
||||
|
||||
pub(crate) fn update_mobile_home_refresh(&self, unix_seconds: i64) -> Result<(), ConfigError> {
|
||||
if unix_seconds <= 0 {
|
||||
return Err(ConfigError::InvalidField {
|
||||
field: "ui.home_remote_refreshed_at_unix_seconds",
|
||||
});
|
||||
}
|
||||
let mut document = self.document.clone();
|
||||
let mut document = self.current_document()?;
|
||||
let root = document
|
||||
.as_table_mut()
|
||||
.ok_or_else(|| ConfigError::Malformed {
|
||||
@@ -209,7 +248,7 @@ impl Config {
|
||||
}
|
||||
|
||||
pub fn update_biometric_unlock(&self, enabled: bool) -> Result<(), ConfigError> {
|
||||
let mut document = self.document.clone();
|
||||
let mut document = self.current_document()?;
|
||||
let root = document
|
||||
.as_table_mut()
|
||||
.ok_or_else(|| ConfigError::Malformed {
|
||||
@@ -233,6 +272,10 @@ impl Config {
|
||||
validate_config(self.source.clone(), document, raw)?.persist()
|
||||
}
|
||||
|
||||
fn current_document(&self) -> Result<toml::Value, ConfigError> {
|
||||
Self::load(Some(&self.source)).map(|config| config.document)
|
||||
}
|
||||
|
||||
pub(crate) fn create_mobile_clone(
|
||||
source: PathBuf,
|
||||
vault: &Path,
|
||||
@@ -873,6 +916,8 @@ struct RawSecurity {
|
||||
struct RawUi {
|
||||
selected_mobile_tab: Option<String>,
|
||||
home_remote_refreshed_at_unix_seconds: Option<i64>,
|
||||
#[serde(default)]
|
||||
watch_shared_totp_entries: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -964,6 +1009,16 @@ fn validate_config(
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
let watch_shared_totp_entries = raw
|
||||
.ui
|
||||
.watch_shared_totp_entries
|
||||
.into_iter()
|
||||
.map(|entry| {
|
||||
EntryPath::parse(&entry).map_err(|_| ConfigError::InvalidField {
|
||||
field: "ui.watch_shared_totp_entries",
|
||||
})
|
||||
})
|
||||
.collect::<Result<BTreeSet<_>, _>>()?;
|
||||
let git_remotes = validate_remotes(raw.git.remotes)?;
|
||||
|
||||
Ok(Config {
|
||||
@@ -978,6 +1033,7 @@ fn validate_config(
|
||||
biometric_unlock_enabled,
|
||||
mobile_tab,
|
||||
mobile_home_refreshed_at,
|
||||
watch_shared_totp_entries,
|
||||
git_remotes,
|
||||
})
|
||||
}
|
||||
@@ -1162,6 +1218,7 @@ fn validate_known_fields(value: &toml::Value, source: &Path) -> Result<(), Confi
|
||||
&[
|
||||
"selected_mobile_tab",
|
||||
"home_remote_refreshed_at_unix_seconds",
|
||||
"watch_shared_totp_entries",
|
||||
],
|
||||
)?;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user