Cache TOTP discovery and report progress (#74)

This commit is contained in:
2026-08-11 23:15:23 +02:00
parent 6edcb5fc86
commit 9759162eff
12 changed files with 1577 additions and 198 deletions

View File

@@ -53,7 +53,9 @@ use ironstorage::{
MobilePasswordRowKind as StoragePasswordRowKind,
},
mobile_totp::{
MobileTotpDetail as StorageTotpDetail, MobileTotpPage as StorageTotpPage,
MobileTotpDetail as StorageTotpDetail,
MobileTotpDiscoveryPhase as StorageTotpDiscoveryPhase,
MobileTotpOperation as StorageTotpOperation, MobileTotpPage as StorageTotpPage,
MobileWatchSnapshotState as StorageWatchSnapshotState,
MobileWatchSnapshotStatus as StorageWatchSnapshotStatus,
},
@@ -812,6 +814,7 @@ pub struct MobileTotpRow {
pub struct MobileTotpPage {
pub rows: Vec<MobileTotpRow>,
pub unavailable_entries: u32,
pub cache_notice: Option<String>,
pub watch: MobileWatchSnapshotStatus,
}
@@ -831,11 +834,67 @@ impl From<StorageTotpPage> for MobileTotpPage {
})
.collect(),
unavailable_entries: page.unavailable_entries(),
cache_notice: page.cache_notice().map(str::to_owned),
watch: page.watch().into(),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, uniffi::Enum)]
pub enum MobileTotpDiscoveryPhase {
Preparing,
Inspecting,
Saving,
Complete,
Cancelled,
}
impl From<StorageTotpDiscoveryPhase> for MobileTotpDiscoveryPhase {
fn from(phase: StorageTotpDiscoveryPhase) -> Self {
match phase {
StorageTotpDiscoveryPhase::Preparing => Self::Preparing,
StorageTotpDiscoveryPhase::Inspecting => Self::Inspecting,
StorageTotpDiscoveryPhase::Saving => Self::Saving,
StorageTotpDiscoveryPhase::Complete => Self::Complete,
StorageTotpDiscoveryPhase::Cancelled => Self::Cancelled,
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct MobileTotpDiscoveryProgress {
pub phase: MobileTotpDiscoveryPhase,
pub total: u32,
pub inspected: u32,
pub cache_hits: u32,
pub matches: u32,
pub unavailable: u32,
}
#[derive(uniffi::Object)]
pub struct MobileTotpOperation {
operation: StorageTotpOperation,
}
#[uniffi::export]
impl MobileTotpOperation {
pub fn progress(&self) -> MobileTotpDiscoveryProgress {
let progress = self.operation.progress();
MobileTotpDiscoveryProgress {
phase: progress.phase().into(),
total: progress.total(),
inspected: progress.inspected(),
cache_hits: progress.cache_hits(),
matches: progress.matches(),
unavailable: progress.unavailable(),
}
}
pub fn cancel(&self) {
self.operation.cancel();
}
}
#[derive(Clone, uniffi::Record)]
pub struct MobileTotpDetail {
pub path: String,
@@ -1369,13 +1428,23 @@ impl MobileAuthentication {
.map_err(Into::into)
}
pub fn totp_page(&self) -> Result<MobileTotpPage, MobileAuthenticationFfiError> {
pub fn totp_page(
&self,
operation: Arc<MobileTotpOperation>,
) -> Result<MobileTotpPage, MobileAuthenticationFfiError> {
self.authentication
.totp_page()
.totp_page(&operation.operation)
.map(Into::into)
.map_err(Into::into)
}
pub fn cached_totp_page(&self) -> Result<Option<MobileTotpPage>, MobileAuthenticationFfiError> {
self.authentication
.cached_totp_page()
.map(|page| page.map(Into::into))
.map_err(Into::into)
}
pub fn totp_detail(
&self,
path: String,
@@ -1733,6 +1802,13 @@ pub fn mobile_home_operation() -> Arc<MobileHomeOperation> {
})
}
#[uniffi::export]
pub fn mobile_totp_operation() -> Arc<MobileTotpOperation> {
Arc::new(MobileTotpOperation {
operation: StorageTotpOperation::default(),
})
}
#[uniffi::export]
pub fn mobile_password_page(
path: Option<String>,