Add additive KDBX importer

This commit is contained in:
2026-08-11 09:04:48 +02:00
parent f84f7247d2
commit bf75465642
23 changed files with 1959 additions and 82 deletions

View File

@@ -32,6 +32,30 @@ pub async fn pick_qr_image() -> Result<Option<SecretBytes>, String> {
.transpose()
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
pub async fn pick_kdbx_file() -> Result<Option<PathBuf>, String> {
pick_file("Import KeePass Database", "KeePass database", &["kdbx"]).await
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
pub async fn pick_key_file() -> Result<Option<PathBuf>, String> {
pick_file("Select KeePass Key File", "Key file", &["key", "keyx"]).await
}
#[cfg(any(target_os = "macos", target_os = "windows"))]
async fn pick_file(
title: &str,
filter_name: &str,
extensions: &[&str],
) -> Result<Option<PathBuf>, String> {
Ok(rfd::AsyncFileDialog::new()
.set_title(title)
.add_filter(filter_name, extensions)
.pick_file()
.await
.map(|file| file.path().to_owned()))
}
#[cfg(target_os = "linux")]
pub async fn pick_folder(initial: Option<PathBuf>) -> Result<Option<PathBuf>, String> {
use ashpd::{
@@ -96,6 +120,45 @@ pub async fn pick_qr_image() -> Result<Option<SecretBytes>, String> {
.map_err(|error| error.to_string())
}
#[cfg(target_os = "linux")]
pub async fn pick_kdbx_file() -> Result<Option<PathBuf>, String> {
pick_file("Import KeePass Database", "Import").await
}
#[cfg(target_os = "linux")]
pub async fn pick_key_file() -> Result<Option<PathBuf>, String> {
pick_file("Select KeePass Key File", "Select").await
}
#[cfg(target_os = "linux")]
async fn pick_file(title: &str, accept_label: &str) -> Result<Option<PathBuf>, String> {
use ashpd::{
PortalError,
desktop::{file_chooser::SelectedFiles, request::ResponseError},
};
let response = SelectedFiles::open_file()
.title(title)
.accept_label(accept_label)
.modal(true)
.multiple(false)
.send()
.await
.and_then(|request| request.response());
let selected = match response {
Ok(selected) => selected,
Err(ashpd::Error::Response(ResponseError::Cancelled))
| Err(ashpd::Error::Portal(PortalError::Cancelled(_))) => return Ok(None),
Err(error) => return Err(error.to_string()),
};
selected
.uris()
.first()
.ok_or_else(|| "file portal returned no selection".to_owned())
.and_then(|uri| file_uri_path(uri.as_str()))
.map(Some)
}
#[cfg(target_os = "linux")]
fn file_uri_path(uri: &str) -> Result<PathBuf, String> {
let uri = url::Url::parse(uri).map_err(|_| "folder portal returned an invalid URI")?;