Skip to content

Commit

Permalink
Support JSON path queries in copy_clipboard().
Browse files Browse the repository at this point in the history
  • Loading branch information
tmpfs committed Dec 10, 2024
1 parent 0e1211e commit d62c232
Show file tree
Hide file tree
Showing 10 changed files with 99 additions and 7 deletions.
57 changes: 57 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ colored = "2"
arboard = { version = "3", default-features = false }
zeroize = "1"
bytes = "1.8"
serde_json_path = "0.7"

axum-server = { version = "0.7", features = ["tls-rustls-no-provider"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"] }
Expand Down
3 changes: 2 additions & 1 deletion crates/ipc/src/integration/linked_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1036,9 +1036,10 @@ impl Account for LinkedAccount {
&self,
clipboard: &xclipboard::Clipboard,
target: &SecretPath,
path: Option<&sos_sdk::json_path::JsonPath>,
) -> Result<bool> {
let account = self.account.lock().await;
Ok(account.copy_clipboard(clipboard, target).await?)
Ok(account.copy_clipboard(clipboard, target, path).await?)
}
}

Expand Down
7 changes: 6 additions & 1 deletion crates/ipc/src/web_service/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ where
return status(StatusCode::BAD_REQUEST);
};

let path = None;

let accounts = accounts.read().await;
match accounts.copy_clipboard(&account_id, &request).await {
match accounts
.copy_clipboard(&account_id, &request, path.as_ref())
.await
{
Ok(result) => json(StatusCode::OK, &result),
Err(e) => {
tracing::error!(error = %e, "copy_clipboard");
Expand Down
3 changes: 2 additions & 1 deletion crates/net/src/account/network_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1823,8 +1823,9 @@ impl Account for NetworkAccount {
&self,
clipboard: &xclipboard::Clipboard,
target: &SecretPath,
path: Option<&sos_sdk::json_path::JsonPath>,
) -> Result<bool> {
let account = self.account.lock().await;
Ok(account.copy_clipboard(clipboard, target).await?)
Ok(account.copy_clipboard(clipboard, target, path).await?)
}
}
3 changes: 2 additions & 1 deletion crates/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ default = ["account", "audit", "logs"]
account = []
archive = ["dep:async_zip"]
audit = []
clipboard = ["dep:xclipboard"]
clipboard = ["dep:xclipboard", "dep:serde_json_path"]
contacts = []
files = []
interactive-keychain-tests = []
Expand Down Expand Up @@ -63,6 +63,7 @@ rs_merkle.workspace = true
typeshare.workspace = true
sos-vfs.workspace = true
xclipboard = { workspace = true, optional = true }
serde_json_path = { workspace = true, optional = true }

subtle = { version = "2.5" }
ethereum-types = "0.15"
Expand Down
14 changes: 13 additions & 1 deletion crates/sdk/src/account/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ pub trait Account {
&self,
clipboard: &xclipboard::Clipboard,
target: &SecretPath,
path: Option<&serde_json_path::JsonPath>,
) -> std::result::Result<bool, Self::Error>;
}

Expand Down Expand Up @@ -3417,7 +3418,9 @@ impl Account for LocalAccount {
&self,
clipboard: &xclipboard::Clipboard,
target: &SecretPath,
path: Option<&serde_json_path::JsonPath>,
) -> Result<bool> {
use serde_json::Value;
let target_folder = self.find(|f| f.id() == target.folder_id()).await;
if let Some(folder) = target_folder {
let current_folder = self.current_folder().await?;
Expand All @@ -3427,7 +3430,16 @@ impl Account for LocalAccount {
self.open_folder(current).await?;
}
let secret = data.secret();
let text = secret.copy_value_unsafe().unwrap_or_default();
let text = if let Some(path) = path {
let value: Value = serde_json::to_value(&secret)?;
let node = path.query(&value).exactly_one()?;
match node {
Value::String(s) => s.to_string(),
_ => return Err(Error::InvalidJsonPathType),
}
} else {
secret.copy_value_unsafe().unwrap_or_default()
};
clipboard
.set_text_timeout(text)
.await
Expand Down
3 changes: 2 additions & 1 deletion crates/sdk/src/account/account_switcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,15 @@ where
&self,
account_id: &Address,
target: &SecretPath,
path: Option<&serde_json_path::JsonPath>,
) -> std::result::Result<bool, E> {
let Some(clipboard) = self.clipboard.clone() else {
return Err(Error::NoClipboard.into());
};

let account = self.iter().find(|a| a.address() == account_id);
if let Some(account) = account {
account.copy_clipboard(&clipboard, target).await
account.copy_clipboard(&clipboard, target, path).await
} else {
Ok(false)
}
Expand Down
10 changes: 10 additions & 0 deletions crates/sdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,16 @@ pub enum Error {
#[cfg(feature = "clipboard")]
#[error(transparent)]
Clipboard(#[from] xclipboard::Error),

/// Error generated by the JSON path library.
#[cfg(feature = "clipboard")]
#[error(transparent)]
JsonPath(#[from] serde_json_path::ExactlyOneError),

/// Error generated matching a JSON path when a string node is expected.
#[cfg(feature = "clipboard")]
#[error("invalid type in JSON path match, must be a string node")]
InvalidJsonPathType,
}

/// Extension functions for error types.
Expand Down
5 changes: 4 additions & 1 deletion crates/sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,12 @@ pub use url;
pub use urn;
pub use uuid;
pub use vcard4;
pub use zxcvbn;

#[cfg(feature = "clipboard")]
pub use serde_json_path as json_path;
#[cfg(feature = "clipboard")]
pub use xclipboard;
pub use zxcvbn;

/// Result type for the core library.
pub type Result<T> = std::result::Result<T, Error>;

0 comments on commit d62c232

Please sign in to comment.