mirror of
https://github.com/ichmagmaus111/ghostgram.git
synced 2026-07-11 02:13:41 +02:00
Update Ghostgram features
This commit is contained in:
@@ -329,10 +329,10 @@ public func grantSecureIdAccess(network: Network, peerId: PeerId, publicKey: Str
|
||||
|
||||
var valueHashes: [Api.SecureValueHash] = []
|
||||
for value in values {
|
||||
valueHashes.append(.secureValueHash(type: apiSecureValueType(value: value.value), hash: Buffer(data: value.opaqueHash)))
|
||||
valueHashes.append(.secureValueHash(.init(type: apiSecureValueType(value: value.value), hash: Buffer(data: value.opaqueHash))))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.account.acceptAuthorization(botId: peerId.id._internalGetInt64Value(), scope: scope, publicKey: publicKey, valueHashes: valueHashes, credentials: .secureCredentialsEncrypted(data: Buffer(data: encryptedCredentialsData), hash: Buffer(data: decryptedCredentialsHash), secret: Buffer(data: encryptedSecretData))))
|
||||
return network.request(Api.functions.account.acceptAuthorization(botId: peerId.id._internalGetInt64Value(), scope: scope, publicKey: publicKey, valueHashes: valueHashes, credentials: .secureCredentialsEncrypted(.init(data: Buffer(data: encryptedCredentialsData), hash: Buffer(data: decryptedCredentialsHash), secret: Buffer(data: encryptedSecretData)))))
|
||||
|> mapError { error -> GrantSecureIdAccessError in
|
||||
return .generic
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ private func parseSecureValueType(_ type: Api.SecureValueType, selfie: Bool, tra
|
||||
|
||||
private func parseSecureData(_ value: Api.SecureData) -> (data: Data, hash: Data, secret: Data) {
|
||||
switch value {
|
||||
case let .secureData(data, dataHash, secret):
|
||||
case let .secureData(secureDataData):
|
||||
let (data, dataHash, secret) = (secureDataData.data, secureDataData.dataHash, secureDataData.secret)
|
||||
return (data.makeData(), dataHash.makeData(), secret.makeData())
|
||||
}
|
||||
}
|
||||
@@ -55,7 +56,8 @@ struct ParsedSecureValue {
|
||||
|
||||
func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, errors: [Api.SecureValueError]) -> ParsedSecureValue? {
|
||||
switch value {
|
||||
case let .secureValue(_, type, data, frontSide, reverseSide, selfie, translation, files, plainData, hash):
|
||||
case let .secureValue(secureValueData):
|
||||
let (_, type, data, frontSide, reverseSide, selfie, translation, files, plainData, hash) = (secureValueData.flags, secureValueData.type, secureValueData.data, secureValueData.frontSide, secureValueData.reverseSide, secureValueData.selfie, secureValueData.translation, secureValueData.files, secureValueData.plainData, secureValueData.hash)
|
||||
let parsedFileReferences = files.flatMap { $0.compactMap(SecureIdFileReference.init) } ?? []
|
||||
let parsedFiles = parsedFileReferences.map(SecureIdVerificationDocumentReference.remote)
|
||||
let parsedTranslationReferences = translation.flatMap { $0.compactMap(SecureIdFileReference.init) } ?? []
|
||||
@@ -204,7 +206,8 @@ func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, er
|
||||
return nil
|
||||
}
|
||||
switch publicData {
|
||||
case let .securePlainPhone(phone):
|
||||
case let .securePlainPhone(securePlainPhoneData):
|
||||
let (phone) = (securePlainPhoneData.phone)
|
||||
value = .phone(SecureIdPhoneValue(phone: phone))
|
||||
default:
|
||||
return nil
|
||||
@@ -214,7 +217,8 @@ func parseSecureValue(context: SecureIdAccessContext, value: Api.SecureValue, er
|
||||
return nil
|
||||
}
|
||||
switch publicData {
|
||||
case let .securePlainEmail(email):
|
||||
case let .securePlainEmail(securePlainEmailData):
|
||||
let (email) = (securePlainEmailData.email)
|
||||
value = .email(SecureIdEmailValue(email: email))
|
||||
default:
|
||||
return nil
|
||||
@@ -262,17 +266,21 @@ public func requestSecureIdForm(accountPeerId: PeerId, postbox: Postbox, network
|
||||
|> mapToSignal { result -> Signal<EncryptedSecureIdForm, RequestSecureIdFormError> in
|
||||
return postbox.transaction { transaction -> EncryptedSecureIdForm in
|
||||
switch result {
|
||||
case let .authorizationForm(_, requiredTypes, values, errors, users, termsUrl):
|
||||
case let .authorizationForm(authorizationFormData):
|
||||
let (_, requiredTypes, values, errors, users, termsUrl) = (authorizationFormData.flags, authorizationFormData.requiredTypes, authorizationFormData.values, authorizationFormData.errors, authorizationFormData.users, authorizationFormData.privacyPolicyUrl)
|
||||
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: AccumulatedPeers(users: users))
|
||||
|
||||
return EncryptedSecureIdForm(peerId: peerId, requestedFields: requiredTypes.map { requiredType in
|
||||
switch requiredType {
|
||||
case let .secureRequiredType(flags, type):
|
||||
case let .secureRequiredType(secureRequiredTypeData):
|
||||
let (flags, type) = (secureRequiredTypeData.flags, secureRequiredTypeData.type)
|
||||
return .just(parseSecureValueType(type, selfie: (flags & 1 << 1) != 0, translation: (flags & 1 << 2) != 0, nativeNames: (flags & 1 << 0) != 0))
|
||||
case let .secureRequiredTypeOneOf(types):
|
||||
case let .secureRequiredTypeOneOf(secureRequiredTypeOneOfData):
|
||||
let (types) = (secureRequiredTypeOneOfData.types)
|
||||
let parsedInnerTypes = types.compactMap { innerType -> SecureIdRequestedFormFieldValue? in
|
||||
switch innerType {
|
||||
case let .secureRequiredType(flags, type):
|
||||
case let .secureRequiredType(secureRequiredTypeData):
|
||||
let (flags, type) = (secureRequiredTypeData.flags, secureRequiredTypeData.type)
|
||||
return parseSecureValueType(type, selfie: (flags & 1 << 1) != 0, translation: (flags & 1 << 2) != 0, nativeNames: (flags & 1 << 0) != 0)
|
||||
case .secureRequiredTypeOneOf:
|
||||
return nil
|
||||
|
||||
@@ -89,9 +89,9 @@ func decryptedSecureValueData(context: SecureIdValueAccessContext, encryptedData
|
||||
private func apiInputSecretFile(_ file: SecureIdVerificationDocumentReference) -> Api.InputSecureFile {
|
||||
switch file {
|
||||
case let .remote(file):
|
||||
return Api.InputSecureFile.inputSecureFile(id: file.id, accessHash: file.accessHash)
|
||||
return Api.InputSecureFile.inputSecureFile(.init(id: file.id, accessHash: file.accessHash))
|
||||
case let .uploaded(file):
|
||||
return Api.InputSecureFile.inputSecureFileUploaded(id: file.id, parts: file.parts, md5Checksum: file.md5Checksum, fileHash: Buffer(data: file.fileHash), secret: Buffer(data: file.encryptedSecret))
|
||||
return Api.InputSecureFile.inputSecureFileUploaded(.init(id: file.id, parts: file.parts, md5Checksum: file.md5Checksum, fileHash: Buffer(data: file.fileHash), secret: Buffer(data: file.encryptedSecret)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +142,9 @@ private func inputSecureIdValueData(value: SecureIdValue) -> InputSecureIdValueD
|
||||
let (dict, fileReferences, translations) = rentalAgreement.serialize()
|
||||
return InputSecureIdValueData(type: .secureValueTypeRentalAgreement, dict: dict, fileReferences: fileReferences, translationReferences: translations, frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: nil)
|
||||
case let .phone(phone):
|
||||
return InputSecureIdValueData(type: .secureValueTypePhone, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainPhone(phone: phone.phone))
|
||||
return InputSecureIdValueData(type: .secureValueTypePhone, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainPhone(.init(phone: phone.phone)))
|
||||
case let .email(email):
|
||||
return InputSecureIdValueData(type: .secureValueTypeEmail, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainEmail(email: email.email))
|
||||
return InputSecureIdValueData(type: .secureValueTypeEmail, dict: nil, fileReferences: [], translationReferences: [], frontSideReference: nil, backSideReference: nil, selfieReference: nil, publicData: .securePlainEmail(.init(email: email.email)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ private func makeInputSecureValue(context: SecureIdAccessContext, value: SecureI
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
secureData = .secureData(data: Buffer(data: encryptedData.data), dataHash: Buffer(data: encryptedData.dataHash), secret: Buffer(data: encryptedData.encryptedSecret))
|
||||
secureData = .secureData(.init(data: Buffer(data: encryptedData.data), dataHash: Buffer(data: encryptedData.dataHash), secret: Buffer(data: encryptedData.encryptedSecret)))
|
||||
}
|
||||
|
||||
var flags: Int32 = 0
|
||||
@@ -205,7 +205,7 @@ private func makeInputSecureValue(context: SecureIdAccessContext, value: SecureI
|
||||
flags |= 1 << 5
|
||||
}
|
||||
|
||||
return Api.InputSecureValue.inputSecureValue(flags: flags, type: inputData.type, data: secureData, frontSide: inputData.frontSideReference.flatMap(apiInputSecretFile), reverseSide: inputData.backSideReference.flatMap(apiInputSecretFile), selfie: inputData.selfieReference.flatMap(apiInputSecretFile), translation: translations, files: files, plainData: inputData.publicData)
|
||||
return Api.InputSecureValue.inputSecureValue(.init(flags: flags, type: inputData.type, data: secureData, frontSide: inputData.frontSideReference.flatMap(apiInputSecretFile), reverseSide: inputData.backSideReference.flatMap(apiInputSecretFile), selfie: inputData.selfieReference.flatMap(apiInputSecretFile), translation: translations, files: files, plainData: inputData.publicData))
|
||||
}
|
||||
|
||||
public func saveSecureIdValue(postbox: Postbox, network: Network, context: SecureIdAccessContext, value: SecureIdValue, uploadedFiles: [Data: Data]) -> Signal<SecureIdValueWithContext, SaveSecureIdValueError> {
|
||||
@@ -286,7 +286,7 @@ public func dropSecureId(network: Network, currentPassword: String) -> Signal<Vo
|
||||
if let currentPasswordDerivation = authData.currentPasswordDerivation, let srpSessionData = authData.srpSessionData {
|
||||
let kdfResult = passwordKDF(encryptionProvider: network.encryptionProvider, password: currentPassword, derivation: currentPasswordDerivation, srpSessionData: srpSessionData)
|
||||
if let kdfResult = kdfResult {
|
||||
checkPassword = .inputCheckPasswordSRP(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1))
|
||||
checkPassword = .inputCheckPasswordSRP(.init(srpId: kdfResult.id, A: Buffer(data: kdfResult.A), M1: Buffer(data: kdfResult.M1)))
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
@@ -305,7 +305,7 @@ public func dropSecureId(network: Network, currentPassword: String) -> Signal<Vo
|
||||
case .passwordSettings:
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 2)
|
||||
return network.request(Api.functions.account.updatePasswordSettings(password: .inputCheckPasswordEmpty, newSettings: .passwordInputSettings(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: nil, newSecureSettings: nil)), automaticFloodWait: false)
|
||||
return network.request(Api.functions.account.updatePasswordSettings(password: .inputCheckPasswordEmpty, newSettings: .passwordInputSettings(.init(flags: flags, newAlgo: nil, newPasswordHash: nil, hint: nil, email: nil, newSecureSettings: nil))), automaticFloodWait: false)
|
||||
|> map { _ in }
|
||||
|> mapError { _ in
|
||||
return AuthorizationPasswordVerificationError.generic
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import TelegramApi
|
||||
|
||||
extension SecureFileMediaResource: TelegramCloudMediaResource, TelegramMultipartFetchableResource, EncryptedMediaResource {
|
||||
func apiInputLocation(fileReference: Data?) -> Api.InputFileLocation? {
|
||||
return Api.InputFileLocation.inputSecureFileLocation(id: self.file.id, accessHash: self.file.accessHash)
|
||||
return Api.InputFileLocation.inputSecureFileLocation(.init(id: self.file.id, accessHash: self.file.accessHash))
|
||||
}
|
||||
|
||||
public func decrypt(data: Data, params: Any) -> Data? {
|
||||
|
||||
@@ -27,9 +27,11 @@ public func secureIdConfiguration(postbox: Postbox, network: Network) -> Signal<
|
||||
assertionFailure()
|
||||
return .complete()
|
||||
}
|
||||
case let .passportConfig(hash, countriesLangs):
|
||||
case let .passportConfig(passportConfigData):
|
||||
let (hash, countriesLangs) = (passportConfigData.hash, passportConfigData.countriesLangs)
|
||||
switch countriesLangs {
|
||||
case let .dataJSON(data):
|
||||
case let .dataJSON(dataJSONData):
|
||||
let data = dataJSONData.data
|
||||
let value = SecureIdConfiguration(jsonString: data)
|
||||
parsed = CachedSecureIdConfiguration(value: value, hash: hash)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ public enum SecureIdGender {
|
||||
extension SecureIdFileReference {
|
||||
init?(apiFile: Api.SecureFile) {
|
||||
switch apiFile {
|
||||
case let .secureFile(id, accessHash, size, dcId, date, fileHash, secret):
|
||||
case let .secureFile(secureFileData):
|
||||
let (id, accessHash, size, dcId, date, fileHash, secret) = (secureFileData.id, secureFileData.accessHash, secureFileData.size, secureFileData.dcId, secureFileData.date, secureFileData.fileHash, secureFileData.secret)
|
||||
self.init(id: id, accessHash: accessHash, size: size, datacenterId: dcId, timestamp: date, fileHash: fileHash.makeData(), encryptedSecret: secret.makeData())
|
||||
case .secureFileEmpty:
|
||||
return nil
|
||||
|
||||
+18
-9
@@ -71,9 +71,11 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
|
||||
var result: [SecureIdValueContentErrorKey: SecureIdValueContentError] = [:]
|
||||
for error in errors {
|
||||
switch error {
|
||||
case let .secureValueError(type, _, text):
|
||||
case let .secureValueError(secureValueErrorData):
|
||||
let (type, _, text) = (secureValueErrorData.type, secureValueErrorData.hash, secureValueErrorData.text)
|
||||
result[.value(SecureIdValueKey(apiType: type))] = text
|
||||
case let .secureValueErrorData(type, errorDataHash, field, text):
|
||||
case let .secureValueErrorData(secureValueErrorDataData):
|
||||
let (type, errorDataHash, field, text) = (secureValueErrorDataData.type, secureValueErrorDataData.dataHash, secureValueErrorDataData.field, secureValueErrorDataData.text)
|
||||
if errorDataHash.makeData() == dataHash {
|
||||
switch type {
|
||||
case .secureValueTypePersonalDetails:
|
||||
@@ -104,11 +106,13 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
|
||||
break
|
||||
}
|
||||
}
|
||||
case let .secureValueErrorFile(_, fileHash, text):
|
||||
case let .secureValueErrorFile(secureValueErrorFileData):
|
||||
let (_, fileHash, text) = (secureValueErrorFileData.type, secureValueErrorFileData.fileHash, secureValueErrorFileData.text)
|
||||
if fileHashes.contains(fileHash.makeData()) {
|
||||
result[.file(hash: fileHash.makeData())] = text
|
||||
}
|
||||
case let .secureValueErrorFiles(_, fileHash, text):
|
||||
case let .secureValueErrorFiles(secureValueErrorFilesData):
|
||||
let (_, fileHash, text) = (secureValueErrorFilesData.type, secureValueErrorFilesData.fileHash, secureValueErrorFilesData.text)
|
||||
var containsAll = true
|
||||
loop: for hash in fileHash {
|
||||
if !fileHashes.contains(hash.makeData()) {
|
||||
@@ -119,11 +123,13 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
|
||||
if containsAll {
|
||||
result[.files(hashes: Set(fileHash.map { $0.makeData() }))] = text
|
||||
}
|
||||
case let .secureValueErrorTranslationFile(_, fileHash, text):
|
||||
case let .secureValueErrorTranslationFile(secureValueErrorTranslationFileData):
|
||||
let (_, fileHash, text) = (secureValueErrorTranslationFileData.type, secureValueErrorTranslationFileData.fileHash, secureValueErrorTranslationFileData.text)
|
||||
if fileHashes.contains(fileHash.makeData()) {
|
||||
result[.translationFile(hash: fileHash.makeData())] = text
|
||||
}
|
||||
case let .secureValueErrorTranslationFiles(_, fileHash, text):
|
||||
case let .secureValueErrorTranslationFiles(secureValueErrorTranslationFilesData):
|
||||
let (_, fileHash, text) = (secureValueErrorTranslationFilesData.type, secureValueErrorTranslationFilesData.fileHash, secureValueErrorTranslationFilesData.text)
|
||||
var containsAll = true
|
||||
loop: for hash in fileHash {
|
||||
if !fileHashes.contains(hash.makeData()) {
|
||||
@@ -134,15 +140,18 @@ func parseSecureIdValueContentErrors(dataHash: Data?, fileHashes: Set<Data>, sel
|
||||
if containsAll {
|
||||
result[.translationFiles(hashes: Set(fileHash.map { $0.makeData() }))] = text
|
||||
}
|
||||
case let .secureValueErrorSelfie(_, fileHash, text):
|
||||
case let .secureValueErrorSelfie(secureValueErrorSelfieData):
|
||||
let (_, fileHash, text) = (secureValueErrorSelfieData.type, secureValueErrorSelfieData.fileHash, secureValueErrorSelfieData.text)
|
||||
if selfieHash == fileHash.makeData() {
|
||||
result[.selfie(hash: fileHash.makeData())] = text
|
||||
}
|
||||
case let .secureValueErrorFrontSide(_, fileHash, text):
|
||||
case let .secureValueErrorFrontSide(secureValueErrorFrontSideData):
|
||||
let (_, fileHash, text) = (secureValueErrorFrontSideData.type, secureValueErrorFrontSideData.fileHash, secureValueErrorFrontSideData.text)
|
||||
if frontSideHash == fileHash.makeData() {
|
||||
result[.frontSide(hash: fileHash.makeData())] = text
|
||||
}
|
||||
case let .secureValueErrorReverseSide(_, fileHash, text):
|
||||
case let .secureValueErrorReverseSide(secureValueErrorReverseSideData):
|
||||
let (_, fileHash, text) = (secureValueErrorReverseSideData.type, secureValueErrorReverseSideData.fileHash, secureValueErrorReverseSideData.text)
|
||||
if backSideHash == fileHash.makeData() {
|
||||
result[.backSide(hash: fileHash.makeData())] = text
|
||||
}
|
||||
|
||||
@@ -112,12 +112,8 @@ public func uploadSecureIdFile(context: SecureIdAccessContext, postbox: Postbox,
|
||||
switch result {
|
||||
case let .progress(value):
|
||||
return .single(.progress(value))
|
||||
case let .inputFile(file):
|
||||
if case let .inputFile(id, parts, _, md5Checksum) = file {
|
||||
return .single(.result(UploadedSecureIdFile(id: id, parts: parts, md5Checksum: md5Checksum, fileHash: encryptedData.hash, encryptedSecret: encryptedData.encryptedSecret), encryptedData.data))
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
}
|
||||
case let .inputFile(.inputFile(fileData)):
|
||||
return .single(.result(UploadedSecureIdFile(id: fileData.id, parts: fileData.parts, md5Checksum: fileData.md5Checksum, fileHash: encryptedData.hash, encryptedSecret: encryptedData.encryptedSecret), encryptedData.data))
|
||||
default:
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public struct SecureIdPreparePhoneVerificationPayload {
|
||||
}
|
||||
|
||||
public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPhoneValue) -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> {
|
||||
return network.request(Api.functions.account.sendVerifyPhoneCode(phoneNumber: value.phone, settings: .codeSettings(flags: 0, logoutTokens: nil, token: nil, appSandbox: nil)), automaticFloodWait: false)
|
||||
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
|
||||
@@ -28,7 +28,8 @@ public func secureIdPreparePhoneVerification(network: Network, value: SecureIdPh
|
||||
}
|
||||
|> mapToSignal { sentCode -> Signal<SecureIdPreparePhoneVerificationPayload, SecureIdPreparePhoneVerificationError> in
|
||||
switch sentCode {
|
||||
case let .sentCode(_, type, phoneCodeHash, nextType, timeout):
|
||||
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()
|
||||
@@ -84,7 +85,8 @@ public func secureIdPrepareEmailVerification(network: Network, value: SecureIdEm
|
||||
}
|
||||
|> map { sentCode -> SecureIdPrepareEmailVerificationPayload in
|
||||
switch sentCode {
|
||||
case .sentEmailCode(_, let length):
|
||||
case let .sentEmailCode(sentEmailCodeData):
|
||||
let length = sentEmailCodeData.length
|
||||
return SecureIdPrepareEmailVerificationPayload(email: value.email, length: length)
|
||||
}
|
||||
}
|
||||
@@ -97,7 +99,7 @@ public enum SecureIdCommitEmailVerificationError {
|
||||
}
|
||||
|
||||
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(code: code)), automaticFloodWait: false)
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user