diff --git a/Telegram/Resources/scheme.tl b/Telegram/Resources/scheme.tl index d09ab90ca..119721014 100644 --- a/Telegram/Resources/scheme.tl +++ b/Telegram/Resources/scheme.tl @@ -995,9 +995,14 @@ inputSecureValue#c0da30f0 flags:# type:SecureValueType data:flags.0?SecureData f secureValueHash#ed1ecdb0 type:SecureValueType hash:bytes = SecureValueHash; +secureValueErrorData#e8a40bd9 type:SecureValueType data_hash:bytes field:string text:string = SecureValueError; +secureValueErrorFile#7a700873 type:SecureValueType file_hash:bytes text:string = SecureValueError; +secureValueErrorFiles#666220e9 type:SecureValueType file_hash:Vector text:string = SecureValueError; +secureValueErrorSelfie#e537ced6 type:SecureValueType file_hash:bytes text:string = SecureValueError; + secureCredentialsEncrypted#33f0ea47 data:bytes hash:bytes secret:bytes = SecureCredentialsEncrypted; -account.authorizationForm#b9d3d1f0 flags:# selfie_required:flags.1?true required_types:Vector values:Vector users:Vector privacy_policy_url:flags.0?string = account.AuthorizationForm; +account.authorizationForm#cb976d53 flags:# selfie_required:flags.1?true required_types:Vector values:Vector errors:Vector users:Vector privacy_policy_url:flags.0?string = account.AuthorizationForm; account.sentEmailCode#811f854f email_pattern:string length:int = account.SentEmailCode; @@ -1059,6 +1064,7 @@ account.resetWebAuthorizations#682d2594 = Bool; account.getSecureValue#73665bc2 types:Vector = Vector; account.saveSecureValue#899fe31d value:InputSecureValue secure_secret_id:long = SecureValue; account.deleteSecureValue#b880bc4b types:Vector = Bool; +account.setSecureValueErrors#d0093ce4 user_id:InputUser errors:Vector = Bool; account.getAuthorizationForm#b86ba8e1 bot_id:int scope:string public_key:string = account.AuthorizationForm; account.acceptAuthorization#e7027c94 bot_id:int scope:string public_key:string value_hashes:Vector credentials:SecureCredentialsEncrypted = Bool; account.sendVerifyPhoneCode#823380b4 flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode; diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index 8ae70592d..53da4d1a3 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -495,38 +495,60 @@ void FormController::decryptValues() { } void FormController::fillErrors() { - const auto errors = _request.errors.toUtf8(); - const auto list = DeserializeErrors(bytes::make_span(errors)); - for (const auto &error : list) { - for (auto &[type, value] : _form.values) { - if (ValueCredentialsKey(type) != error.type) { - continue; - } - if (!error.key.has_value()) { - value.scanMissingError = error.text; - } else if (const auto key = base::get_if(&error.key)) { - value.data.parsed.fields[(*key)].error = error.text; - } else if (auto hash = base::get_if(&error.key)) { - const auto check = [&](const File &file) { - return *hash == QByteArray::fromRawData( - reinterpret_cast(file.hash.data()), - file.hash.size()); - }; - for (auto &scan : value.scans) { - if (check(scan)) { - scan.error = error.text; - break; - } - } - if (value.selfie) { - if (check(*value.selfie) || hash->isEmpty()) { - value.selfie->error = error.text; - } - } - } - break; + const auto find = [&](const MTPSecureValueType &type) -> Value* { + const auto converted = ConvertType(type); + const auto i = _form.values.find(ConvertType(type)); + if (i != end(_form.values)) { + return &i->second; + } + LOG(("API Error: Value not found for error type.")); + return nullptr; + }; + const auto scan = [&](Value &value, bytes::const_span hash) -> File* { + const auto i = ranges::find_if(value.scans, [&](const File &scan) { + return !bytes::compare(hash, scan.hash); + }); + if (i != end(value.scans)) { + return &*i; + } + LOG(("API Error: File not found for error value.")); + return nullptr; + }; + for (const auto &error : _form.pendingErrors) { + switch (error.type()) { + case mtpc_secureValueErrorData: { + const auto &data = error.c_secureValueErrorData(); + if (const auto value = find(data.vtype)) { + const auto key = qs(data.vfield); + value->data.parsed.fields[key].error = qs(data.vtext); + } + } break; + case mtpc_secureValueErrorFile: { + const auto &data = error.c_secureValueErrorFile(); + const auto hash = bytes::make_span(data.vfile_hash.v); + if (const auto value = find(data.vtype)) { + if (const auto file = scan(*value, hash)) { + file->error = qs(data.vtext); + } + } + } break; + case mtpc_secureValueErrorFiles: { + const auto &data = error.c_secureValueErrorFiles(); + if (const auto value = find(data.vtype)) { + value->scanMissingError = qs(data.vtext); + } + } break; + case mtpc_secureValueErrorSelfie: { + const auto &data = error.c_secureValueErrorSelfie(); + if (const auto value = find(data.vtype)) { + if (value->selfie) { + value->selfie->error = qs(data.vtext); + } else { + LOG(("API Error: Selfie not found for error value.")); + } + } + } break; } - } } @@ -1786,6 +1808,7 @@ void FormController::parseForm(const MTPaccount_AuthorizationForm &result) { _form.values.emplace(type, Value(type)); } _bot = App::userLoaded(_request.botId); + _form.pendingErrors = data.verrors.v; } void FormController::formFail(const QString &error) { diff --git a/Telegram/SourceFiles/passport/passport_form_controller.h b/Telegram/SourceFiles/passport/passport_form_controller.h index 05b2df7d6..ef355bbbf 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.h +++ b/Telegram/SourceFiles/passport/passport_form_controller.h @@ -170,6 +170,8 @@ struct Form { std::vector request; bool identitySelfieRequired = false; QString privacyPolicyUrl; + QVector pendingErrors; + }; struct PasswordSettings { diff --git a/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp b/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp index 74da8a8c3..7af720736 100644 --- a/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp @@ -411,6 +411,9 @@ void EditScans::updateScan(ScanInfo &&info) { _header->show(anim::type::normal); _uploadTexts.fire(uploadButtonText()); } + if (_uploadMoreError) { + _uploadMoreError->toggle(!uploadedSomeMore(), anim::type::normal); + } } void EditScans::createSelfieRow(const ScanInfo &info) {