From 367774a3202da4def05fcbd29683689f2aff85bd Mon Sep 17 00:00:00 2001 From: Ali <> Date: Fri, 13 Dec 2019 17:36:16 +0400 Subject: [PATCH] Support QR login with password --- .../TelegramCore/Sources/AuthTransfer.swift | 61 +++++++++++++++++-- ...tionSequencePhoneEntryControllerNode.swift | 6 +- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/submodules/TelegramCore/Sources/AuthTransfer.swift b/submodules/TelegramCore/Sources/AuthTransfer.swift index 4480abb041..232dd17f4f 100644 --- a/submodules/TelegramCore/Sources/AuthTransfer.swift +++ b/submodules/TelegramCore/Sources/AuthTransfer.swift @@ -24,20 +24,49 @@ public struct AuthTransferTokenInfo { public enum ExportAuthTransferTokenError { case generic + case limitExceeded } public enum ExportAuthTransferTokenResult { case displayToken(AuthTransferExportedToken) case changeAccountAndRetry(UnauthorizedAccount) case loggedIn + case passwordRequested } public func exportAuthTransferToken(accountManager: AccountManager, account: UnauthorizedAccount, otherAccountUserIds: [Int32], syncContacts: Bool) -> Signal { return account.network.request(Api.functions.auth.exportLoginToken(apiId: account.networkArguments.apiId, apiHash: account.networkArguments.apiHash, exceptIds: otherAccountUserIds)) - |> mapError { _ -> ExportAuthTransferTokenError in - return .generic + |> map(Optional.init) + |> `catch` { error -> Signal in + if error.errorDescription == "SESSION_PASSWORD_NEEDED" { + return account.network.request(Api.functions.account.getPassword(), automaticFloodWait: false) + |> mapError { error -> ExportAuthTransferTokenError in + if error.errorDescription.hasPrefix("FLOOD_WAIT") { + return .limitExceeded + } else { + return .generic + } + } + |> mapToSignal { result -> Signal in + switch result { + case let .password(password): + return account.postbox.transaction { transaction -> Api.auth.LoginToken? in + transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: password.hint ?? "", number: nil, code: nil, suggestReset: false, syncContacts: syncContacts))) + return nil + } + |> castError(ExportAuthTransferTokenError.self) + + return .single(nil) + } + } + } else { + return .fail(.generic) + } } |> mapToSignal { result -> Signal in + guard let result = result else { + return .single(.passwordRequested) + } switch result { case let .loginToken(expires, token): return .single(.displayToken(AuthTransferExportedToken(value: token.makeData(), validUntil: expires))) @@ -47,8 +76,32 @@ public func exportAuthTransferToken(accountManager: AccountManager, account: Una |> castError(ExportAuthTransferTokenError.self) |> mapToSignal { updatedAccount -> Signal in return updatedAccount.network.request(Api.functions.auth.importLoginToken(token: token)) - |> mapError { _ -> ExportAuthTransferTokenError in - return .generic + |> map(Optional.init) + |> `catch` { error -> Signal in + if error.errorDescription == "SESSION_PASSWORD_NEEDED" { + return account.network.request(Api.functions.account.getPassword(), automaticFloodWait: false) + |> mapError { error -> ExportAuthTransferTokenError in + if error.errorDescription.hasPrefix("FLOOD_WAIT") { + return .limitExceeded + } else { + return .generic + } + } + |> mapToSignal { result -> Signal in + switch result { + case let .password(password): + return account.postbox.transaction { transaction -> Api.auth.LoginToken? in + transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: password.hint ?? "", number: nil, code: nil, suggestReset: false, syncContacts: syncContacts))) + return nil + } + |> castError(ExportAuthTransferTokenError.self) + + return .single(nil) + } + } + } else { + return .fail(.generic) + } } |> mapToSignal { result -> Signal in switch result { diff --git a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift index da12563150..c887a828af 100644 --- a/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift +++ b/submodules/TelegramUI/TelegramUI/AuthorizationSequencePhoneEntryControllerNode.swift @@ -315,7 +315,9 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { super.didLoad() self.titleNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.debugTap(_:)))) - //self.noticeNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.debugQrTap(_:)))) + #if DEBUG + self.noticeNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.debugQrTap(_:)))) + #endif } func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { @@ -452,7 +454,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode { self?.refreshQrToken() })) strongSelf.refreshQrToken() - case .loggedIn: + case .loggedIn, .passwordRequested: strongSelf.exportTokenDisposable.set(nil) } }))