diff --git a/src-tauri/src/notifications.rs b/src-tauri/src/notifications.rs index 4991f5c0..043c9a02 100644 --- a/src-tauri/src/notifications.rs +++ b/src-tauri/src/notifications.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; use ts_rs::TS; use yaak_common::api_client::yaak_api_client; -use yaak_common::platform::get_os; +use yaak_common::platform::get_os_str; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; @@ -108,7 +108,7 @@ impl YaakNotifier { ("installed", &launch_info.user_since.format("%Y-%m-%d").to_string()), ("license", &license_check), ("updates", &get_updater_status(app_handle).to_string()), - ("platform", &get_os().to_string()), + ("platform", &get_os_str().to_string()), ]); let resp = req.send().await?; if resp.status() != 200 { diff --git a/src-tauri/yaak-common/src/platform.rs b/src-tauri/yaak-common/src/platform.rs index 0424e5bf..4888d176 100644 --- a/src-tauri/yaak-common/src/platform.rs +++ b/src-tauri/yaak-common/src/platform.rs @@ -1,12 +1,30 @@ -pub fn get_os() -> &'static str { +use crate::platform::OperatingSystem::{Linux, MacOS, Unknown, Windows}; + +pub enum OperatingSystem { + Windows, + MacOS, + Linux, + Unknown, +} + +pub fn get_os() -> OperatingSystem { if cfg!(target_os = "windows") { - "windows" + Windows } else if cfg!(target_os = "macos") { - "macos" + MacOS } else if cfg!(target_os = "linux") { - "linux" + Linux } else { - "unknown" + Unknown + } +} + +pub fn get_os_str() -> &'static str { + match get_os() { + Windows => "windows", + MacOS => "macos", + Linux => "linux", + Unknown => "unknown", } } @@ -33,4 +51,5 @@ pub fn get_ua_arch() -> &'static str { "ARM64" } else { "Unknown" - }} + } +} diff --git a/src-tauri/yaak-license/src/license.rs b/src-tauri/yaak-license/src/license.rs index bd417b52..8b5943a4 100644 --- a/src-tauri/yaak-license/src/license.rs +++ b/src-tauri/yaak-license/src/license.rs @@ -8,7 +8,7 @@ use std::time::Duration; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow, is_dev}; use ts_rs::TS; use yaak_common::api_client::yaak_api_client; -use yaak_common::platform::get_os; +use yaak_common::platform::get_os_str; use yaak_models::query_manager::QueryManagerExt; use yaak_models::util::UpdateSource; @@ -71,7 +71,7 @@ pub async fn activate_license( let client = reqwest::Client::new(); let payload = ActivateLicenseRequestPayload { license_key: license_key.to_string(), - app_platform: get_os().to_string(), + app_platform: get_os_str().to_string(), app_version: window.app_handle().package_info().version.to_string(), }; let response = client.post(build_url("/licenses/activate")).json(&payload).send().await?; @@ -111,7 +111,7 @@ pub async fn deactivate_license(window: &WebviewWindow) -> Result let client = reqwest::Client::new(); let path = format!("/licenses/activations/{}/deactivate", activation_id); let payload = DeactivateLicenseRequestPayload { - app_platform: get_os().to_string(), + app_platform: get_os_str().to_string(), app_version: window.app_handle().package_info().version.to_string(), }; let response = client.post(build_url(&path)).json(&payload).send().await?; @@ -153,7 +153,7 @@ pub enum LicenseCheckStatus { pub async fn check_license(window: &WebviewWindow) -> Result { let payload = CheckActivationRequestPayload { - app_platform: get_os().to_string(), + app_platform: get_os_str().to_string(), app_version: window.package_info().version.to_string(), }; let activation_id = get_activation_id(window.app_handle()).await; diff --git a/src-tauri/yaak-plugins/src/native_template_functions.rs b/src-tauri/yaak-plugins/src/native_template_functions.rs index ff393ab4..9f05d700 100644 --- a/src-tauri/yaak-plugins/src/native_template_functions.rs +++ b/src-tauri/yaak-plugins/src/native_template_functions.rs @@ -1,18 +1,20 @@ use crate::events::{ - FormInput, FormInputBase, FormInputText, PluginContext, RenderPurpose, TemplateFunction, - TemplateFunctionArg, TemplateFunctionPreviewType, + Color, FormInput, FormInputBanner, FormInputBase, FormInputMarkdown, FormInputText, + PluginContext, RenderPurpose, TemplateFunction, TemplateFunctionArg, + TemplateFunctionPreviewType, }; use crate::template_callback::PluginTemplateCallback; -use base64::Engine; use base64::prelude::BASE64_STANDARD; +use base64::Engine; use keyring::Error::NoEntry; use log::{debug, info}; use std::collections::HashMap; use tauri::{AppHandle, Runtime}; +use yaak_common::platform::{get_os, OperatingSystem}; use yaak_crypto::manager::EncryptionManagerExt; use yaak_templates::error::Error::RenderError; use yaak_templates::error::Result; -use yaak_templates::{FnArg, Parser, Token, Tokens, Val, transform_args}; +use yaak_templates::{transform_args, FnArg, Parser, Token, Tokens, Val}; pub(crate) fn template_function_secure() -> TemplateFunction { TemplateFunction { @@ -36,16 +38,49 @@ pub(crate) fn template_function_secure() -> TemplateFunction { } pub(crate) fn template_function_keyring() -> TemplateFunction { + struct Meta { + description: String, + service_label: String, + account_label: String, + } + + let meta = match get_os() { + OperatingSystem::MacOS => Meta { + description: + "Access application passwords from the macOS Login keychain".to_string(), + service_label: "Where".to_string(), + account_label: "Account".to_string(), + }, + OperatingSystem::Windows => Meta { + description: "Access a secret via Windows Credential Manager".to_string(), + service_label: "Target".to_string(), + account_label: "Username".to_string(), + }, + _ => Meta { + description: "Access a secret via [Secret Service](https://specifications.freedesktop.org/secret-service/latest/) (eg. Gnome keyring or KWallet)".to_string(), + service_label: "Collection".to_string(), + account_label: "Account".to_string(), + }, + }; + TemplateFunction { name: "keychain".to_string(), preview_type: Some(TemplateFunctionPreviewType::Live), - description: Some("Get a password from the OS keychain or keyring".to_string()), + description: Some(meta.description), aliases: Some(vec!["keyring".to_string()]), args: vec![ + TemplateFunctionArg::FormInput(FormInput::Banner(FormInputBanner { + inputs: Some(vec![FormInput::Markdown(FormInputMarkdown { + content: "For most cases, prefer the [`secure(…)`](https://yaak.app/help/encryption) template function, which encrypts values using a key stored in keychain".to_string(), + hidden: None, + })]), + color: Some(Color::Info), + hidden: None, + })), TemplateFunctionArg::FormInput(FormInput::Text(FormInputText { base: FormInputBase { name: "service".to_string(), - label: Some("Service".to_string()), + label: Some(meta.service_label), description: Some("App or URL for the password".to_string()), ..Default::default() }, @@ -54,7 +89,7 @@ pub(crate) fn template_function_keyring() -> TemplateFunction { TemplateFunctionArg::FormInput(FormInput::Text(FormInputText { base: FormInputBase { name: "account".to_string(), - label: Some("Account".to_string()), + label: Some(meta.account_label), description: Some("Username or email address".to_string()), ..Default::default() }, @@ -191,7 +226,7 @@ pub fn encrypt_secure_template_function( tokens, &PluginTemplateCallback::new(app_handle, plugin_context, RenderPurpose::Preview), )? - .to_string()) + .to_string()) } pub fn template_function_keychain_run(args: HashMap) -> Result {