Fix firebase

This commit is contained in:
Isaac 2024-05-15 19:32:06 +04:00
parent 2d06c977ed
commit 95ffacf97c
7 changed files with 146 additions and 27 deletions

View File

@ -886,6 +886,7 @@ public enum CollectibleItemInfoScreenSubject {
public protocol SharedAccountContext: AnyObject {
var sharedContainerPath: String { get }
var basePath: String { get }
var networkArguments: NetworkInitializationArguments { get }
var mainWindow: Window1? { get }
var accountManager: AccountManager<TelegramAccountManagerTypes> { get }
var appLockContext: AppLockContext { get }

View File

@ -229,7 +229,13 @@ func changePhoneNumberCodeController(context: AccountContext, phoneNumber: Strin
|> take(1)
|> mapToSignal { _ -> Signal<Void, NoError> in
return Signal { subscriber in
return context.engine.accountData.requestNextChangeAccountPhoneNumberVerification(phoneNumber: phoneNumber, phoneCodeHash: data.hash).start(next: { next in
return context.engine.accountData.requestNextChangeAccountPhoneNumberVerification(
phoneNumber: phoneNumber,
phoneCodeHash: data.hash,
apiId: context.sharedContext.networkArguments.apiId,
apiHash: context.sharedContext.networkArguments.apiHash,
firebaseSecretStream: context.sharedContext.firebaseSecretStream
).start(next: { next in
currentDataPromise?.set(.single(next))
}, error: { error in

View File

@ -36,7 +36,13 @@ public func ChangePhoneNumberController(context: AccountContext) -> ViewControll
authorizationPushConfiguration
|> castError(RequestChangeAccountPhoneNumberVerificationError.self)
|> mapToSignal { authorizationPushConfiguration in
return context.engine.accountData.requestChangeAccountPhoneNumberVerification(phoneNumber: phoneNumber, pushNotificationConfiguration: authorizationPushConfiguration, firebaseSecretStream: context.sharedContext.firebaseSecretStream)
return context.engine.accountData.requestChangeAccountPhoneNumberVerification(
apiId: context.sharedContext.networkArguments.apiId,
apiHash: context.sharedContext.networkArguments.apiHash,
phoneNumber: phoneNumber,
pushNotificationConfiguration: authorizationPushConfiguration,
firebaseSecretStream: context.sharedContext.firebaseSecretStream
)
}
|> deliverOnMainQueue).start(next: { [weak controller] next in
controller?.inProgress = false

View File

@ -129,11 +129,10 @@ enum SendFirebaseAuthorizationCodeError {
case generic
}
private func sendFirebaseAuthorizationCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, phoneNumber: String, apiId: Int32, apiHash: String, phoneCodeHash: String, timeout: Int32?, firebaseSecret: String, syncContacts: Bool) -> Signal<Bool, SendFirebaseAuthorizationCodeError> {
//auth.requestFirebaseSms#89464b50 flags:# phone_number:string phone_code_hash:string safety_net_token:flags.0?string ios_push_secret:flags.1?string = Bool;
func sendFirebaseAuthorizationCode(network: Network, phoneNumber: String, apiId: Int32, apiHash: String, phoneCodeHash: String, timeout: Int32?, firebaseSecret: String) -> Signal<Bool, SendFirebaseAuthorizationCodeError> {
var flags: Int32 = 0
flags |= 1 << 1
return account.network.request(Api.functions.auth.requestFirebaseSms(flags: flags, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, safetyNetToken: nil, playIntegrityToken: nil, iosPushSecret: firebaseSecret))
return network.request(Api.functions.auth.requestFirebaseSms(flags: flags, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, safetyNetToken: nil, playIntegrityToken: nil, iosPushSecret: firebaseSecret))
|> mapError { _ -> SendFirebaseAuthorizationCodeError in
return .generic
}
@ -295,10 +294,10 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
|> castError(AuthorizationCodeRequestError.self)
|> mapToSignal { firebaseSecret -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> in
guard let firebaseSecret = firebaseSecret else {
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: phoneNumber, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream)
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: phoneNumber, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream, reason: .firebasePushTimeout)
}
return sendFirebaseAuthorizationCode(accountManager: accountManager, account: account, phoneNumber: phoneNumber, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret, syncContacts: syncContacts)
return sendFirebaseAuthorizationCode(network: account.network, phoneNumber: phoneNumber, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret)
|> `catch` { _ -> Signal<Bool, SendFirebaseAuthorizationCodeError> in
return .single(false)
}
@ -332,7 +331,7 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
}
|> castError(AuthorizationCodeRequestError.self)
} else {
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: phoneNumber, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream)
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: phoneNumber, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream, reason: .firebaseSendCodeError)
}
}
}
@ -394,8 +393,20 @@ public func sendAuthorizationCode(accountManager: AccountManager<TelegramAccount
}
}
private func internalResendAuthorizationCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, number: String, apiId: Int32, apiHash: String, hash: String, syncContacts: Bool, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> {
return account.network.request(Api.functions.auth.resendCode(flags: 0, phoneNumber: number, phoneCodeHash: hash, reason: nil), automaticFloodWait: false)
enum ResendAuthorizationCodeReason: String {
case firebasePushTimeout = "FIREBASE_PUSH_TIMEOUT"
case firebaseSendCodeError = "FIREBASE_SEND_CODE_ERROR"
}
private func internalResendAuthorizationCode(accountManager: AccountManager<TelegramAccountManagerTypes>, account: UnauthorizedAccount, number: String, apiId: Int32, apiHash: String, hash: String, syncContacts: Bool, firebaseSecretStream: Signal<[String: String], NoError>, reason: ResendAuthorizationCodeReason?) -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> {
var flags: Int32 = 0
var mappedReason: String?
if let reason {
flags |= 1 << 0
mappedReason = reason.rawValue
}
return account.network.request(Api.functions.auth.resendCode(flags: flags, phoneNumber: number, phoneCodeHash: hash, reason: mappedReason), automaticFloodWait: false)
|> mapError { error -> AuthorizationCodeRequestError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .limitExceeded
@ -441,10 +452,10 @@ private func internalResendAuthorizationCode(accountManager: AccountManager<Tele
|> castError(AuthorizationCodeRequestError.self)
|> mapToSignal { firebaseSecret -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> in
guard let firebaseSecret = firebaseSecret else {
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream)
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream, reason: .firebasePushTimeout)
}
return sendFirebaseAuthorizationCode(accountManager: accountManager, account: account, phoneNumber: number, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret, syncContacts: syncContacts)
return sendFirebaseAuthorizationCode(network: account.network, phoneNumber: number, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret)
|> `catch` { _ -> Signal<Bool, SendFirebaseAuthorizationCodeError> in
return .single(false)
}
@ -478,7 +489,7 @@ private func internalResendAuthorizationCode(accountManager: AccountManager<Tele
}
|> castError(AuthorizationCodeRequestError.self)
} else {
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream)
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream, reason: .firebaseSendCodeError)
}
}
}
@ -583,10 +594,10 @@ public func resendAuthorizationCode(accountManager: AccountManager<TelegramAccou
|> castError(AuthorizationCodeRequestError.self)
|> mapToSignal { firebaseSecret -> Signal<SendAuthorizationCodeResult, AuthorizationCodeRequestError> in
guard let firebaseSecret = firebaseSecret else {
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream)
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream, reason: .firebasePushTimeout)
}
return sendFirebaseAuthorizationCode(accountManager: accountManager, account: account, phoneNumber: number, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret, syncContacts: syncContacts)
return sendFirebaseAuthorizationCode(network: account.network, phoneNumber: number, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret)
|> `catch` { _ -> Signal<Bool, SendFirebaseAuthorizationCodeError> in
return .single(false)
}
@ -602,7 +613,7 @@ public func resendAuthorizationCode(accountManager: AccountManager<TelegramAccou
}
|> castError(AuthorizationCodeRequestError.self)
} else {
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream)
return internalResendAuthorizationCode(accountManager: accountManager, account: account, number: number, apiId: apiId, apiHash: apiHash, hash: phoneCodeHash, syncContacts: syncContacts, firebaseSecretStream: firebaseSecretStream, reason: .firebaseSendCodeError)
}
}
}

