Password reset fixes

This commit is contained in:
Ali
2021-07-06 03:27:53 +04:00
parent ad5d4f5c75
commit a2f0f5b1ce
15 changed files with 4885 additions and 4972 deletions

View File

@@ -342,30 +342,6 @@ public enum PasswordRecoveryOption {
case email(pattern: String)
}
public func requestPasswordRecovery(account: UnauthorizedAccount) -> Signal<PasswordRecoveryOption, PasswordRecoveryRequestError> {
return account.network.request(Api.functions.auth.requestPasswordRecovery())
|> map(Optional.init)
|> `catch` { error -> Signal<Api.auth.PasswordRecovery?, PasswordRecoveryRequestError> in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .fail(.limitExceeded)
} else if error.errorDescription.hasPrefix("PASSWORD_RECOVERY_NA") {
return .single(nil)
} else {
return .fail(.generic)
}
}
|> map { result -> PasswordRecoveryOption in
if let result = result {
switch result {
case let .passwordRecovery(emailPattern):
return .email(pattern: emailPattern)
}
} else {
return .none
}
}
}
public enum PasswordRecoveryError {
case invalidCode
case limitExceeded
@@ -373,7 +349,7 @@ public enum PasswordRecoveryError {
case generic
}
public func checkPasswordRecoveryCode(network: Network, code: String) -> Signal<Never, PasswordRecoveryError> {
func _internal_checkPasswordRecoveryCode(network: Network, code: String) -> Signal<Never, PasswordRecoveryError> {
return network.request(Api.functions.auth.checkRecoveryPassword(code: code), automaticFloodWait: false)
|> mapError { error -> PasswordRecoveryError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
@@ -389,12 +365,40 @@ public func checkPasswordRecoveryCode(network: Network, code: String) -> Signal<
}
}
func _internal_performPasswordRecovery(accountManager: AccountManager, account: UnauthorizedAccount, code: String, syncContacts: Bool, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal<Void, PasswordRecoveryError> {
return _internal_twoStepAuthData(account.network)
public final class RecoveredAccountData {
let authorization: Api.auth.Authorization
init(authorization: Api.auth.Authorization) {
self.authorization = authorization
}
}
public func loginWithRecoveredAccountData(accountManager: AccountManager, account: UnauthorizedAccount, recoveredAccountData: RecoveredAccountData, syncContacts: Bool) -> Signal<Never, NoError> {
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
switch recoveredAccountData.authorization {
case let .authorization(_, _, user):
let user = TelegramUser(user: user)
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
transaction.setState(state)
return accountManager.transaction { transaction -> Void in
switchToAuthorizedAccount(transaction: transaction, account: account)
}
case .authorizationSignUpRequired:
return .complete()
}
}
|> switchToLatest
|> ignoreValues
}
func _internal_performPasswordRecovery(network: Network, code: String, updatedPassword: UpdatedTwoStepVerificationPassword) -> Signal<RecoveredAccountData, PasswordRecoveryError> {
return _internal_twoStepAuthData(network)
|> mapError { _ -> PasswordRecoveryError in
return .generic
}
|> mapToSignal { authData -> Signal<Void, PasswordRecoveryError> in
|> mapToSignal { authData -> Signal<RecoveredAccountData, PasswordRecoveryError> in
let newSettings: Api.account.PasswordInputSettings?
switch updatedPassword {
case .none:
@@ -405,7 +409,7 @@ func _internal_performPasswordRecovery(accountManager: AccountManager, account:
flags |= (1 << 1)
}
guard let (updatedPasswordHash, updatedPasswordDerivation) = passwordUpdateKDF(encryptionProvider: account.network.encryptionProvider, password: password, derivation: authData.nextPasswordDerivation) else {
guard let (updatedPasswordHash, updatedPasswordDerivation) = passwordUpdateKDF(encryptionProvider: network.encryptionProvider, password: password, derivation: authData.nextPasswordDerivation) else {
return .fail(.invalidCode)
}
@@ -416,7 +420,7 @@ func _internal_performPasswordRecovery(accountManager: AccountManager, account:
if newSettings != nil {
flags |= 1 << 0
}
return account.network.request(Api.functions.auth.recoverPassword(flags: flags, code: code, newSettings: newSettings), automaticFloodWait: false)
return network.request(Api.functions.auth.recoverPassword(flags: flags, code: code, newSettings: newSettings), automaticFloodWait: false)
|> mapError { error -> PasswordRecoveryError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .limitExceeded
@@ -426,24 +430,8 @@ func _internal_performPasswordRecovery(accountManager: AccountManager, account:
return .invalidCode
}
}
|> mapToSignal { result -> Signal<Void, PasswordRecoveryError> in
return account.postbox.transaction { transaction -> Signal<Void, NoError> in
switch result {
case let .authorization(_, _, user):
let user = TelegramUser(user: user)
let state = AuthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, peerId: user.id, state: nil)
initializedAppSettingsAfterLogin(transaction: transaction, appVersion: account.networkArguments.appVersion, syncContacts: syncContacts)
transaction.setState(state)
return accountManager.transaction { transaction -> Void in
switchToAuthorizedAccount(transaction: transaction, account: account)
}
case .authorizationSignUpRequired:
return .complete()
}
}
|> switchToLatest
|> mapError { _ -> PasswordRecoveryError in }
|> mapToSignal { result -> Signal<RecoveredAccountData, PasswordRecoveryError> in
return .single(RecoveredAccountData(authorization: result))
}
}
}