Better keychain function descriptions

This commit is contained in:
Gregory Schier
2025-11-19 09:15:50 -08:00
parent 6863decd8e
commit 1fbf9e50c4
4 changed files with 74 additions and 20 deletions

View File

@@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow}; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow};
use ts_rs::TS; use ts_rs::TS;
use yaak_common::api_client::yaak_api_client; 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::query_manager::QueryManagerExt;
use yaak_models::util::UpdateSource; use yaak_models::util::UpdateSource;
@@ -108,7 +108,7 @@ impl YaakNotifier {
("installed", &launch_info.user_since.format("%Y-%m-%d").to_string()), ("installed", &launch_info.user_since.format("%Y-%m-%d").to_string()),
("license", &license_check), ("license", &license_check),
("updates", &get_updater_status(app_handle).to_string()), ("updates", &get_updater_status(app_handle).to_string()),
("platform", &get_os().to_string()), ("platform", &get_os_str().to_string()),
]); ]);
let resp = req.send().await?; let resp = req.send().await?;
if resp.status() != 200 { if resp.status() != 200 {

View File

@@ -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") { if cfg!(target_os = "windows") {
"windows" Windows
} else if cfg!(target_os = "macos") { } else if cfg!(target_os = "macos") {
"macos" MacOS
} else if cfg!(target_os = "linux") { } else if cfg!(target_os = "linux") {
"linux" Linux
} else { } 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" "ARM64"
} else { } else {
"Unknown" "Unknown"
}} }
}

View File

@@ -8,7 +8,7 @@ use std::time::Duration;
use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow, is_dev}; use tauri::{AppHandle, Emitter, Manager, Runtime, WebviewWindow, is_dev};
use ts_rs::TS; use ts_rs::TS;
use yaak_common::api_client::yaak_api_client; 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::query_manager::QueryManagerExt;
use yaak_models::util::UpdateSource; use yaak_models::util::UpdateSource;
@@ -71,7 +71,7 @@ pub async fn activate_license<R: Runtime>(
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let payload = ActivateLicenseRequestPayload { let payload = ActivateLicenseRequestPayload {
license_key: license_key.to_string(), 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(), app_version: window.app_handle().package_info().version.to_string(),
}; };
let response = client.post(build_url("/licenses/activate")).json(&payload).send().await?; let response = client.post(build_url("/licenses/activate")).json(&payload).send().await?;
@@ -111,7 +111,7 @@ pub async fn deactivate_license<R: Runtime>(window: &WebviewWindow<R>) -> Result
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let path = format!("/licenses/activations/{}/deactivate", activation_id); let path = format!("/licenses/activations/{}/deactivate", activation_id);
let payload = DeactivateLicenseRequestPayload { 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(), app_version: window.app_handle().package_info().version.to_string(),
}; };
let response = client.post(build_url(&path)).json(&payload).send().await?; let response = client.post(build_url(&path)).json(&payload).send().await?;
@@ -153,7 +153,7 @@ pub enum LicenseCheckStatus {
pub async fn check_license<R: Runtime>(window: &WebviewWindow<R>) -> Result<LicenseCheckStatus> { pub async fn check_license<R: Runtime>(window: &WebviewWindow<R>) -> Result<LicenseCheckStatus> {
let payload = CheckActivationRequestPayload { let payload = CheckActivationRequestPayload {
app_platform: get_os().to_string(), app_platform: get_os_str().to_string(),
app_version: window.package_info().version.to_string(), app_version: window.package_info().version.to_string(),
}; };
let activation_id = get_activation_id(window.app_handle()).await; let activation_id = get_activation_id(window.app_handle()).await;

View File

@@ -1,18 +1,20 @@
use crate::events::{ use crate::events::{
FormInput, FormInputBase, FormInputText, PluginContext, RenderPurpose, TemplateFunction, Color, FormInput, FormInputBanner, FormInputBase, FormInputMarkdown, FormInputText,
TemplateFunctionArg, TemplateFunctionPreviewType, PluginContext, RenderPurpose, TemplateFunction, TemplateFunctionArg,
TemplateFunctionPreviewType,
}; };
use crate::template_callback::PluginTemplateCallback; use crate::template_callback::PluginTemplateCallback;
use base64::Engine;
use base64::prelude::BASE64_STANDARD; use base64::prelude::BASE64_STANDARD;
use base64::Engine;
use keyring::Error::NoEntry; use keyring::Error::NoEntry;
use log::{debug, info}; use log::{debug, info};
use std::collections::HashMap; use std::collections::HashMap;
use tauri::{AppHandle, Runtime}; use tauri::{AppHandle, Runtime};
use yaak_common::platform::{get_os, OperatingSystem};
use yaak_crypto::manager::EncryptionManagerExt; use yaak_crypto::manager::EncryptionManagerExt;
use yaak_templates::error::Error::RenderError; use yaak_templates::error::Error::RenderError;
use yaak_templates::error::Result; 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 { pub(crate) fn template_function_secure() -> TemplateFunction {
TemplateFunction { TemplateFunction {
@@ -36,16 +38,49 @@ pub(crate) fn template_function_secure() -> TemplateFunction {
} }
pub(crate) fn template_function_keyring() -> 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 { TemplateFunction {
name: "keychain".to_string(), name: "keychain".to_string(),
preview_type: Some(TemplateFunctionPreviewType::Live), 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()]), aliases: Some(vec!["keyring".to_string()]),
args: vec![ 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 { TemplateFunctionArg::FormInput(FormInput::Text(FormInputText {
base: FormInputBase { base: FormInputBase {
name: "service".to_string(), name: "service".to_string(),
label: Some("Service".to_string()), label: Some(meta.service_label),
description: Some("App or URL for the password".to_string()), description: Some("App or URL for the password".to_string()),
..Default::default() ..Default::default()
}, },
@@ -54,7 +89,7 @@ pub(crate) fn template_function_keyring() -> TemplateFunction {
TemplateFunctionArg::FormInput(FormInput::Text(FormInputText { TemplateFunctionArg::FormInput(FormInput::Text(FormInputText {
base: FormInputBase { base: FormInputBase {
name: "account".to_string(), name: "account".to_string(),
label: Some("Account".to_string()), label: Some(meta.account_label),
description: Some("Username or email address".to_string()), description: Some("Username or email address".to_string()),
..Default::default() ..Default::default()
}, },
@@ -191,7 +226,7 @@ pub fn encrypt_secure_template_function<R: Runtime>(
tokens, tokens,
&PluginTemplateCallback::new(app_handle, plugin_context, RenderPurpose::Preview), &PluginTemplateCallback::new(app_handle, plugin_context, RenderPurpose::Preview),
)? )?
.to_string()) .to_string())
} }
pub fn template_function_keychain_run(args: HashMap<String, serde_json::Value>) -> Result<String> { pub fn template_function_keychain_run(args: HashMap<String, serde_json::Value>) -> Result<String> {