use crate::sh; use serde::Deserialize; use std::io::{Error, ErrorKind}; const EXECUTABLE: &str = "bw"; #[derive(Deserialize, Clone)] pub struct Item { pub id: String, pub name: String, #[serde(rename = "passwordHistory")] pub password_history: Vec, #[serde(rename = "revisionDate")] pub revision_date: String, #[serde(rename = "creationDate")] pub creation_date: String, pub object: String, #[serde(rename = "type")] pub type_: u16, pub notes: Option, pub favorite: bool, pub fields: Vec, pub login: Login, } #[derive(Deserialize, Clone)] pub struct PasswordHistoryItem { #[serde(rename = "lastUsedDate")] pub last_used_date: String, pub password: String, } #[derive(Deserialize, Clone)] pub struct ItemField { pub name: String, pub value: String, #[serde(rename = "type")] pub type_: u16, } #[derive(Deserialize, Clone)] pub struct Login { pub uris: Vec, pub username: String, pub password: String, pub totp: Option, #[serde(rename = "passwordRevisionDate")] pub password_revision_date: Option, #[serde(rename = "fido2Credentials")] pub fido2_credentials: Vec, } #[derive(Deserialize, Clone)] pub struct LoginUri { pub uri: String, } #[derive(Deserialize, Clone)] pub struct Fido2Credential { #[serde(rename = "credentialId")] pub credential_id: String, #[serde(rename = "keyType")] pub key_type: String, #[serde(rename = "keyAlgorithm")] pub key_algorithm: String, #[serde(rename = "keyCurve")] pub key_curve: String, #[serde(rename = "keyValue")] pub key_value: String, #[serde(rename = "rpId")] pub rp_id: String, #[serde(rename = "userHandle")] pub user_handle: String, #[serde(rename = "userName")] pub user_name: String, pub counter: String, #[serde(rename = "rpName")] pub rp_name: String, #[serde(rename = "userDisplayName")] pub user_display_name: String, pub discoverable: String, #[serde(rename = "creationDate")] pub creation_date: String, } pub fn check_bw() -> Result { let which = sh::sh(format!("which {}", EXECUTABLE)); if which.is_empty() { return Err(Error::new( ErrorKind::Other, format!("{} is not installed", EXECUTABLE), )); } let session = sh::sh(format!("{} unlock", EXECUTABLE)); if session.is_empty() { return Err(Error::new( ErrorKind::Other, format!("{} couldn't unlock", EXECUTABLE), )); } Ok(session) } pub fn get_items(session: String) -> Result, Error> { let items_raw = sh::sh(format!("BW_SESSION={} {} list --raw", session, EXECUTABLE)); match serde_json::from_str(items_raw.as_str()) { Ok(val) => Ok(val), Err(e) => Err(Error::new( ErrorKind::Other, format!("Couldn't get items: {e}"), )), } }