Crypto identity reset (#3107)

* Add EncryptionReset password entry screen

* Expose client proxy identity reset method

* Update the IdentityConfirmationScreen to the latest designs

* Replace the old recovery key reset screen with a new EncryptionReset one

* Fixes #3102 - Add support for resetting the user's whole crypto identity

* Address review comments

* Bump the SDK to v1.0.30
This commit is contained in:
Stefan Ceriu
2024-08-05 09:35:18 +03:00
committed by GitHub
parent 276bbb09f2
commit 63e0b94764
58 changed files with 1217 additions and 319 deletions
@@ -28,7 +28,7 @@ enum SecureBackupRecoveryKeyScreenCoordinatorAction {
case recoverySetUp
case recoveryChanged
case recoveryFixed
case showResetKeyInfo
case resetEncryption
}
final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
@@ -65,8 +65,8 @@ final class SecureBackupRecoveryKeyScreenCoordinator: CoordinatorProtocol {
case .unknown:
fatalError()
}
case .showResetKeyInfo:
self.actionsSubject.send(.showResetKeyInfo)
case .resetEncryption:
self.actionsSubject.send(.resetEncryption)
}
}
.store(in: &cancellables)
@@ -19,7 +19,7 @@ import Foundation
enum SecureBackupRecoveryKeyScreenViewModelAction {
case done(mode: SecureBackupRecoveryKeyScreenViewMode)
case cancel
case showResetKeyInfo
case resetEncryption
}
enum SecureBackupRecoveryKeyScreenViewMode {
@@ -90,7 +90,7 @@ enum SecureBackupRecoveryKeyScreenViewAction {
case copyKey
case keySaved
case confirmKey
case resetKey
case resetEncryption
case done
case cancel
}
@@ -40,13 +40,12 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
secureBackupController.recoveryState
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak userIndicatorController] state in
let loadingIndicatorIdentifier = "SecureBackupRecoveryKeyScreenLoading"
.sink(receiveValue: { [weak self] state in
switch state {
case .settingUp:
userIndicatorController?.submitIndicator(.init(id: loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))
self?.showLoadingIndicator()
default:
userIndicatorController?.retractIndicatorWithId(loadingIndicatorIdentifier)
self?.hideLoadingIndicator()
}
})
.store(in: &cancellables)
@@ -67,6 +66,8 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
MXLog.error("Failed generating recovery key with error: \(error)")
state.bindings.alertInfo = .init(id: .init())
}
hideLoadingIndicator()
}
case .copyKey:
UIPasteboard.general.string = state.recoveryKey
@@ -76,8 +77,7 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
state.doneButtonEnabled = true
case .confirmKey:
Task {
let loadingIndicatorIdentifier = "SecureBackupRecoveryKeyScreen"
userIndicatorController.submitIndicator(.init(id: loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))
showLoadingIndicator()
switch await secureBackupController.confirmRecoveryKey(state.bindings.confirmationRecoveryKey) {
case .success:
@@ -87,7 +87,7 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
state.bindings.alertInfo = .init(id: .init())
}
userIndicatorController.retractIndicatorWithId(loadingIndicatorIdentifier)
hideLoadingIndicator()
}
case .cancel:
actionsSubject.send(.cancel)
@@ -100,10 +100,23 @@ class SecureBackupRecoveryKeyScreenViewModel: SecureBackupRecoveryKeyScreenViewM
guard let self else { return }
actionsSubject.send(.done(mode: context.viewState.mode))
}))
case .resetKey:
actionsSubject.send(.showResetKeyInfo)
case .resetEncryption:
actionsSubject.send(.resetEncryption)
}
}
private static let loadingIndicatorIdentifier = "\(SecureBackupRecoveryKeyScreenViewModel.self)-Loading"
private func showLoadingIndicator() {
userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal,
title: L10n.commonLoading,
persistent: true))
}
private func hideLoadingIndicator() {
userIndicatorController.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
}
}
extension SecureBackupRecoveryState {
@@ -101,7 +101,7 @@ struct SecureBackupRecoveryKeyScreen: View {
.disabled(context.confirmationRecoveryKey.isEmpty)
Button {
context.send(viewAction: .resetKey)
context.send(viewAction: .resetEncryption)
} label: {
Text(L10n.screenIdentityConfirmationCreateNewRecoveryKey)
.padding(.vertical, 14)
@@ -205,9 +205,6 @@ struct SecureBackupRecoveryKeyScreen: View {
.font(.compound.bodySMSemibold)
SecureField(L10n.screenRecoveryKeyConfirmKeyPlaceholder, text: $context.confirmationRecoveryKey)
.textContentType(.password) // Not ideal but stops random suggestions
.autocapitalization(.none)
.disableAutocorrection(true)
.frame(maxWidth: .infinity)
.padding()
.background(Color.compound.bgSubtleSecondaryLevel0)