Implement native iPhone entry editor
This commit is contained in:
@@ -15,7 +15,11 @@ use ironstorage::{
|
||||
MobileEntryCopy as StorageEntryCopy,
|
||||
},
|
||||
mobile_entry::{
|
||||
MobileEntryPage as StorageEntryPage, MobileEntrySectionKind as StorageEntrySectionKind,
|
||||
MobileEntryEditorFieldKind as StorageEntryEditorFieldKind,
|
||||
MobileEntryEditorInput as StorageEntryEditorInput,
|
||||
MobileEntryEditorPage as StorageEntryEditorPage,
|
||||
MobileEntryEditorSession as StorageEntryEditorSession, MobileEntryPage as StorageEntryPage,
|
||||
MobileEntrySectionKind as StorageEntrySectionKind,
|
||||
},
|
||||
mobile_home::{
|
||||
self, MobileHomeChangeKind as StorageHomeChangeKind,
|
||||
@@ -511,6 +515,7 @@ pub enum MobileAuthenticationErrorKind {
|
||||
Entry,
|
||||
SecureStorage,
|
||||
Expired,
|
||||
Conflict,
|
||||
}
|
||||
|
||||
impl From<StorageAuthenticationErrorKind> for MobileAuthenticationErrorKind {
|
||||
@@ -525,6 +530,7 @@ impl From<StorageAuthenticationErrorKind> for MobileAuthenticationErrorKind {
|
||||
StorageAuthenticationErrorKind::Entry => Self::Entry,
|
||||
StorageAuthenticationErrorKind::SecureStorage => Self::SecureStorage,
|
||||
StorageAuthenticationErrorKind::Expired => Self::Expired,
|
||||
StorageAuthenticationErrorKind::Conflict => Self::Conflict,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -624,6 +630,124 @@ pub struct MobileEntryCopy {
|
||||
pub timeout_seconds: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, uniffi::Enum)]
|
||||
pub enum MobileEntryEditorFieldKind {
|
||||
Password,
|
||||
Field,
|
||||
Note,
|
||||
OtpUri,
|
||||
}
|
||||
|
||||
impl From<StorageEntryEditorFieldKind> for MobileEntryEditorFieldKind {
|
||||
fn from(kind: StorageEntryEditorFieldKind) -> Self {
|
||||
match kind {
|
||||
StorageEntryEditorFieldKind::Password => Self::Password,
|
||||
StorageEntryEditorFieldKind::Field => Self::Field,
|
||||
StorageEntryEditorFieldKind::Note => Self::Note,
|
||||
StorageEntryEditorFieldKind::OtpUri => Self::OtpUri,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MobileEntryEditorFieldKind> for StorageEntryEditorFieldKind {
|
||||
fn from(kind: MobileEntryEditorFieldKind) -> Self {
|
||||
match kind {
|
||||
MobileEntryEditorFieldKind::Password => Self::Password,
|
||||
MobileEntryEditorFieldKind::Field => Self::Field,
|
||||
MobileEntryEditorFieldKind::Note => Self::Note,
|
||||
MobileEntryEditorFieldKind::OtpUri => Self::OtpUri,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileEntryEditorField {
|
||||
pub id: u64,
|
||||
pub kind: MobileEntryEditorFieldKind,
|
||||
pub name: Option<String>,
|
||||
pub label: String,
|
||||
pub system_image: String,
|
||||
pub value: Option<String>,
|
||||
pub masked_value: String,
|
||||
pub diagnostic: Option<String>,
|
||||
pub sensitive: bool,
|
||||
pub multiline: bool,
|
||||
pub name_editable: bool,
|
||||
pub removable: bool,
|
||||
pub reorderable: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileEntryEditorPage {
|
||||
pub path: String,
|
||||
pub title: String,
|
||||
pub fields: Vec<MobileEntryEditorField>,
|
||||
pub dirty: bool,
|
||||
pub creating: bool,
|
||||
pub default_password_length: u32,
|
||||
pub maximum_password_length: u32,
|
||||
}
|
||||
|
||||
impl From<&StorageEntryEditorPage> for MobileEntryEditorPage {
|
||||
fn from(page: &StorageEntryEditorPage) -> Self {
|
||||
Self {
|
||||
path: page.path().to_owned(),
|
||||
title: page.title().to_owned(),
|
||||
fields: page
|
||||
.fields()
|
||||
.iter()
|
||||
.map(|field| MobileEntryEditorField {
|
||||
id: field.id(),
|
||||
kind: field.kind().into(),
|
||||
name: field.name().map(str::to_owned),
|
||||
label: field.label().to_owned(),
|
||||
system_image: field.system_image().to_owned(),
|
||||
value: field.value().map(str::to_owned),
|
||||
masked_value: field.masked_value().to_owned(),
|
||||
diagnostic: field.diagnostic().map(str::to_owned),
|
||||
sensitive: field.sensitive(),
|
||||
multiline: field.multiline(),
|
||||
name_editable: field.name_editable(),
|
||||
removable: field.removable(),
|
||||
reorderable: field.reorderable(),
|
||||
})
|
||||
.collect(),
|
||||
dirty: page.dirty(),
|
||||
creating: page.creating(),
|
||||
default_password_length: page.default_password_length(),
|
||||
maximum_password_length: page.maximum_password_length(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileEntryEditorSession {
|
||||
pub id: u64,
|
||||
pub page: MobileEntryEditorPage,
|
||||
}
|
||||
|
||||
impl From<StorageEntryEditorSession> for MobileEntryEditorSession {
|
||||
fn from(session: StorageEntryEditorSession) -> Self {
|
||||
Self {
|
||||
id: session.id(),
|
||||
page: session.page().into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Record)]
|
||||
pub struct MobileEntryEditorInput {
|
||||
pub id: u64,
|
||||
pub name: Option<String>,
|
||||
pub value: Option<String>,
|
||||
}
|
||||
|
||||
impl From<MobileEntryEditorInput> for StorageEntryEditorInput {
|
||||
fn from(input: MobileEntryEditorInput) -> Self {
|
||||
Self::new(input.id, input.name, input.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StorageEntryCopy> for MobileEntryCopy {
|
||||
fn from(copy: StorageEntryCopy) -> Self {
|
||||
Self {
|
||||
@@ -760,6 +884,119 @@ impl MobileAuthentication {
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn begin_entry_editor(
|
||||
&self,
|
||||
path: String,
|
||||
) -> Result<MobileEntryEditorSession, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.begin_entry_editor(&path)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn begin_create_entry(
|
||||
&self,
|
||||
directory: String,
|
||||
name: String,
|
||||
passphrase: Option<String>,
|
||||
) -> Result<MobileEntryEditorSession, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.begin_create_entry(
|
||||
&directory,
|
||||
&name,
|
||||
passphrase
|
||||
.map(|value| ironstorage::repository::SecretBytes::new(value.into_bytes())),
|
||||
)
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn entry_editor(
|
||||
&self,
|
||||
editor: u64,
|
||||
) -> Result<MobileEntryEditorPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.entry_editor(editor)
|
||||
.map(|page| (&page).into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn update_entry_editor(
|
||||
&self,
|
||||
editor: u64,
|
||||
fields: Vec<MobileEntryEditorInput>,
|
||||
) -> Result<MobileEntryEditorPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.update_entry_editor(editor, fields.into_iter().map(Into::into).collect())
|
||||
.map(|page| (&page).into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn add_entry_editor_field(
|
||||
&self,
|
||||
editor: u64,
|
||||
kind: MobileEntryEditorFieldKind,
|
||||
name: Option<String>,
|
||||
value: String,
|
||||
) -> Result<MobileEntryEditorPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.add_entry_editor_field(editor, kind.into(), name, value)
|
||||
.map(|page| (&page).into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn remove_entry_editor_field(
|
||||
&self,
|
||||
editor: u64,
|
||||
field: u64,
|
||||
) -> Result<MobileEntryEditorPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.remove_entry_editor_field(editor, field)
|
||||
.map(|page| (&page).into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn reorder_entry_editor_field(
|
||||
&self,
|
||||
editor: u64,
|
||||
field: u64,
|
||||
index: u32,
|
||||
) -> Result<MobileEntryEditorPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.reorder_entry_editor_field(editor, field, index as usize)
|
||||
.map(|page| (&page).into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn generate_entry_editor_password(
|
||||
&self,
|
||||
editor: u64,
|
||||
length: Option<u32>,
|
||||
no_symbols: bool,
|
||||
) -> Result<MobileEntryEditorPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.generate_entry_editor_password(editor, length, no_symbols)
|
||||
.map(|page| (&page).into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn save_entry_editor(
|
||||
&self,
|
||||
editor: u64,
|
||||
fields: Vec<MobileEntryEditorInput>,
|
||||
) -> Result<MobileEntryPage, MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.save_entry_editor(editor, fields.into_iter().map(Into::into).collect())
|
||||
.map(Into::into)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn discard_entry_editor(&self, editor: u64) -> Result<(), MobileAuthenticationFfiError> {
|
||||
self.authentication
|
||||
.discard_entry_editor(editor)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn manual_lock(&self) -> Result<(), MobileAuthenticationFfiError> {
|
||||
self.authentication.manual_lock().map_err(Into::into)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user