Implement iPhone TOTP tab and Watch sharing
This commit is contained in:
@@ -37,6 +37,11 @@ use ironstorage::{
|
||||
MobilePasswordErrorKind as StoragePasswordErrorKind,
|
||||
MobilePasswordRowKind as StoragePasswordRowKind,
|
||||
},
|
||||
mobile_totp::{
|
||||
MobileTotpDetail as StorageTotpDetail, MobileTotpPage as StorageTotpPage,
|
||||
MobileWatchSnapshotState as StorageWatchSnapshotState,
|
||||
MobileWatchSnapshotStatus as StorageWatchSnapshotStatus,
|
||||
},
|
||||
};
|
||||
|
||||
uniffi::setup_scaffolding!();
|
||||
@@ -630,6 +635,102 @@ pub struct MobileEntryCopy {
|
||||
pub timeout_seconds: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, uniffi::Enum)]
|
||||
pub enum MobileWatchSnapshotState {
|
||||
Unavailable,
|
||||
Pending,
|
||||
}
|
||||
|
||||
impl From<StorageWatchSnapshotState> for MobileWatchSnapshotState {
|
||||
fn from(state: StorageWatchSnapshotState) -> Self {
|
||||
match state {
|
||||
StorageWatchSnapshotState::Unavailable => Self::Unavailable,
|
||||
StorageWatchSnapshotState::Pending => Self::Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileWatchSnapshotStatus {
|
||||
pub state: MobileWatchSnapshotState,
|
||||
pub detail: String,
|
||||
}
|
||||
|
||||
impl From<&StorageWatchSnapshotStatus> for MobileWatchSnapshotStatus {
|
||||
fn from(status: &StorageWatchSnapshotStatus) -> Self {
|
||||
Self {
|
||||
state: status.state().into(),
|
||||
detail: status.detail().to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileTotpRow {
|
||||
pub path: String,
|
||||
pub issuer: Option<String>,
|
||||
pub account: String,
|
||||
pub title: String,
|
||||
pub detail: String,
|
||||
pub shared_with_watch: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileTotpPage {
|
||||
pub rows: Vec<MobileTotpRow>,
|
||||
pub unavailable_entries: u32,
|
||||
pub watch: MobileWatchSnapshotStatus,
|
||||
}
|
||||
|
||||
impl From<StorageTotpPage> for MobileTotpPage {
|
||||
fn from(page: StorageTotpPage) -> Self {
|
||||
Self {
|
||||
rows: page
|
||||
.rows()
|
||||
.iter()
|
||||
.map(|row| MobileTotpRow {
|
||||
path: row.path().to_owned(),
|
||||
issuer: row.issuer().map(str::to_owned),
|
||||
account: row.account().to_owned(),
|
||||
title: row.title().to_owned(),
|
||||
detail: row.detail().to_owned(),
|
||||
shared_with_watch: row.shared_with_watch(),
|
||||
})
|
||||
.collect(),
|
||||
unavailable_entries: page.unavailable_entries(),
|
||||
watch: page.watch().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileTotpDetail {
|
||||
pub path: String,
|
||||
pub issuer: Option<String>,
|
||||
pub account: String,
|
||||
pub code: String,
|
||||
pub valid_until: u64,
|
||||
pub period: u64,
|
||||
pub shared_with_watch: bool,
|
||||
pub watch: MobileWatchSnapshotStatus,
|
||||
}
|
||||
|
||||
impl From<StorageTotpDetail> for MobileTotpDetail {
|
||||
fn from(detail: StorageTotpDetail) -> Self {
|
||||
Self {
|
||||
path: detail.path().to_owned(),
|
||||
issuer: detail.issuer().map(str::to_owned),
|
||||
account: detail.account().to_owned(),
|
||||
code: String::from_utf8(detail.code().expose().to_vec())
|
||||
.expect("storage-generated TOTP codes are ASCII"),
|
||||
valid_until: detail.valid_until(),
|
||||
period: detail.period(),
|
||||
shared_with_watch: detail.shared_with_watch(),
|
||||
watch: detail.watch().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, uniffi::Enum)]
|
||||
pub enum MobileEntryEditorFieldKind {
|
||||
Password,
|
||||
@@ -894,6 +995,60 @@ impl MobileAuthentication {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn unlock_totp(
|
||||
&self,
|
||||
passphrase: Option<String>,
|
||||
) -> Result<MobileAuthenticationState, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.unlock_totp(
|
||||
passphrase
|
||||
.map(|value| ironstorage::repository::SecretBytes::new(value.into_bytes())),
|
||||
)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn totp_page(&self) -> Result<MobileTotpPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.totp_page()
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn totp_detail(
|
||||
&self,
|
||||
path: String,
|
||||
unix_seconds: u64,
|
||||
) -> Result<MobileTotpDetail, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.totp_detail(&path, unix_seconds)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn copy_totp_code(
|
||||
&self,
|
||||
path: String,
|
||||
unix_seconds: u64,
|
||||
) -> Result<MobileEntryCopy, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.copy_totp_code(&path, unix_seconds)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn set_totp_watch_shared(
|
||||
&self,
|
||||
path: String,
|
||||
shared: bool,
|
||||
unix_seconds: u64,
|
||||
) -> Result<MobileTotpDetail, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.set_totp_watch_shared(&path, shared, unix_seconds)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn begin_create_entry(
|
||||
&self,
|
||||
directory: String,
|
||||
|
||||
Reference in New Issue
Block a user