Skip to content

Commit

Permalink
fix encrypted search
Browse files Browse the repository at this point in the history
  • Loading branch information
0-don committed Feb 24, 2025
1 parent 038a215 commit 21d6a89
Show file tree
Hide file tree
Showing 9 changed files with 328 additions and 42 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clippy",
"version": "1.4.1",
"version": "1.4.2",
"description": "Clipboard Manager built with Rust & Typescript",
"license": "MIT",
"type": "module",
Expand Down
112 changes: 99 additions & 13 deletions src-tauri/Cargo.lock

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

5 changes: 4 additions & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "clippy"
version = "1.4.1"
version = "1.4.2"
description = "Clipboard Manager built with Rust & Typescript"
authors = ["0-don"]
license = "MIT"
Expand Down Expand Up @@ -73,6 +73,9 @@ http-body-util = "0"
# cipher
ring = "0"

# caching
moka = { version = "0", features = ["sync"] }

[profile.release]
# panic = "abort"
# codegen-units = 1
Expand Down
1 change: 1 addition & 0 deletions src-tauri/common/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub static GLOBAL_EVENTS: LazyLock<Vec<String>> = LazyLock::new(|| {
pub static DB_NAME: &str = "clippy.sqlite";
pub static CONFIG_NAME: &str = "config.json";
pub static TOKEN_NAME: &str = "token.json";
pub static CACHE_KEY: &str = "clipboards";

pub static BACKUP_SETTINGS_PREFIX: &str = "settings";
pub static BACKUP_FILE_PREFIX: &str = "clippy";
Expand Down
109 changes: 87 additions & 22 deletions src-tauri/src/commands/clipboard.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
use crate::service::cipher::is_encryption_key_set;
use crate::service::clipboard::init_clipboards;
use crate::service::clipboard::{filter_clipboards, get_all_clipboards_db, init_clipboards};
use crate::service::decrypt::decrypt_clipboard;
use crate::service::settings::get_global_settings;
use crate::tao::global::get_app;
use crate::tao::global::{get_app, get_cache};
use crate::{
service::clipboard::{
clear_clipboards_db, copy_clipboard_from_id, delete_clipboards_db, get_clipboard_count_db,
get_clipboard_db, get_clipboards_db, star_clipboard_db,
},
utils::hotkey_manager::unregister_hotkeys,
};
use common::constants::CACHE_KEY;
use common::io::clipboard::trim_clipboard_data;
use common::types::orm_query::FullClipboardDto;
use common::{
printlog,
types::{enums::ClipboardType, orm_query::ClipboardsResponse, types::CommandError},
Expand All @@ -26,30 +28,92 @@ pub async fn get_clipboards(
star: Option<bool>,
img: Option<bool>,
) -> Result<ClipboardsResponse, CommandError> {
let mut clipboards = get_clipboards_db(cursor, search, star, img).await?;
printlog!(
"Getting clipboards with cursor: {:?}, search: {:?}, star: {:?}, img: {:?}",
cursor,
search,
star,
img
);

let settings = get_global_settings();
let is_encrypted = settings.encryption && is_encryption_key_set();
let total = get_clipboard_count_db().await?;
let current_position = cursor.unwrap_or(0) + clipboards.len() as u64;
let has_more = current_position < total;

if get_global_settings().encryption && is_encryption_key_set() {
clipboards = clipboards
.into_iter()
.map(|clipboard| {
if clipboard.clipboard.encrypted {
match decrypt_clipboard(clipboard.clone()) {
Ok(decrypted) => decrypted,
Err(e) => {
// Log the error but return the original encrypted clipboard
printlog!("Failed to decrypt clipboard: {:?}", e);
clipboard
// Only use cache for encrypted clipboards WITH a search term
let clipboards = if is_encrypted && search.is_some() && !search.as_ref().unwrap().is_empty() {
// Get or populate the cache
let all_decrypted = if let Some(cached) = get_cache().get(CACHE_KEY) {
cached
} else {
// No cache hit, load and decrypt all clipboards
let all_clipboards = get_all_clipboards_db().await?;

// Decrypt all clipboards
let decrypted_clipboards: Vec<FullClipboardDto> = all_clipboards
.into_iter()
.map(|clipboard| {
if clipboard.clipboard.encrypted {
match decrypt_clipboard(clipboard.clone()) {
Ok(decrypted) => decrypted,
Err(e) => {
printlog!("Failed to decrypt clipboard: {:?}", e);
clipboard
}
}
} else {
clipboard
}
} else {
clipboard
}
})
.collect();
}
})
.collect();

// Cache all decrypted clipboards
get_cache().insert(CACHE_KEY.to_string(), decrypted_clipboards.clone());
decrypted_clipboards
};

// Apply filters in memory
let filtered = filter_clipboards(&all_decrypted, search.as_ref(), star, img, &settings);

// Apply pagination
let start = cursor.unwrap_or(0) as usize;
let end = (start + 25).min(filtered.len());

if start < filtered.len() {
filtered[start..end].to_vec()
} else {
Vec::new()
}
} else {
// For regular search (non-encrypted OR encrypted without search string)
// we use the standard database query
let clipboards_from_db = get_clipboards_db(cursor, search, star, img).await?;

// If encrypted, we still need to decrypt the results
if is_encrypted {
clipboards_from_db
.into_iter()
.map(|clipboard| {
if clipboard.clipboard.encrypted {
match decrypt_clipboard(clipboard.clone()) {
Ok(decrypted) => decrypted,
Err(e) => {
printlog!("Failed to decrypt clipboard: {:?}", e);
clipboard
}
}
} else {
clipboard
}
})
.collect()
} else {
clipboards_from_db
}
};

let current_position = cursor.unwrap_or(0) + clipboards.len() as u64;
let has_more = current_position < total;

printlog!(
"Total: {}, Current Position: {}, Has More: {}",
Expand All @@ -58,6 +122,7 @@ pub async fn get_clipboards(
has_more
);

// Note: The database search results are already trimmed in trim_clipboard_data
Ok(ClipboardsResponse {
clipboards: trim_clipboard_data(clipboards),
total,
Expand Down
Loading

0 comments on commit 21d6a89

Please sign in to comment.