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

@@ -603,6 +603,8 @@ fileprivate struct FfiConverterData: FfiConverterRustBuffer {
public protocol MobileAuthenticationProtocol: AnyObject, Sendable {
func acknowledgeWatchSnapshot(receipt: Data) throws -> MobileWatchSnapshotStatus
func addEntryEditorField(editor: UInt64, kind: MobileEntryEditorFieldKind, name: String?, value: String) throws -> MobileEntryEditorPage
func beginCreateEntry(directory: String, name: String, passphrase: String?) throws -> MobileEntryEditorSession
@@ -623,6 +625,8 @@ public protocol MobileAuthenticationProtocol: AnyObject, Sendable {
func entryPage(path: String, unixSeconds: UInt64) throws -> MobileEntryPresentation
func failWatchSnapshot(revision: UInt64, detail: String) throws -> MobileWatchSnapshotStatus
func generateEntryEditorPassword(editor: UInt64, length: UInt32?, noSymbols: Bool) throws -> MobileEntryEditorPage
func gitIdentity() throws -> MobileGitIdentity
@@ -637,6 +641,8 @@ public protocol MobileAuthenticationProtocol: AnyObject, Sendable {
func prepareEntryMutation(path: String, action: MobileMutationAction) throws -> MobileMutationPlan
func prepareWatchSnapshot(platformPairingIdentity: String) throws -> MobileWatchSnapshotTransfer
func removeApplicationToken() throws
func removeEntryEditorField(editor: UInt64, field: UInt64) throws -> MobileEntryEditorPage
@@ -661,6 +667,8 @@ public protocol MobileAuthenticationProtocol: AnyObject, Sendable {
func setTotpWatchShared(path: String, shared: Bool, unixSeconds: UInt64) throws -> MobileTotpDetail
func setWatchSnapshotUnavailable(unpaired: Bool, detail: String) throws -> MobileWatchSnapshotStatus
func state() throws -> MobileAuthenticationState
func totpDetail(path: String, unixSeconds: UInt64) throws -> MobileTotpDetail
@@ -675,6 +683,8 @@ public protocol MobileAuthenticationProtocol: AnyObject, Sendable {
func updateEntryEditor(editor: UInt64, fields: [MobileEntryEditorInput]) throws -> MobileEntryEditorPage
func watchSnapshotStatus() throws -> MobileWatchSnapshotStatus
}
open class MobileAuthentication: MobileAuthenticationProtocol, @unchecked Sendable {
fileprivate let handle: UInt64
@@ -729,6 +739,16 @@ open class MobileAuthentication: MobileAuthenticationProtocol, @unchecked Sendab
open func acknowledgeWatchSnapshot(receipt: Data)throws -> MobileWatchSnapshotStatus {
return try FfiConverterTypeMobileWatchSnapshotStatus_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
uniffi_ironstorage_apple_fn_method_mobileauthentication_acknowledge_watch_snapshot(
self.uniffiCloneHandle(),
FfiConverterData.lower(receipt),uniffiCallStatus
)
})
}
open func addEntryEditorField(editor: UInt64, kind: MobileEntryEditorFieldKind, name: String?, value: String)throws -> MobileEntryEditorPage {
return try FfiConverterTypeMobileEntryEditorPage_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
@@ -833,6 +853,17 @@ open func entryPage(path: String, unixSeconds: UInt64)throws -> MobileEntryPres
})
}
open func failWatchSnapshot(revision: UInt64, detail: String)throws -> MobileWatchSnapshotStatus {
return try FfiConverterTypeMobileWatchSnapshotStatus_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
uniffi_ironstorage_apple_fn_method_mobileauthentication_fail_watch_snapshot(
self.uniffiCloneHandle(),
FfiConverterUInt64.lower(revision),
FfiConverterString.lower(detail),uniffiCallStatus
)
})
}
open func generateEntryEditorPassword(editor: UInt64, length: UInt32?, noSymbols: Bool)throws -> MobileEntryEditorPage {
return try FfiConverterTypeMobileEntryEditorPage_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
@@ -904,6 +935,16 @@ open func prepareEntryMutation(path: String, action: MobileMutationAction)throws
})
}
open func prepareWatchSnapshot(platformPairingIdentity: String)throws -> MobileWatchSnapshotTransfer {
return try FfiConverterTypeMobileWatchSnapshotTransfer_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
uniffi_ironstorage_apple_fn_method_mobileauthentication_prepare_watch_snapshot(
self.uniffiCloneHandle(),
FfiConverterString.lower(platformPairingIdentity),uniffiCallStatus
)
})
}
open func removeApplicationToken()throws {try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
uniffi_ironstorage_apple_fn_method_mobileauthentication_remove_application_token(
@@ -1030,6 +1071,17 @@ open func setTotpWatchShared(path: String, shared: Bool, unixSeconds: UInt64)thr
})
}
open func setWatchSnapshotUnavailable(unpaired: Bool, detail: String)throws -> MobileWatchSnapshotStatus {
return try FfiConverterTypeMobileWatchSnapshotStatus_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
uniffi_ironstorage_apple_fn_method_mobileauthentication_set_watch_snapshot_unavailable(
self.uniffiCloneHandle(),
FfiConverterBool.lower(unpaired),
FfiConverterString.lower(detail),uniffiCallStatus
)
})
}
open func state()throws -> MobileAuthenticationState {
return try FfiConverterTypeMobileAuthenticationState_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
@@ -1100,6 +1152,15 @@ open func updateEntryEditor(editor: UInt64, fields: [MobileEntryEditorInput])thr
})
}
open func watchSnapshotStatus()throws -> MobileWatchSnapshotStatus {
return try FfiConverterTypeMobileWatchSnapshotStatus_lift(try rustCallWithError(FfiConverterTypeMobileAuthenticationFfiError_lift) {
uniffiCallStatus in
uniffi_ironstorage_apple_fn_method_mobileauthentication_watch_snapshot_status(
self.uniffiCloneHandle(),uniffiCallStatus
)
})
}
}
@@ -4453,12 +4514,14 @@ public func FfiConverterTypeMobileTotpRow_lower(_ value: MobileTotpRow) -> RustB
public struct MobileWatchSnapshotStatus: Equatable, Hashable {
public var state: MobileWatchSnapshotState
public var revision: UInt64?
public var detail: String
// Default memberwise initializers are never public by default, so we
// declare one manually.
public init(state: MobileWatchSnapshotState, detail: String) {
public init(state: MobileWatchSnapshotState, revision: UInt64?, detail: String) {
self.state = state
self.revision = revision
self.detail = detail
}
@@ -4479,12 +4542,14 @@ public struct FfiConverterTypeMobileWatchSnapshotStatus: FfiConverterRustBuffer
return
try MobileWatchSnapshotStatus(
state: FfiConverterTypeMobileWatchSnapshotState.read(from: &buf),
revision: FfiConverterOptionUInt64.read(from: &buf),
detail: FfiConverterString.read(from: &buf)
)
}
public static func write(_ value: MobileWatchSnapshotStatus, into buf: inout [UInt8]) {
FfiConverterTypeMobileWatchSnapshotState.write(value.state, into: &buf)
FfiConverterOptionUInt64.write(value.revision, into: &buf)
FfiConverterString.write(value.detail, into: &buf)
}
}
@@ -4505,6 +4570,68 @@ public func FfiConverterTypeMobileWatchSnapshotStatus_lower(_ value: MobileWatch
}
public struct MobileWatchSnapshotTransfer: Equatable, Hashable {
public var revision: UInt64
public var selectedEntries: UInt32
public var snapshot: Data
public var deliveredReceipt: Data
// Default memberwise initializers are never public by default, so we
// declare one manually.
public init(revision: UInt64, selectedEntries: UInt32, snapshot: Data, deliveredReceipt: Data) {
self.revision = revision
self.selectedEntries = selectedEntries
self.snapshot = snapshot
self.deliveredReceipt = deliveredReceipt
}
}
#if compiler(>=6)
extension MobileWatchSnapshotTransfer: Sendable {}
#endif
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public struct FfiConverterTypeMobileWatchSnapshotTransfer: FfiConverterRustBuffer {
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MobileWatchSnapshotTransfer {
return
try MobileWatchSnapshotTransfer(
revision: FfiConverterUInt64.read(from: &buf),
selectedEntries: FfiConverterUInt32.read(from: &buf),
snapshot: FfiConverterData.read(from: &buf),
deliveredReceipt: FfiConverterData.read(from: &buf)
)
}
public static func write(_ value: MobileWatchSnapshotTransfer, into buf: inout [UInt8]) {
FfiConverterUInt64.write(value.revision, into: &buf)
FfiConverterUInt32.write(value.selectedEntries, into: &buf)
FfiConverterData.write(value.snapshot, into: &buf)
FfiConverterData.write(value.deliveredReceipt, into: &buf)
}
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeMobileWatchSnapshotTransfer_lift(_ buf: RustBuffer) throws -> MobileWatchSnapshotTransfer {
return try FfiConverterTypeMobileWatchSnapshotTransfer.lift(buf)
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
public func FfiConverterTypeMobileWatchSnapshotTransfer_lower(_ value: MobileWatchSnapshotTransfer) -> RustBuffer {
return FfiConverterTypeMobileWatchSnapshotTransfer.lower(value)
}
public enum MobileAppearance: Equatable, Hashable {
@@ -6618,6 +6745,9 @@ public enum MobileWatchPreferenceState: Equatable, Hashable {
case appNotInstalled
case ready
case pending
case delivered
case current
case failed
@@ -6649,6 +6779,12 @@ public struct FfiConverterTypeMobileWatchPreferenceState: FfiConverterRustBuffer
case 5: return .pending
case 6: return .delivered
case 7: return .current
case 8: return .failed
default: throw UniffiInternalError.unexpectedEnumCase
}
}
@@ -6676,6 +6812,18 @@ public struct FfiConverterTypeMobileWatchPreferenceState: FfiConverterRustBuffer
case .pending:
writeInt(&buf, Int32(5))
case .delivered:
writeInt(&buf, Int32(6))
case .current:
writeInt(&buf, Int32(7))
case .failed:
writeInt(&buf, Int32(8))
}
}
}
@@ -6701,7 +6849,11 @@ public func FfiConverterTypeMobileWatchPreferenceState_lower(_ value: MobileWatc
public enum MobileWatchSnapshotState: Equatable, Hashable {
case unavailable
case unpaired
case pending
case delivered
case current
case failed
@@ -6725,7 +6877,15 @@ public struct FfiConverterTypeMobileWatchSnapshotState: FfiConverterRustBuffer {
case 1: return .unavailable
case 2: return .pending
case 2: return .unpaired
case 3: return .pending
case 4: return .delivered
case 5: return .current
case 6: return .failed
default: throw UniffiInternalError.unexpectedEnumCase
}
@@ -6739,9 +6899,25 @@ public struct FfiConverterTypeMobileWatchSnapshotState: FfiConverterRustBuffer {
writeInt(&buf, Int32(1))
case .pending:
case .unpaired:
writeInt(&buf, Int32(2))
case .pending:
writeInt(&buf, Int32(3))
case .delivered:
writeInt(&buf, Int32(4))
case .current:
writeInt(&buf, Int32(5))
case .failed:
writeInt(&buf, Int32(6))
}
}
}
@@ -6786,6 +6962,30 @@ fileprivate struct FfiConverterOptionUInt32: FfiConverterRustBuffer {
}
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer {
typealias SwiftType = UInt64?
public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
guard let value = value else {
writeInt(&buf, Int8(0))
return
}
writeInt(&buf, Int8(1))
FfiConverterUInt64.write(value, into: &buf)
}
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
switch try readInt(&buf) as Int8 {
case 0: return nil
case 1: return try FfiConverterUInt64.read(from: &buf)
default: throw UniffiInternalError.unexpectedOptionalTag
}
}
}
#if swift(>=5.8)
@_documentation(visibility: private)
#endif
@@ -7497,6 +7697,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_ironstorage_apple_checksum_func_set_selected_mobile_tab() != 65280) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_acknowledge_watch_snapshot() != 12885) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_add_entry_editor_field() != 58790) {
return InitializationResult.apiChecksumMismatch
}
@@ -7527,6 +7730,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_entry_page() != 9073) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_fail_watch_snapshot() != 56313) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_generate_entry_editor_password() != 34289) {
return InitializationResult.apiChecksumMismatch
}
@@ -7548,6 +7754,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_prepare_entry_mutation() != 6234) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_prepare_watch_snapshot() != 14176) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_remove_application_token() != 11452) {
return InitializationResult.apiChecksumMismatch
}
@@ -7584,6 +7793,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_set_totp_watch_shared() != 57472) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_set_watch_snapshot_unavailable() != 49094) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_state() != 60826) {
return InitializationResult.apiChecksumMismatch
}
@@ -7605,6 +7817,9 @@ private let initializationResult: InitializationResult = {
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_update_entry_editor() != 30139) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobileauthentication_watch_snapshot_status() != 17344) {
return InitializationResult.apiChecksumMismatch
}
if (uniffi_ironstorage_apple_checksum_method_mobilehomeoperation_cached() != 32436) {
return InitializationResult.apiChecksumMismatch
}