mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge commit 'e839427846'
This commit is contained in:
commit
0e5337636d
6 changed files with 231 additions and 175 deletions
|
|
@ -192,6 +192,7 @@ public enum ResolvedUrlSettingsSection {
|
|||
case twoStepAuth
|
||||
case enableLog
|
||||
case phonePrivacy
|
||||
case loginEmail
|
||||
}
|
||||
|
||||
public struct ResolvedBotChoosePeerTypes: OptionSet {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ public final class AuthorizationSequenceEmailEntryController: ViewController {
|
|||
}
|
||||
}
|
||||
|
||||
public var authorization: Any?
|
||||
public var authorizationDelegate: Any?
|
||||
|
||||
public init(presentationData: PresentationData, mode: Mode, back: @escaping () -> Void) {
|
||||
self.presentationData = presentationData
|
||||
self.mode = mode
|
||||
|
|
|
|||
|
|
@ -0,0 +1,217 @@
|
|||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
import TelegramCore
|
||||
import AccountContext
|
||||
import TelegramPresentationData
|
||||
import AuthorizationUI
|
||||
import AuthenticationServices
|
||||
import UndoUI
|
||||
|
||||
final class LoginEmailSetupDelegate: NSObject, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
||||
var authorizationCompletion: ((Any) -> Void)?
|
||||
|
||||
private var context: AccountContext
|
||||
init(context: AccountContext) {
|
||||
self.context = context
|
||||
}
|
||||
@available(iOS 13.0, *)
|
||||
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
||||
self.authorizationCompletion?(authorization.credential)
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
|
||||
Logger.shared.log("AppleSignIn", "Failed with error: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||||
return self.context.sharedContext.mainWindow!.viewController!.view.window!
|
||||
}
|
||||
}
|
||||
|
||||
public func loginEmailSetupController(context: AccountContext, emailPattern: String?, navigationController: NavigationController?, completion: @escaping () -> Void) -> ViewController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var dismissEmailControllerImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController) -> Void)?
|
||||
|
||||
let delegate = LoginEmailSetupDelegate(context: context)
|
||||
|
||||
let emailChangeCompletion: (AuthorizationSequenceCodeEntryController?) -> Void = { codeController in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
codeController?.animateSuccess()
|
||||
|
||||
completion()
|
||||
|
||||
Queue.mainQueue().after(0.75) {
|
||||
if let navigationController {
|
||||
let controllers = navigationController.viewControllers.filter { controller in
|
||||
if controller is AuthorizationSequenceEmailEntryController || controller is AuthorizationSequenceCodeEntryController {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
|
||||
Queue.mainQueue().after(0.5, {
|
||||
navigationController.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .emoji(name: "IntroLetter", text: presentationData.strings.Login_EmailChanged), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
||||
return false
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let emailController = AuthorizationSequenceEmailEntryController(presentationData: presentationData, mode: emailPattern != nil ? .change : .setup, back: {
|
||||
dismissEmailControllerImpl?()
|
||||
})
|
||||
emailController.proceedWithEmail = { [weak emailController] email in
|
||||
emailController?.inProgress = true
|
||||
|
||||
let _ = (sendLoginEmailChangeCode(account: context.account, email: email)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
var dismissCodeControllerImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController) -> Void)?
|
||||
|
||||
let codeController = AuthorizationSequenceCodeEntryController(presentationData: presentationData, back: {
|
||||
dismissCodeControllerImpl?()
|
||||
})
|
||||
|
||||
presentControllerImpl = { [weak codeController] c in
|
||||
codeController?.present(c, in: .window(.root), with: nil)
|
||||
}
|
||||
|
||||
codeController.loginWithCode = { [weak codeController] code in
|
||||
let _ = (verifyLoginEmailChange(account: context.account, code: .emailCode(code))
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
Queue.mainQueue().async {
|
||||
codeController?.inProgress = false
|
||||
|
||||
if case .invalidCode = error {
|
||||
codeController?.animateError(text: presentationData.strings.Login_WrongCodeError)
|
||||
} else {
|
||||
var resetCode = false
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
resetCode = true
|
||||
text = presentationData.strings.Login_CodeFloodError
|
||||
case .invalidCode:
|
||||
resetCode = true
|
||||
text = presentationData.strings.Login_InvalidCodeError
|
||||
case .generic:
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
case .codeExpired:
|
||||
text = presentationData.strings.Login_CodeExpired
|
||||
case .timeout:
|
||||
text = presentationData.strings.Login_NetworkError
|
||||
case .invalidEmailToken:
|
||||
text = presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .emailNotAllowed:
|
||||
text = presentationData.strings.Login_EmailNotAllowedError
|
||||
}
|
||||
|
||||
if resetCode {
|
||||
codeController?.resetCode()
|
||||
}
|
||||
|
||||
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||
}
|
||||
}
|
||||
}, completed: { [weak codeController] in
|
||||
emailChangeCompletion(codeController)
|
||||
})
|
||||
}
|
||||
codeController.updateData(number: "", email: email, codeType: .email(emailPattern: "", length: data.length, resetAvailablePeriod: nil, resetPendingDate: nil, appleSignInAllowed: false, setup: true), nextType: nil, timeout: nil, termsOfService: nil, previousCodeType: nil, isPrevious: false)
|
||||
navigationController?.pushViewController(codeController)
|
||||
dismissCodeControllerImpl = { [weak codeController] in
|
||||
codeController?.dismiss()
|
||||
}
|
||||
}, error: { [weak emailController] error in
|
||||
emailController?.inProgress = false
|
||||
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = presentationData.strings.Login_CodeFloodError
|
||||
case .generic, .codeExpired:
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
case .timeout:
|
||||
text = presentationData.strings.Login_NetworkError
|
||||
case .invalidEmail:
|
||||
text = presentationData.strings.Login_InvalidEmailError
|
||||
case .emailNotAllowed:
|
||||
text = presentationData.strings.Login_EmailNotAllowedError
|
||||
}
|
||||
|
||||
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||
}, completed: { [weak emailController] in
|
||||
emailController?.inProgress = false
|
||||
})
|
||||
}
|
||||
emailController.signInWithApple = { [weak emailController] in
|
||||
if #available(iOS 13.0, *) {
|
||||
let appleIdProvider = ASAuthorizationAppleIDProvider()
|
||||
let request = appleIdProvider.createRequest()
|
||||
request.requestedScopes = [.email]
|
||||
|
||||
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
||||
authorizationController.delegate = delegate
|
||||
authorizationController.presentationContextProvider = delegate
|
||||
authorizationController.performRequests()
|
||||
emailController?.authorization = authorizationController
|
||||
emailController?.authorizationDelegate = delegate
|
||||
|
||||
delegate.authorizationCompletion = { [weak emailController] credential in
|
||||
guard let credential = credential as? ASAuthorizationCredential else {
|
||||
return
|
||||
}
|
||||
switch credential {
|
||||
case let appleIdCredential as ASAuthorizationAppleIDCredential:
|
||||
guard let tokenData = appleIdCredential.identityToken, let token = String(data: tokenData, encoding: .utf8) else {
|
||||
emailController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
return
|
||||
}
|
||||
let _ = (verifyLoginEmailChange(account: context.account, code: .appleToken(token))
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = presentationData.strings.Login_CodeFloodError
|
||||
case .generic, .codeExpired:
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
case .invalidCode:
|
||||
text = presentationData.strings.Login_InvalidCodeError
|
||||
case .timeout:
|
||||
text = presentationData.strings.Login_NetworkError
|
||||
case .invalidEmailToken:
|
||||
text = presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .emailNotAllowed:
|
||||
text = presentationData.strings.Login_EmailNotAllowedError
|
||||
}
|
||||
emailController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
}, completed: { [weak emailController] in
|
||||
emailController?.authorization = nil
|
||||
emailController?.authorizationDelegate = nil
|
||||
|
||||
emailChangeCompletion(nil)
|
||||
})
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emailController.updateData(appleSignInAllowed: true)
|
||||
presentControllerImpl = { [weak emailController] c in
|
||||
emailController?.present(c, in: .window(.root), with: nil)
|
||||
}
|
||||
|
||||
dismissEmailControllerImpl = { [weak emailController] in
|
||||
emailController?.dismiss()
|
||||
}
|
||||
return emailController
|
||||
}
|
||||
|
|
@ -1486,33 +1486,7 @@ public func privacyAndSecurityController(
|
|||
controller.didAppear = { _ in
|
||||
updateHasTwoStepAuth()
|
||||
}
|
||||
|
||||
let emailChangeCompletion: (AuthorizationSequenceCodeEntryController?) -> Void = { codeController in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
codeController?.animateSuccess()
|
||||
|
||||
updatedTwoStepAuthData?()
|
||||
|
||||
Queue.mainQueue().after(0.75) {
|
||||
if let navigationController = getNavigationControllerImpl?() {
|
||||
let controllers = navigationController.viewControllers.filter { controller in
|
||||
if controller is AuthorizationSequenceEmailEntryController || controller is AuthorizationSequenceCodeEntryController {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
|
||||
Queue.mainQueue().after(0.5, {
|
||||
navigationController.presentOverlay(controller: UndoOverlayController(presentationData: presentationData, content: .emoji(name: "IntroLetter", text: presentationData.strings.Login_EmailChanged), elevatedLayout: false, animateInAsReplacement: false, action: { _ in
|
||||
return false
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showPrivacySuggestionImpl = {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
if reviewCallPrivacySuggestion {
|
||||
|
|
@ -1557,156 +1531,10 @@ public func privacyAndSecurityController(
|
|||
}
|
||||
|
||||
setupEmailImpl = { emailPattern in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
var dismissEmailControllerImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController) -> Void)?
|
||||
|
||||
let emailController = AuthorizationSequenceEmailEntryController(presentationData: presentationData, mode: emailPattern != nil ? .change : .setup, back: {
|
||||
dismissEmailControllerImpl?()
|
||||
let controller = loginEmailSetupController(context: context, emailPattern: emailPattern, navigationController: getNavigationControllerImpl?(), completion: {
|
||||
updatedTwoStepAuthData?()
|
||||
})
|
||||
emailController.proceedWithEmail = { [weak emailController] email in
|
||||
emailController?.inProgress = true
|
||||
|
||||
actionsDisposable.add((sendLoginEmailChangeCode(account: context.account, email: email)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
var dismissCodeControllerImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController) -> Void)?
|
||||
|
||||
let codeController = AuthorizationSequenceCodeEntryController(presentationData: presentationData, back: {
|
||||
dismissCodeControllerImpl?()
|
||||
})
|
||||
|
||||
presentControllerImpl = { [weak codeController] c in
|
||||
codeController?.present(c, in: .window(.root), with: nil)
|
||||
}
|
||||
|
||||
codeController.loginWithCode = { [weak codeController] code in
|
||||
actionsDisposable.add((verifyLoginEmailChange(account: context.account, code: .emailCode(code))
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
Queue.mainQueue().async {
|
||||
codeController?.inProgress = false
|
||||
|
||||
if case .invalidCode = error {
|
||||
codeController?.animateError(text: presentationData.strings.Login_WrongCodeError)
|
||||
} else {
|
||||
var resetCode = false
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
resetCode = true
|
||||
text = presentationData.strings.Login_CodeFloodError
|
||||
case .invalidCode:
|
||||
resetCode = true
|
||||
text = presentationData.strings.Login_InvalidCodeError
|
||||
case .generic:
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
case .codeExpired:
|
||||
text = presentationData.strings.Login_CodeExpired
|
||||
case .timeout:
|
||||
text = presentationData.strings.Login_NetworkError
|
||||
case .invalidEmailToken:
|
||||
text = presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .emailNotAllowed:
|
||||
text = presentationData.strings.Login_EmailNotAllowedError
|
||||
}
|
||||
|
||||
if resetCode {
|
||||
codeController?.resetCode()
|
||||
}
|
||||
|
||||
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||
}
|
||||
}
|
||||
}, completed: { [weak codeController] in
|
||||
emailChangeCompletion(codeController)
|
||||
}))
|
||||
}
|
||||
codeController.updateData(number: "", email: email, codeType: .email(emailPattern: "", length: data.length, resetAvailablePeriod: nil, resetPendingDate: nil, appleSignInAllowed: false, setup: true), nextType: nil, timeout: nil, termsOfService: nil, previousCodeType: nil, isPrevious: false)
|
||||
pushControllerImpl?(codeController, true)
|
||||
dismissCodeControllerImpl = { [weak codeController] in
|
||||
codeController?.dismiss()
|
||||
}
|
||||
}, error: { [weak emailController] error in
|
||||
emailController?.inProgress = false
|
||||
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = presentationData.strings.Login_CodeFloodError
|
||||
case .generic, .codeExpired:
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
case .timeout:
|
||||
text = presentationData.strings.Login_NetworkError
|
||||
case .invalidEmail:
|
||||
text = presentationData.strings.Login_InvalidEmailError
|
||||
case .emailNotAllowed:
|
||||
text = presentationData.strings.Login_EmailNotAllowedError
|
||||
}
|
||||
|
||||
presentControllerImpl?(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]))
|
||||
}, completed: { [weak emailController] in
|
||||
emailController?.inProgress = false
|
||||
}))
|
||||
}
|
||||
emailController.signInWithApple = { [weak controller, weak emailController] in
|
||||
if #available(iOS 13.0, *) {
|
||||
let appleIdProvider = ASAuthorizationAppleIDProvider()
|
||||
let request = appleIdProvider.createRequest()
|
||||
request.requestedScopes = [.email]
|
||||
|
||||
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
||||
authorizationController.delegate = controller
|
||||
authorizationController.presentationContextProvider = controller
|
||||
authorizationController.performRequests()
|
||||
|
||||
controller?.authorizationCompletion = { [weak controller, weak emailController] credential in
|
||||
guard let credential = credential as? ASAuthorizationCredential else {
|
||||
return
|
||||
}
|
||||
switch credential {
|
||||
case let appleIdCredential as ASAuthorizationAppleIDCredential:
|
||||
guard let tokenData = appleIdCredential.identityToken, let token = String(data: tokenData, encoding: .utf8) else {
|
||||
emailController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
return
|
||||
}
|
||||
actionsDisposable.add((verifyLoginEmailChange(account: context.account, code: .appleToken(token))
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
let text: String
|
||||
switch error {
|
||||
case .limitExceeded:
|
||||
text = presentationData.strings.Login_CodeFloodError
|
||||
case .generic, .codeExpired:
|
||||
text = presentationData.strings.Login_UnknownError
|
||||
case .invalidCode:
|
||||
text = presentationData.strings.Login_InvalidCodeError
|
||||
case .timeout:
|
||||
text = presentationData.strings.Login_NetworkError
|
||||
case .invalidEmailToken:
|
||||
text = presentationData.strings.Login_InvalidEmailTokenError
|
||||
case .emailNotAllowed:
|
||||
text = presentationData.strings.Login_EmailNotAllowedError
|
||||
}
|
||||
emailController?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||
}, completed: { [weak controller] in
|
||||
controller?.authorizationCompletion = nil
|
||||
emailChangeCompletion(nil)
|
||||
}))
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
emailController.updateData(appleSignInAllowed: true)
|
||||
pushControllerImpl?(emailController, true)
|
||||
|
||||
presentControllerImpl = { [weak emailController] c in
|
||||
emailController?.present(c, in: .window(.root), with: nil)
|
||||
}
|
||||
|
||||
dismissEmailControllerImpl = { [weak emailController] in
|
||||
emailController?.dismiss()
|
||||
}
|
||||
pushControllerImpl?(controller, true)
|
||||
}
|
||||
|
||||
return controller
|
||||
|
|
|
|||
|
|
@ -827,6 +827,11 @@ func openResolvedUrlImpl(
|
|||
navigationController.pushViewController(controller)
|
||||
}
|
||||
})
|
||||
case .loginEmail:
|
||||
if let navigationController {
|
||||
let controller = loginEmailSetupController(context: context, emailPattern: nil, navigationController: navigationController, completion: {})
|
||||
navigationController.pushViewController(controller)
|
||||
}
|
||||
}
|
||||
case let .premiumOffer(reference):
|
||||
dismissInput()
|
||||
|
|
|
|||
|
|
@ -1088,6 +1088,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||
section = .enableLog
|
||||
case "phone_privacy":
|
||||
section = .phonePrivacy
|
||||
case "login_email":
|
||||
section = .loginEmail
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue