mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Update password reset
This commit is contained in:
parent
bdfd37c052
commit
81c33b761f
@ -6540,3 +6540,12 @@ Sorry for the inconvenience.";
|
|||||||
"TwoFactorSetup.PasswordRecovery.SkipAlertTitle" = "Attention!";
|
"TwoFactorSetup.PasswordRecovery.SkipAlertTitle" = "Attention!";
|
||||||
"TwoFactorSetup.PasswordRecovery.SkipAlertText" = "Skipping this step will disable 2-step verification for your account. Are you sure you want to skip?";
|
"TwoFactorSetup.PasswordRecovery.SkipAlertText" = "Skipping this step will disable 2-step verification for your account. Are you sure you want to skip?";
|
||||||
"TwoFactorSetup.PasswordRecovery.SkipAlertAction" = "Skip";
|
"TwoFactorSetup.PasswordRecovery.SkipAlertAction" = "Skip";
|
||||||
|
|
||||||
|
"TwoStepAuth.RecoveryUnavailableResetTitle" = "Reset Password";
|
||||||
|
"TwoStepAuth.RecoveryUnavailableResetText" = "Since you haven't provided a recovery e-mail when setting up your password, your remaining options are either to remember your password or wait 7 days until your password is reset.";
|
||||||
|
"TwoStepAuth.RecoveryEmailResetText" = "If you don't have access to your recovery email, your remaining options are either to remember your password or wait 7 days until your password resets.";
|
||||||
|
"TwoStepAuth.RecoveryUnavailableResetAction" = "Reset";
|
||||||
|
"TwoStepAuth.ResetPendingText" = "You can reset your password in %@.";
|
||||||
|
"TwoStepAuth.CancelResetTitle" = "Cancel Reset";
|
||||||
|
"TwoStepAuth.ResetAction" = "Reset Password";
|
||||||
|
"TwoStepAuth.CancelResetText" = "Cancel the password resetting process? If you proceed, the expired part of the 7-day delay will be lost.";
|
||||||
|
@ -518,7 +518,7 @@ public final class SecureIdAuthController: ViewController, StandalonePresentable
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var completionImpl: (() -> Void)?
|
var completionImpl: (() -> Void)?
|
||||||
let controller = resetPasswordController(context: strongSelf.context, emailPattern: emailPattern, completion: {
|
let controller = resetPasswordController(context: strongSelf.context, emailPattern: emailPattern, completion: { _ in
|
||||||
completionImpl?()
|
completionImpl?()
|
||||||
})
|
})
|
||||||
completionImpl = { [weak controller] in
|
completionImpl = { [weak controller] in
|
||||||
|
@ -115,7 +115,7 @@ public enum ResetPasswordState: Equatable {
|
|||||||
case pendingVerification(emailPattern: String)
|
case pendingVerification(emailPattern: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func resetPasswordController(context: AccountContext, emailPattern: String, completion: @escaping () -> Void) -> ViewController {
|
public func resetPasswordController(context: AccountContext, emailPattern: String, completion: @escaping (Bool) -> Void) -> ViewController {
|
||||||
let statePromise = ValuePromise(ResetPasswordControllerState(), ignoreRepeated: true)
|
let statePromise = ValuePromise(ResetPasswordControllerState(), ignoreRepeated: true)
|
||||||
let stateValue = Atomic(value: ResetPasswordControllerState())
|
let stateValue = Atomic(value: ResetPasswordControllerState())
|
||||||
let updateState: ((ResetPasswordControllerState) -> ResetPasswordControllerState) -> Void = { f in
|
let updateState: ((ResetPasswordControllerState) -> ResetPasswordControllerState) -> Void = { f in
|
||||||
@ -138,7 +138,20 @@ public func resetPasswordController(context: AccountContext, emailPattern: Strin
|
|||||||
}
|
}
|
||||||
}, openHelp: {
|
}, openHelp: {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.TwoStepAuth_RecoveryFailed, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetTitle, text: presentationData.strings.TwoStepAuth_RecoveryEmailResetText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetAction, action: {
|
||||||
|
let _ = (requestTwoStepPasswordReset(network: context.account.network)
|
||||||
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
|
switch result {
|
||||||
|
case .done, .waitingForReset:
|
||||||
|
completion(false)
|
||||||
|
case .declined:
|
||||||
|
break
|
||||||
|
case let .error(reason):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
})
|
})
|
||||||
|
|
||||||
var initialFocusImpl: (() -> Void)?
|
var initialFocusImpl: (() -> Void)?
|
||||||
@ -187,7 +200,7 @@ public func resetPasswordController(context: AccountContext, emailPattern: Strin
|
|||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
}, completed: {
|
}, completed: {
|
||||||
completion()
|
completion(true)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -475,7 +475,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func performRecovery(recovery: TwoFactorDataInputMode.Recovery, password: String, hint: String) {
|
private func performRecovery(recovery: TwoFactorDataInputMode.Recovery, password: String, hint: String) {
|
||||||
/*let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: nil))
|
let statusController = OverlayStatusController(theme: self.presentationData.theme, type: .loading(cancelled: nil))
|
||||||
self.present(statusController, in: .window(.root))
|
self.present(statusController, in: .window(.root))
|
||||||
|
|
||||||
let _ = (performPasswordRecovery(accountManager: self.sharedContext.accountManager, account: recovery.account, code: recovery.code, syncContacts: recovery.syncContacts, updatedPassword: password.isEmpty ? .none : .password(password: password, hint: hint, email: nil))
|
let _ = (performPasswordRecovery(accountManager: self.sharedContext.accountManager, account: recovery.account, code: recovery.code, syncContacts: recovery.syncContacts, updatedPassword: password.isEmpty ? .none : .password(password: password, hint: hint, email: nil))
|
||||||
@ -507,7 +507,7 @@ public final class TwoFactorDataInputScreen: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.dismiss()
|
strongSelf.dismiss()
|
||||||
})*/
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1126,7 +1126,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch strongSelf.mode {
|
switch strongSelf.mode {
|
||||||
case .emailAddress, .updateEmailAddress:
|
case .emailAddress, .updateEmailAddress, .passwordRecovery:
|
||||||
let hasText = strongSelf.inputNodes.contains(where: { !$0.text.isEmpty })
|
let hasText = strongSelf.inputNodes.contains(where: { !$0.text.isEmpty })
|
||||||
strongSelf.buttonNode.isHidden = !hasText
|
strongSelf.buttonNode.isHidden = !hasText
|
||||||
strongSelf.skipActionTitleNode.isHidden = hasText
|
strongSelf.skipActionTitleNode.isHidden = hasText
|
||||||
@ -1148,7 +1148,7 @@ private final class TwoFactorDataInputScreenNode: ViewControllerTracingNode, UIS
|
|||||||
strongSelf.buttonNode.isHidden = !hasText
|
strongSelf.buttonNode.isHidden = !hasText
|
||||||
strongSelf.skipActionTitleNode.isHidden = hasText
|
strongSelf.skipActionTitleNode.isHidden = hasText
|
||||||
strongSelf.skipActionButtonNode.isHidden = hasText
|
strongSelf.skipActionButtonNode.isHidden = hasText
|
||||||
case .password, .passwordRecovery:
|
case .password:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
updateAnimations()
|
updateAnimations()
|
||||||
|
@ -140,7 +140,7 @@ private func twoStepVerificationResetControllerEntries(presentationData: Present
|
|||||||
return entries
|
return entries
|
||||||
}
|
}
|
||||||
|
|
||||||
func twoStepVerificationResetController(context: AccountContext, emailPattern: String, result: Promise<Bool>) -> ViewController {
|
func twoStepVerificationResetController(context: AccountContext, emailPattern: String, result: Promise<Bool>, requestedRecoveryReset: @escaping () -> Void) -> ViewController {
|
||||||
let initialState = TwoStepVerificationResetControllerState(codeText: "", checking: false)
|
let initialState = TwoStepVerificationResetControllerState(codeText: "", checking: false)
|
||||||
|
|
||||||
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
||||||
@ -202,7 +202,20 @@ func twoStepVerificationResetController(context: AccountContext, emailPattern: S
|
|||||||
checkCode()
|
checkCode()
|
||||||
}, openEmailInaccessible: {
|
}, openEmailInaccessible: {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.TwoStepAuth_RecoveryFailed, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetTitle, text: presentationData.strings.TwoStepAuth_RecoveryEmailResetText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetAction, action: {
|
||||||
|
let _ = (requestTwoStepPasswordReset(network: context.account.network)
|
||||||
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
|
switch result {
|
||||||
|
case .done, .waitingForReset:
|
||||||
|
requestedRecoveryReset()
|
||||||
|
case .declined:
|
||||||
|
break
|
||||||
|
case let .error(reason):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
})
|
})
|
||||||
|
|
||||||
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get()) |> deliverOnMainQueue
|
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get()) |> deliverOnMainQueue
|
||||||
|
@ -26,8 +26,10 @@ private final class TwoStepVerificationUnlockSettingsControllerArguments {
|
|||||||
let openResetPendingEmail: () -> Void
|
let openResetPendingEmail: () -> Void
|
||||||
let updateEmailCode: (String) -> Void
|
let updateEmailCode: (String) -> Void
|
||||||
let openConfirmEmail: () -> Void
|
let openConfirmEmail: () -> Void
|
||||||
|
let declinePasswordReset: () -> Void
|
||||||
|
let resetPassword: () -> Void
|
||||||
|
|
||||||
init(updatePasswordText: @escaping (String) -> Void, checkPassword: @escaping () -> Void, openForgotPassword: @escaping () -> Void, openSetupPassword: @escaping () -> Void, openDisablePassword: @escaping () -> Void, openSetupEmail: @escaping () -> Void, openResetPendingEmail: @escaping () -> Void, updateEmailCode: @escaping (String) -> Void, openConfirmEmail: @escaping () -> Void) {
|
init(updatePasswordText: @escaping (String) -> Void, checkPassword: @escaping () -> Void, openForgotPassword: @escaping () -> Void, openSetupPassword: @escaping () -> Void, openDisablePassword: @escaping () -> Void, openSetupEmail: @escaping () -> Void, openResetPendingEmail: @escaping () -> Void, updateEmailCode: @escaping (String) -> Void, openConfirmEmail: @escaping () -> Void, declinePasswordReset: @escaping () -> Void, resetPassword: @escaping () -> Void) {
|
||||||
self.updatePasswordText = updatePasswordText
|
self.updatePasswordText = updatePasswordText
|
||||||
self.checkPassword = checkPassword
|
self.checkPassword = checkPassword
|
||||||
self.openForgotPassword = openForgotPassword
|
self.openForgotPassword = openForgotPassword
|
||||||
@ -37,6 +39,8 @@ private final class TwoStepVerificationUnlockSettingsControllerArguments {
|
|||||||
self.openResetPendingEmail = openResetPendingEmail
|
self.openResetPendingEmail = openResetPendingEmail
|
||||||
self.updateEmailCode = updateEmailCode
|
self.updateEmailCode = updateEmailCode
|
||||||
self.openConfirmEmail = openConfirmEmail
|
self.openConfirmEmail = openConfirmEmail
|
||||||
|
self.declinePasswordReset = declinePasswordReset
|
||||||
|
self.resetPassword = resetPassword
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,47 +136,53 @@ private enum TwoStepVerificationUnlockSettingsEntry: ItemListNodeEntry {
|
|||||||
}, action: {
|
}, action: {
|
||||||
arguments.checkPassword()
|
arguments.checkPassword()
|
||||||
})
|
})
|
||||||
case let .passwordEntryInfo(theme, text):
|
case let .passwordEntryInfo(_, text):
|
||||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section, linkAction: { action in
|
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section, linkAction: { action in
|
||||||
switch action {
|
switch action {
|
||||||
case .tap:
|
case let .tap(item):
|
||||||
arguments.openForgotPassword()
|
if item == "forgot" {
|
||||||
|
arguments.openForgotPassword()
|
||||||
|
} else if item == "declineReset" {
|
||||||
|
arguments.declinePasswordReset()
|
||||||
|
} else if item == "reset" {
|
||||||
|
arguments.resetPassword()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
case let .passwordSetup(theme, text):
|
case let .passwordSetup(_, text):
|
||||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openSetupPassword()
|
arguments.openSetupPassword()
|
||||||
})
|
})
|
||||||
case let .passwordSetupInfo(theme, text):
|
case let .passwordSetupInfo(_, text):
|
||||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section)
|
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section)
|
||||||
case let .changePassword(theme, text):
|
case let .changePassword(_, text):
|
||||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openSetupPassword()
|
arguments.openSetupPassword()
|
||||||
})
|
})
|
||||||
case let .turnPasswordOff(theme, text):
|
case let .turnPasswordOff(_, text):
|
||||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openDisablePassword()
|
arguments.openDisablePassword()
|
||||||
})
|
})
|
||||||
case let .setupRecoveryEmail(theme, text):
|
case let .setupRecoveryEmail(_, text):
|
||||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openSetupEmail()
|
arguments.openSetupEmail()
|
||||||
})
|
})
|
||||||
case let .passwordInfo(theme, text):
|
case let .passwordInfo(_, text):
|
||||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||||
case let .pendingEmailConfirmInfo(theme, text):
|
case let .pendingEmailConfirmInfo(_, text):
|
||||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||||
case let .pendingEmailConfirmCode(theme, strings, title, text):
|
case let .pendingEmailConfirmCode(_, _, title, text):
|
||||||
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: ""), text: text, placeholder: title, type: .number, sectionId: self.section, textUpdated: { value in
|
return ItemListSingleLineInputItem(presentationData: presentationData, title: NSAttributedString(string: ""), text: text, placeholder: title, type: .number, sectionId: self.section, textUpdated: { value in
|
||||||
arguments.updateEmailCode(value)
|
arguments.updateEmailCode(value)
|
||||||
}, action: {})
|
}, action: {})
|
||||||
case let .pendingEmailInfo(theme, text):
|
case let .pendingEmailInfo(_, text):
|
||||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section, linkAction: { action in
|
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section, linkAction: { action in
|
||||||
switch action {
|
switch action {
|
||||||
case .tap:
|
case .tap:
|
||||||
arguments.openResetPendingEmail()
|
arguments.openResetPendingEmail()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
case let .pendingEmailOpenConfirm(theme, text):
|
case let .pendingEmailOpenConfirm(_, text):
|
||||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
arguments.openConfirmEmail()
|
arguments.openConfirmEmail()
|
||||||
})
|
})
|
||||||
@ -204,13 +214,28 @@ private func twoStepVerificationUnlockSettingsControllerEntries(presentationData
|
|||||||
entries.append(.passwordSetup(presentationData.theme, presentationData.strings.TwoStepAuth_SetPassword))
|
entries.append(.passwordSetup(presentationData.theme, presentationData.strings.TwoStepAuth_SetPassword))
|
||||||
entries.append(.passwordSetupInfo(presentationData.theme, presentationData.strings.TwoStepAuth_SetPasswordHelp))
|
entries.append(.passwordSetupInfo(presentationData.theme, presentationData.strings.TwoStepAuth_SetPasswordHelp))
|
||||||
}
|
}
|
||||||
case let .set(hint, _, _):
|
case let .set(hint, _, _, pendingResetTimestamp):
|
||||||
entries.append(.passwordEntry(presentationData.theme, presentationData.strings, presentationData.strings.TwoStepAuth_EnterPasswordPassword, state.passwordText))
|
entries.append(.passwordEntry(presentationData.theme, presentationData.strings, presentationData.strings.TwoStepAuth_EnterPasswordPassword, state.passwordText))
|
||||||
if hint.isEmpty {
|
var text: String = ""
|
||||||
entries.append(.passwordEntryInfo(presentationData.theme, presentationData.strings.TwoStepAuth_EnterPasswordHelp + "\n\n[" + presentationData.strings.TwoStepAuth_EnterPasswordForgot + "](forgot)"))
|
if !hint.isEmpty {
|
||||||
} else {
|
text += presentationData.strings.TwoStepAuth_EnterPasswordHint(escapedPlaintextForMarkdown(hint)).0
|
||||||
entries.append(.passwordEntryInfo(presentationData.theme, presentationData.strings.TwoStepAuth_EnterPasswordHint(escapedPlaintextForMarkdown(hint)).0 + "\n\n" + presentationData.strings.TwoStepAuth_EnterPasswordHelp + "\n\n[" + presentationData.strings.TwoStepAuth_EnterPasswordForgot + "](forgot)"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let pendingResetTimestamp = pendingResetTimestamp {
|
||||||
|
text += "\n\n"
|
||||||
|
let remainingSeconds = pendingResetTimestamp - Int32(Date().timeIntervalSince1970)
|
||||||
|
if remainingSeconds <= 0 {
|
||||||
|
text += "[" + presentationData.strings.TwoStepAuth_ResetAction + "](reset)"
|
||||||
|
} else {
|
||||||
|
text.append(presentationData.strings.TwoStepAuth_ResetPendingText(timeIntervalString(strings: presentationData.strings, value: remainingSeconds)).0)
|
||||||
|
text.append("\n[\(presentationData.strings.TwoStepAuth_CancelResetTitle)](declineReset)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text += "\n\n"
|
||||||
|
text += presentationData.strings.TwoStepAuth_EnterPasswordHelp + "\n\n[" + presentationData.strings.TwoStepAuth_EnterPasswordForgot + "](forgot)"
|
||||||
|
}
|
||||||
|
|
||||||
|
entries.append(.passwordEntryInfo(presentationData.theme, text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .manage(_, emailSet, pendingEmail, _):
|
case let .manage(_, emailSet, pendingEmail, _):
|
||||||
@ -240,14 +265,14 @@ struct TwoStepVerificationPendingEmailState: Equatable {
|
|||||||
|
|
||||||
enum TwoStepVerificationAccessConfiguration: Equatable {
|
enum TwoStepVerificationAccessConfiguration: Equatable {
|
||||||
case notSet(pendingEmail: TwoStepVerificationPendingEmailState?)
|
case notSet(pendingEmail: TwoStepVerificationPendingEmailState?)
|
||||||
case set(hint: String, hasRecoveryEmail: Bool, hasSecureValues: Bool)
|
case set(hint: String, hasRecoveryEmail: Bool, hasSecureValues: Bool, pendingResetTimestamp: Int32?)
|
||||||
|
|
||||||
init(configuration: TwoStepVerificationConfiguration, password: String?) {
|
init(configuration: TwoStepVerificationConfiguration, password: String?) {
|
||||||
switch configuration {
|
switch configuration {
|
||||||
case let .notSet(pendingEmail):
|
case let .notSet(pendingEmail):
|
||||||
self = .notSet(pendingEmail: pendingEmail.flatMap({ TwoStepVerificationPendingEmailState(password: password, email: $0) }))
|
self = .notSet(pendingEmail: pendingEmail.flatMap({ TwoStepVerificationPendingEmailState(password: password, email: $0) }))
|
||||||
case let .set(hint, hasRecoveryEmail, _, hasSecureValues, _):
|
case let .set(hint, hasRecoveryEmail, _, hasSecureValues, pendingResetTimestamp):
|
||||||
self = .set(hint: hint, hasRecoveryEmail: hasRecoveryEmail, hasSecureValues: hasSecureValues)
|
self = .set(hint: hint, hasRecoveryEmail: hasRecoveryEmail, hasSecureValues: hasSecureValues, pendingResetTimestamp: pendingResetTimestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,7 +445,6 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
|
|||||||
|> mapToSignal { settings -> Signal<(TwoStepVerificationSettings, TwoStepVerificationPendingEmail?), AuthorizationPasswordVerificationError> in
|
|> mapToSignal { settings -> Signal<(TwoStepVerificationSettings, TwoStepVerificationPendingEmail?), AuthorizationPasswordVerificationError> in
|
||||||
return twoStepVerificationConfiguration(account: context.account)
|
return twoStepVerificationConfiguration(account: context.account)
|
||||||
|> mapError { _ -> AuthorizationPasswordVerificationError in
|
|> mapError { _ -> AuthorizationPasswordVerificationError in
|
||||||
return .generic
|
|
||||||
}
|
}
|
||||||
|> map { configuration in
|
|> map { configuration in
|
||||||
var pendingEmail: TwoStepVerificationPendingEmail?
|
var pendingEmail: TwoStepVerificationPendingEmail?
|
||||||
@ -469,7 +493,7 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
|
|||||||
if let configuration = configuration {
|
if let configuration = configuration {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
switch configuration {
|
switch configuration {
|
||||||
case let .set(_, hasRecoveryEmail, _):
|
case let .set(_, hasRecoveryEmail, _, pendingResetTimestamp):
|
||||||
if hasRecoveryEmail {
|
if hasRecoveryEmail {
|
||||||
updateState { state in
|
updateState { state in
|
||||||
var state = state
|
var state = state
|
||||||
@ -484,17 +508,25 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
var completionImpl: (() -> Void)?
|
var completionImpl: ((Bool) -> Void)?
|
||||||
let controller = resetPasswordController(context: context, emailPattern: emailPattern, completion: {
|
let controller = resetPasswordController(context: context, emailPattern: emailPattern, completion: { result in
|
||||||
completionImpl?()
|
completionImpl?(result)
|
||||||
})
|
})
|
||||||
completionImpl = { [weak controller] in
|
completionImpl = { [weak controller] result in
|
||||||
dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: .notSet(pendingEmail: nil))))
|
if !result {
|
||||||
controller?.view.endEditing(true)
|
dataPromise.set(twoStepVerificationConfiguration(account: context.account)
|
||||||
controller?.dismiss()
|
|> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil))
|
||||||
|
})
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
controller?.view.endEditing(true)
|
||||||
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.TwoStepAuth_DisableSuccess, false)), nil)
|
controller?.dismiss()
|
||||||
|
} else {
|
||||||
|
dataPromise.set(.single(TwoStepVerificationUnlockSettingsControllerData.access(configuration: .notSet(pendingEmail: nil))))
|
||||||
|
controller?.view.endEditing(true)
|
||||||
|
controller?.dismiss()
|
||||||
|
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.TwoStepAuth_DisableSuccess, false)), nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}, error: { _ in
|
}, error: { _ in
|
||||||
@ -506,7 +538,40 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
|
|||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.TwoStepAuth_RecoveryUnavailable, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
if let pendingResetTimestamp = pendingResetTimestamp {
|
||||||
|
let remainingSeconds = pendingResetTimestamp - Int32(Date().timeIntervalSince1970)
|
||||||
|
if remainingSeconds <= 0 {
|
||||||
|
let _ = (requestTwoStepPasswordReset(network: context.account.network)
|
||||||
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
|
switch result {
|
||||||
|
case .done, .waitingForReset:
|
||||||
|
dataPromise.set(twoStepVerificationConfiguration(account: context.account)
|
||||||
|
|> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil))
|
||||||
|
})
|
||||||
|
case .declined:
|
||||||
|
break
|
||||||
|
case let .error(reason):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetTitle, text: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.TwoStepAuth_RecoveryUnavailableResetAction, action: {
|
||||||
|
let _ = (requestTwoStepPasswordReset(network: context.account.network)
|
||||||
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
|
switch result {
|
||||||
|
case .done, .waitingForReset:
|
||||||
|
dataPromise.set(twoStepVerificationConfiguration(account: context.account)
|
||||||
|
|> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil))
|
||||||
|
})
|
||||||
|
case .declined:
|
||||||
|
break
|
||||||
|
case let .error(reason):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case .notSet:
|
case .notSet:
|
||||||
break
|
break
|
||||||
@ -762,12 +827,62 @@ func twoStepVerificationUnlockSettingsController(context: AccountContext, mode:
|
|||||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}, declinePasswordReset: {
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
presentControllerImpl?(textAlertController(context: context, title: presentationData.strings.TwoStepAuth_CancelResetTitle, text: presentationData.strings.TwoStepAuth_CancelResetText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Yes, action: {
|
||||||
|
let _ = (declineTwoStepPasswordReset(network: context.account.network)
|
||||||
|
|> deliverOnMainQueue).start(completed: {
|
||||||
|
dataPromise.set(twoStepVerificationConfiguration(account: context.account)
|
||||||
|
|> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_No, action: {
|
||||||
|
})]), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
}, resetPassword: {
|
||||||
|
let _ = (requestTwoStepPasswordReset(network: context.account.network)
|
||||||
|
|> deliverOnMainQueue).start(next: { result in
|
||||||
|
switch result {
|
||||||
|
case .done:
|
||||||
|
dismissImpl?()
|
||||||
|
case .waitingForReset:
|
||||||
|
dataPromise.set(twoStepVerificationConfiguration(account: context.account)
|
||||||
|
|> map { TwoStepVerificationUnlockSettingsControllerData.access(configuration: TwoStepVerificationAccessConfiguration(configuration: $0, password: nil))
|
||||||
|
})
|
||||||
|
case .declined:
|
||||||
|
break
|
||||||
|
case let .error(reason):
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
var initialFocusImpl: (() -> Void)?
|
var initialFocusImpl: (() -> Void)?
|
||||||
var didAppear = false
|
var didAppear = false
|
||||||
|
|
||||||
|
let dataWithTimer = dataPromise.get()
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|> mapToSignal { data -> Signal<TwoStepVerificationUnlockSettingsControllerData, NoError> in
|
||||||
|
switch data {
|
||||||
|
case let .access(configuration):
|
||||||
|
if let configuration = configuration {
|
||||||
|
switch configuration {
|
||||||
|
case let .set(_, _, _, pendingResetTimestamp):
|
||||||
|
if pendingResetTimestamp != nil {
|
||||||
|
return .single(data)
|
||||||
|
|> then(.complete() |> delay(0.5, queue: .mainQueue()))
|
||||||
|
|> restart
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return .single(data)
|
||||||
|
}
|
||||||
|
|
||||||
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), dataPromise.get() |> deliverOnMainQueue) |> deliverOnMainQueue
|
let signal = combineLatest(context.sharedContext.presentationData, statePromise.get(), dataWithTimer |> deliverOnMainQueue) |> deliverOnMainQueue
|
||||||
|> map { presentationData, state, data -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|> map { presentationData, state, data -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||||
var rightNavigationButton: ItemListNavigationButton?
|
var rightNavigationButton: ItemListNavigationButton?
|
||||||
var emptyStateItem: ItemListControllerEmptyStateItem?
|
var emptyStateItem: ItemListControllerEmptyStateItem?
|
||||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user