View File

@ -36,7 +36,7 @@ public enum RequestChangeAccountPhoneNumberVerificationError {
case generic
}
func _internal_requestChangeAccountPhoneNumberVerification(account: Account, phoneNumber: String, pushNotificationConfiguration: AuthorizationCodePushNotificationConfiguration?, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
func _internal_requestChangeAccountPhoneNumberVerification(account: Account, apiId: Int32, apiHash: String, phoneNumber: String, pushNotificationConfiguration: AuthorizationCodePushNotificationConfiguration?, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
var flags: Int32 = 0
flags |= 1 << 5 //allowMissedCall
@ -66,20 +66,68 @@ func _internal_requestChangeAccountPhoneNumberVerification(account: Account, pho
}
|> mapToSignal { sentCode -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
switch sentCode {
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
case let .sentCode(_, type, phoneCodeHash, nextType, codeTimeout):
var parsedNextType: AuthorizationCodeNextType?
if let nextType = nextType {
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
}
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType))
if case let .sentCodeTypeFirebaseSms(_, _, _, receipt, pushTimeout, _) = type {
return firebaseSecretStream
|> map { mapping -> String? in
guard let receipt = receipt else {
return nil
}
if let value = mapping[receipt] {
return value
}
if receipt == "" && mapping.count == 1 {
return mapping.first?.value
}
return nil
}
|> filter { $0 != nil }
|> take(1)
|> timeout(Double(pushTimeout ?? 15), queue: .mainQueue(), alternate: .single(nil))
|> castError(RequestChangeAccountPhoneNumberVerificationError.self)
|> mapToSignal { firebaseSecret -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
guard let firebaseSecret = firebaseSecret else {
return internalResendChangeAccountPhoneNumberVerification(account: account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, apiId: apiId, apiHash: apiHash, firebaseSecretStream: firebaseSecretStream, reason: .firebasePushTimeout)
}
return sendFirebaseAuthorizationCode(network: account.network, phoneNumber: phoneNumber, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret)
|> `catch` { _ -> Signal<Bool, SendFirebaseAuthorizationCodeError> in
return .single(false)
}
|> mapError { _ -> RequestChangeAccountPhoneNumberVerificationError in
return .generic
}
|> mapToSignal { success -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
if success {
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: codeTimeout, nextType: parsedNextType))
} else {
return internalResendChangeAccountPhoneNumberVerification(account: account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, apiId: apiId, apiHash: apiHash, firebaseSecretStream: firebaseSecretStream, reason: .firebaseSendCodeError)
}
}
}
} else {
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: codeTimeout, nextType: parsedNextType))
}
case .sentCodeSuccess:
return .never()
}
}
}
func _internal_requestNextChangeAccountPhoneNumberVerification(account: Account, phoneNumber: String, phoneCodeHash: String) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
return account.network.request(Api.functions.auth.resendCode(flags: 0, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, reason: nil), automaticFloodWait: false)
private func internalResendChangeAccountPhoneNumberVerification(account: Account, phoneNumber: String, phoneCodeHash: String, apiId: Int32, apiHash: String, firebaseSecretStream: Signal<[String: String], NoError>, reason: ResendAuthorizationCodeReason?) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
var flags: Int32 = 0
var mappedReason: String?
if let reason {
flags |= 1 << 0
mappedReason = reason.rawValue
}
return account.network.request(Api.functions.auth.resendCode(flags: flags, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, reason: mappedReason), automaticFloodWait: false)
|> mapError { error -> RequestChangeAccountPhoneNumberVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .limitExceeded
@ -93,18 +141,63 @@ func _internal_requestNextChangeAccountPhoneNumberVerification(account: Account,
}
|> mapToSignal { sentCode -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
switch sentCode {
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
case let .sentCode(_, type, phoneCodeHash, nextType, codeTimeout):
var parsedNextType: AuthorizationCodeNextType?
if let nextType = nextType {
parsedNextType = AuthorizationCodeNextType(apiType: nextType)
}
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: timeout, nextType: parsedNextType))
if case let .sentCodeTypeFirebaseSms(_, _, _, receipt, pushTimeout, _) = type {
return firebaseSecretStream
|> map { mapping -> String? in
guard let receipt = receipt else {
return nil
}
if let value = mapping[receipt] {
return value
}
if receipt == "" && mapping.count == 1 {
return mapping.first?.value
}
return nil
}
|> filter { $0 != nil }
|> take(1)
|> timeout(Double(pushTimeout ?? 15), queue: .mainQueue(), alternate: .single(nil))
|> castError(RequestChangeAccountPhoneNumberVerificationError.self)
|> mapToSignal { firebaseSecret -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
guard let firebaseSecret = firebaseSecret else {
return internalResendChangeAccountPhoneNumberVerification(account: account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, apiId: apiId, apiHash: apiHash, firebaseSecretStream: firebaseSecretStream, reason: .firebasePushTimeout)
}
return sendFirebaseAuthorizationCode(network: account.network, phoneNumber: phoneNumber, apiId: apiId, apiHash: apiHash, phoneCodeHash: phoneCodeHash, timeout: codeTimeout, firebaseSecret: firebaseSecret)
|> `catch` { _ -> Signal<Bool, SendFirebaseAuthorizationCodeError> in
return .single(false)
}
|> mapError { _ -> RequestChangeAccountPhoneNumberVerificationError in
return .generic
}
|> mapToSignal { success -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> in
if success {
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: codeTimeout, nextType: parsedNextType))
} else {
return internalResendChangeAccountPhoneNumberVerification(account: account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, apiId: apiId, apiHash: apiHash, firebaseSecretStream: firebaseSecretStream, reason: .firebaseSendCodeError)
}
}
}
} else {
return .single(ChangeAccountPhoneNumberData(type: SentAuthorizationCodeType(apiType: type), hash: phoneCodeHash, timeout: codeTimeout, nextType: parsedNextType))
}
case .sentCodeSuccess:
return .never()
}
}
}
func _internal_requestNextChangeAccountPhoneNumberVerification(account: Account, phoneNumber: String, phoneCodeHash: String, apiId: Int32, apiHash: String, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
return internalResendChangeAccountPhoneNumberVerification(account: account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, apiId: apiId, apiHash: apiHash, firebaseSecretStream: firebaseSecretStream, reason: nil)
}
public enum ChangeAccountPhoneNumberError {
case generic
case invalidCode

View File

@ -15,12 +15,12 @@ public extension TelegramEngine {
return _internal_acceptTermsOfService(account: self.account, id: id)
}
public func requestChangeAccountPhoneNumberVerification(phoneNumber: String, pushNotificationConfiguration: AuthorizationCodePushNotificationConfiguration?, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
return _internal_requestChangeAccountPhoneNumberVerification(account: self.account, phoneNumber: phoneNumber, pushNotificationConfiguration: pushNotificationConfiguration, firebaseSecretStream: firebaseSecretStream)
public func requestChangeAccountPhoneNumberVerification(apiId: Int32, apiHash: String, phoneNumber: String, pushNotificationConfiguration: AuthorizationCodePushNotificationConfiguration?, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
return _internal_requestChangeAccountPhoneNumberVerification(account: self.account, apiId: apiId, apiHash: apiHash, phoneNumber: phoneNumber, pushNotificationConfiguration: pushNotificationConfiguration, firebaseSecretStream: firebaseSecretStream)
}
public func requestNextChangeAccountPhoneNumberVerification(phoneNumber: String, phoneCodeHash: String) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
return _internal_requestNextChangeAccountPhoneNumberVerification(account: self.account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash)
public func requestNextChangeAccountPhoneNumberVerification(phoneNumber: String, phoneCodeHash: String, apiId: Int32, apiHash: String, firebaseSecretStream: Signal<[String: String], NoError>) -> Signal<ChangeAccountPhoneNumberData, RequestChangeAccountPhoneNumberVerificationError> {
return _internal_requestNextChangeAccountPhoneNumberVerification(account: self.account, phoneNumber: phoneNumber, phoneCodeHash: phoneCodeHash, apiId: apiId, apiHash: apiHash, firebaseSecretStream: firebaseSecretStream)
}
public func requestChangeAccountPhoneNumber(phoneNumber: String, phoneCodeHash: String, phoneCode: String) -> Signal<Void, ChangeAccountPhoneNumberError> {

View File

@ -100,6 +100,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
public let applicationBindings: TelegramApplicationBindings
public let sharedContainerPath: String
public let basePath: String
public let networkArguments: NetworkInitializationArguments
public let accountManager: AccountManager<TelegramAccountManagerTypes>
public let appLockContext: AppLockContext
public var notificationController: NotificationContainerController? {
@ -253,6 +254,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
self.applicationBindings = applicationBindings
self.sharedContainerPath = sharedContainerPath
self.basePath = basePath
self.networkArguments = networkArguments
self.accountManager = accountManager
self.navigateToChatImpl = navigateToChat
self.displayUpgradeProgress = displayUpgradeProgress