Add cached TOTP search (#77)

This commit is contained in:
2026-08-12 20:36:03 +02:00
parent 1ce7b7814b
commit 87f9e7be98
7 changed files with 156 additions and 7 deletions

View File

@@ -1494,6 +1494,16 @@ impl MobileAuthentication {
.map_err(Into::into)
}
pub fn search_cached_totp_page(
&self,
query: String,
) -> Result<Option<MobileTotpPage>, MobileAuthenticationFfiError> {
self.authentication
.search_cached_totp_page(&query)
.map(|page| page.map(Into::into))
.map_err(Into::into)
}
pub fn totp_detail(
&self,
path: String,

View File

@@ -587,9 +587,22 @@ impl MobileAuthentication {
}
pub fn cached_totp_page(&self) -> Result<Option<MobileTotpPage>, MobileAuthenticationError> {
self.search_cached_totp_page("")
}
pub fn search_cached_totp_page(
&self,
query: &str,
) -> Result<Option<MobileTotpPage>, MobileAuthenticationError> {
let shared = self.status()?.watch_shared_totp_entries.clone();
let cache_path = self.config.source().with_file_name("totp-catalog.toml");
Ok(MobileTotpService::new(&self.repository, &self.keys).cached_page(&shared, &cache_path))
Ok(
MobileTotpService::new(&self.repository, &self.keys).search_cached_page(
&shared,
&cache_path,
query,
),
)
}
pub fn totp_detail(

View File

@@ -423,14 +423,25 @@ impl<'a> MobileTotpService<'a> {
&self,
shared: &BTreeSet<EntryPath>,
cache_path: &Path,
) -> Option<MobileTotpPage> {
self.search_cached_page(shared, cache_path, "")
}
pub fn search_cached_page(
&self,
shared: &BTreeSet<EntryPath>,
cache_path: &Path,
query: &str,
) -> Option<MobileTotpPage> {
let store = store_identity(self.repository.root_path(), cache_path);
let (catalog, _) = load_cache(cache_path, &store);
let query = query.trim().to_lowercase();
let mut rows: Vec<_> = catalog?
.entries
.into_iter()
.filter(|(_, record)| record.is_totp)
.filter_map(|(path, _)| EntryPath::parse(&path).ok())
.filter(|path| query.is_empty() || path.to_string().to_lowercase().contains(&query))
.map(|path| cached_row(&path, shared.contains(&path)))
.collect();
sort_rows(&mut rows);

View File

@@ -233,6 +233,23 @@ fn totp_cache_reuses_ciphertext_hashes_and_removes_deleted_entries() -> TestResu
.rows(),
page.rows()
);
assert_eq!(
service
.search_cached_page(&BTreeSet::new(), &cache, " TEAM-A ")
.expect("created cache")
.rows()
.iter()
.map(|row| row.path())
.collect::<Vec<_>>(),
["team-a/shared", "team-a"]
);
assert!(
service
.search_cached_page(&BTreeSet::new(), &cache, "missing")
.expect("created cache")
.rows()
.is_empty()
);
write_plaintext(
&repository,