Files
Swiftgram/submodules/TelegramCore/Sources/TelegramEngine/SecureId/VerifySecureIdValue.swift
Isaac b5dc0b2fd9 Refactor constructor use sites for types 400-419 to struct pattern
Refactored Api constructors in authorization and channel-related code:
- authorization, authorizationSignUpRequired, sentCode, sentCodeSuccess,
  sentCodePaymentRequired, sentCodeTypeFirebaseSms, and related types
- channelParticipant, channelParticipants, sendAsPeers, adminLogResults
- chatlistInvite, chatlistInviteAlready, chatlistUpdates, exportedChatlistInvite
- popularAppBots, sponsoredMessageReportResultChooseOption, and others

Fixed variable shadowing issues where 'user' was extracted and then
immediately shadowed by TelegramUser initialization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 23:15:21 +08:00

116 lines
5.0 KiB
Swift

import Foundation
import Postbox
import MtProtoKit
import SwiftSignalKit
import TelegramApi
public enum SecureIdPreparePhoneVerificationError {
case generic
case flood
}
public struct SecureIdPreparePhoneVerificationPayload {
public let type: SentAuthorizationCodeType
public let nextType: AuthorizationCodeNextType?
public let timeout: Int32?
let phone: String
let phoneCodeHash: String
}
public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPhoneValue) -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> {
return network.request(Api.functions.account.sendVerifyPhoneCode(phoneNumber: value.phone, settings: .codeSettings(.init(flags: 0, logoutTokens: nil, token: nil, appSandbox: nil))), automaticFloodWait: false)
|> mapError { error -> SecureIdPreparePhoneVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .flood
}
return .generic
}
|> mapToSignal { sentCode -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> in
switch sentCode {
case let .sentCode(sentCodeData):
let (type, phoneCodeHash, nextType, timeout) = (sentCodeData.type, sentCodeData.phoneCodeHash, sentCodeData.nextType, sentCodeData.timeout)
return .single(SecureIdPreparePhoneVerificationPayload(type: SentAuthorizationCodeType(apiType: type), nextType: nextType.flatMap(AuthorizationCodeNextType.init), timeout: timeout, phone: value.phone, phoneCodeHash: phoneCodeHash))
case .sentCodeSuccess, .sentCodePaymentRequired:
return .never()
}
}
}
public enum SecureIdCommitPhoneVerificationError {
case generic
case flood
case invalid
}
public func secureIdCommitPhoneVerification(postbox: Postbox, network: Network, context: SecureIdAccessContext, payload: SecureIdPreparePhoneVerificationPayload, code: String) -> Signal<SecureIdValueWithContext, SecureIdCommitPhoneVerificationError> {
return network.request(Api.functions.account.verifyPhone(phoneNumber: payload.phone, phoneCodeHash: payload.phoneCodeHash, phoneCode: code))
|> mapError { error -> SecureIdCommitPhoneVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .flood
} else if error.errorDescription == "PHONE_CODE_INVALID" {
return .invalid
}
return .generic
}
|> mapToSignal { _ -> Signal<SecureIdValueWithContext, SecureIdCommitPhoneVerificationError> in
return saveSecureIdValue(postbox: postbox, network: network, context: context, value: .phone(SecureIdPhoneValue(phone: payload.phone)), uploadedFiles: [:])
|> mapError { _ -> SecureIdCommitPhoneVerificationError in
return .generic
}
}
}
public enum SecureIdPrepareEmailVerificationError {
case generic
case invalidEmail
case flood
}
public struct SecureIdPrepareEmailVerificationPayload {
let email: String
public let length: Int32
}
public func secureIdPrepareEmailVerification(network: Network, value: SecureIdEmailValue) -> Signal<SecureIdPrepareEmailVerificationPayload, SecureIdPrepareEmailVerificationError> {
return network.request(Api.functions.account.sendVerifyEmailCode(purpose: .emailVerifyPurposePassport, email: value.email), automaticFloodWait: false)
|> mapError { error -> SecureIdPrepareEmailVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .flood
} else if error.errorDescription.hasPrefix("EMAIL_INVALID") {
return .invalidEmail
}
return .generic
}
|> map { sentCode -> SecureIdPrepareEmailVerificationPayload in
switch sentCode {
case let .sentEmailCode(sentEmailCodeData):
let length = sentEmailCodeData.length
return SecureIdPrepareEmailVerificationPayload(email: value.email, length: length)
}
}
}
public enum SecureIdCommitEmailVerificationError {
case generic
case flood
case invalid
}
public func secureIdCommitEmailVerification(postbox: Postbox, network: Network, context: SecureIdAccessContext, payload: SecureIdPrepareEmailVerificationPayload, code: String) -> Signal<SecureIdValueWithContext, SecureIdCommitEmailVerificationError> {
return network.request(Api.functions.account.verifyEmail(purpose: .emailVerifyPurposePassport, verification: .emailVerificationCode(.init(code: code))), automaticFloodWait: false)
|> mapError { error -> SecureIdCommitEmailVerificationError in
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
return .flood
}
return .generic
}
|> mapToSignal { _ -> Signal<SecureIdValueWithContext, SecureIdCommitEmailVerificationError> in
return saveSecureIdValue(postbox: postbox, network: network, context: context, value: .email(SecureIdEmailValue(email: payload.email)), uploadedFiles: [:])
|> mapError { _ -> SecureIdCommitEmailVerificationError in
return .generic
}
}
}