Synchronize selected TOTP entries to Apple Watch (#55)

This commit is contained in:
2026-08-16 13:47:31 +02:00
parent affdb55519
commit a055c93b86
12 changed files with 1888 additions and 98 deletions

View File

@@ -59,8 +59,11 @@ use ironstorage::{
MobileTotpDetail as StorageTotpDetail,
MobileTotpDiscoveryPhase as StorageTotpDiscoveryPhase,
MobileTotpOperation as StorageTotpOperation, MobileTotpPage as StorageTotpPage,
},
mobile_watch::{
MobileWatchSnapshotState as StorageWatchSnapshotState,
MobileWatchSnapshotStatus as StorageWatchSnapshotStatus,
WatchSnapshotTransfer as StorageWatchSnapshotTransfer,
},
};
@@ -659,6 +662,9 @@ pub enum MobileWatchPreferenceState {
AppNotInstalled,
Ready,
Pending,
Delivered,
Current,
Failed,
}
impl From<StorageWatchPreferenceState> for MobileWatchPreferenceState {
@@ -669,6 +675,9 @@ impl From<StorageWatchPreferenceState> for MobileWatchPreferenceState {
StorageWatchPreferenceState::AppNotInstalled => Self::AppNotInstalled,
StorageWatchPreferenceState::Ready => Self::Ready,
StorageWatchPreferenceState::Pending => Self::Pending,
StorageWatchPreferenceState::Delivered => Self::Delivered,
StorageWatchPreferenceState::Current => Self::Current,
StorageWatchPreferenceState::Failed => Self::Failed,
}
}
}
@@ -922,14 +931,22 @@ pub struct MobileEntryCopy {
#[derive(Clone, Copy, Debug, Eq, PartialEq, uniffi::Enum)]
pub enum MobileWatchSnapshotState {
Unavailable,
Unpaired,
Pending,
Delivered,
Current,
Failed,
}
impl From<StorageWatchSnapshotState> for MobileWatchSnapshotState {
fn from(state: StorageWatchSnapshotState) -> Self {
match state {
StorageWatchSnapshotState::Unavailable => Self::Unavailable,
StorageWatchSnapshotState::Unpaired => Self::Unpaired,
StorageWatchSnapshotState::Pending => Self::Pending,
StorageWatchSnapshotState::Delivered => Self::Delivered,
StorageWatchSnapshotState::Current => Self::Current,
StorageWatchSnapshotState::Failed => Self::Failed,
}
}
}
@@ -937,6 +954,7 @@ impl From<StorageWatchSnapshotState> for MobileWatchSnapshotState {
#[derive(Clone, uniffi::Record)]
pub struct MobileWatchSnapshotStatus {
pub state: MobileWatchSnapshotState,
pub revision: Option<u64>,
pub detail: String,
}
@@ -944,11 +962,31 @@ impl From<&StorageWatchSnapshotStatus> for MobileWatchSnapshotStatus {
fn from(status: &StorageWatchSnapshotStatus) -> Self {
Self {
state: status.state().into(),
revision: status.revision(),
detail: status.detail().to_owned(),
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct MobileWatchSnapshotTransfer {
pub revision: u64,
pub selected_entries: u32,
pub snapshot: Vec<u8>,
pub delivered_receipt: Vec<u8>,
}
impl From<StorageWatchSnapshotTransfer> for MobileWatchSnapshotTransfer {
fn from(transfer: StorageWatchSnapshotTransfer) -> Self {
Self {
revision: transfer.revision(),
selected_entries: transfer.selected_entries(),
snapshot: transfer.snapshot().expose().to_vec(),
delivered_receipt: transfer.delivered_receipt().to_vec(),
}
}
}
#[derive(Clone, uniffi::Record)]
pub struct MobileTotpRow {
pub path: String,
@@ -1724,6 +1762,57 @@ impl MobileAuthentication {
.map_err(Into::into)
}
pub fn watch_snapshot_status(
&self,
) -> Result<MobileWatchSnapshotStatus, MobileAuthenticationFfiError> {
self.authentication
.watch_snapshot_status()
.map(|status| (&status).into())
.map_err(Into::into)
}
pub fn prepare_watch_snapshot(
&self,
platform_pairing_identity: String,
) -> Result<MobileWatchSnapshotTransfer, MobileAuthenticationFfiError> {
self.authentication
.prepare_watch_snapshot(&platform_pairing_identity)
.map(Into::into)
.map_err(Into::into)
}
pub fn set_watch_snapshot_unavailable(
&self,
unpaired: bool,
detail: String,
) -> Result<MobileWatchSnapshotStatus, MobileAuthenticationFfiError> {
self.authentication
.set_watch_snapshot_unavailable(unpaired, detail)
.map(|status| (&status).into())
.map_err(Into::into)
}
pub fn fail_watch_snapshot(
&self,
revision: u64,
detail: String,
) -> Result<MobileWatchSnapshotStatus, MobileAuthenticationFfiError> {
self.authentication
.fail_watch_snapshot(revision, detail)
.map(|status| (&status).into())
.map_err(Into::into)
}
pub fn acknowledge_watch_snapshot(
&self,
receipt: Vec<u8>,
) -> Result<MobileWatchSnapshotStatus, MobileAuthenticationFfiError> {
self.authentication
.acknowledge_watch_snapshot(&receipt)
.map(|status| (&status).into())
.map_err(Into::into)
}
pub fn begin_create_entry(
&self,
directory: String,