Stop passport authorization with confirm.

This commit is contained in:
John Preston 2018-04-13 22:14:14 +04:00
parent 1064208be9
commit 6de3112c8a
11 changed files with 100 additions and 38 deletions

View File

@ -1594,6 +1594,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_passport_delete_email_sure" = "Are you sure you want to delete your email?";
"lng_passport_delete_phone" = "Delete phone number";
"lng_passport_delete_phone_sure" = "Are you sure you want to delete your phone number?";
"lng_passport_success" = "Authorization successfull!";
"lng_passport_stop_sure" = "Are you sure you want to stop this authorization?";
"lng_passport_stop" = "Stop";
// Wnd specific

View File

@ -335,7 +335,7 @@ bytes::vector DecryptValueSecret(
return DecryptSecretBytes(encrypted, bytesForEncryptionKey);
}
uint64 CountSecureSecretHash(bytes::const_span secret) {
uint64 CountSecureSecretId(bytes::const_span secret) {
const auto full = openssl::Sha256(secret);
return *reinterpret_cast<const uint64*>(full.data());
}

View File

@ -54,7 +54,7 @@ bytes::vector DecryptValueSecret(
bytes::const_span secret,
bytes::const_span valueHash);
uint64 CountSecureSecretHash(bytes::const_span secret);
uint64 CountSecureSecretId(bytes::const_span secret);
bytes::vector EncryptCredentialsSecret(
bytes::const_span secret,

View File

@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mainwindow.h"
#include "window/window_controller.h"
#include "core/click_handler_types.h"
#include "ui/toast/toast.h"
#include "auth_session.h"
#include "storage/localimageloader.h"
#include "storage/localstorage.h"
@ -77,7 +78,7 @@ MTPSecureValueType ConvertType(Value::Type type) {
};
QJsonObject GetJSONFromMap(
const std::map<QString, bytes::const_span> &map) {
const std::map<QString, bytes::const_span> &map) {
auto result = QJsonObject();
for (const auto &[key, value] : map) {
const auto raw = QByteArray::fromRawData(
@ -92,7 +93,7 @@ QJsonObject GetJSONFromFile(const File &file) {
return GetJSONFromMap({
{ "file_hash", file.hash },
{ "secret", file.secret }
});
});
}
FormRequest PreprocessRequest(const FormRequest &request) {
@ -125,26 +126,26 @@ FormRequest::FormRequest(
const QString &callbackUrl,
const QString &publicKey,
const QString &payload)
: botId(botId)
, scope(scope)
, callbackUrl(callbackUrl)
, publicKey(publicKey)
, payload(payload) {
: botId(botId)
, scope(scope)
, callbackUrl(callbackUrl)
, publicKey(publicKey)
, payload(payload) {
}
EditFile::EditFile(
not_null<const Value*> value,
const File &fields,
std::unique_ptr<UploadScanData> &&uploadData)
: value(value)
, fields(std::move(fields))
, uploadData(std::move(uploadData))
, guard(std::make_shared<bool>(true)) {
: value(value)
, fields(std::move(fields))
, uploadData(std::move(uploadData))
, guard(std::make_shared<bool>(true)) {
}
UploadScanDataPointer::UploadScanDataPointer(
std::unique_ptr<UploadScanData> &&value)
: _value(std::move(value)) {
: _value(std::move(value)) {
}
UploadScanDataPointer::UploadScanDataPointer(
@ -183,9 +184,9 @@ Value::Value(Type type) : type(type) {
FormController::FormController(
not_null<Window::Controller*> controller,
const FormRequest &request)
: _controller(controller)
, _request(PreprocessRequest(request))
, _view(std::make_unique<PanelController>(this)) {
: _controller(controller)
, _request(PreprocessRequest(request))
, _view(std::make_unique<PanelController>(this)) {
}
void FormController::show() {
@ -202,7 +203,7 @@ QString FormController::privacyPolicyUrl() const {
}
bytes::vector FormController::passwordHashForAuth(
bytes::const_span password) const {
bytes::const_span password) const {
return openssl::Sha256(bytes::concatenate(
_password.salt,
password,
@ -213,14 +214,14 @@ auto FormController::prepareFinalData() -> FinalData {
auto hashes = QVector<MTPSecureValueHash>();
auto secureData = QJsonObject();
const auto addValueToJSON = [&](
const QString &key,
not_null<const Value*> value) {
const QString &key,
not_null<const Value*> value) {
auto object = QJsonObject();
if (!value->data.parsed.fields.empty()) {
object.insert("data", GetJSONFromMap({
{ "data_hash", value->data.hash },
{ "secret", value->data.secret }
}));
}));
}
if (!value->scans.empty()) {
auto files = QJsonArray();
@ -277,7 +278,7 @@ auto FormController::prepareFinalData() -> FinalData {
}
bool FormController::submit() {
if (_submitRequestId) {
if (_submitRequestId || _submitSuccess|| _cancelled) {
return true;
}
@ -301,11 +302,17 @@ bool FormController::submit() {
MTP_bytes(credentialsEncryptedData.hash),
MTP_bytes(credentialsEncryptedSecret))
)).done([=](const MTPBool &result) {
const auto url = qthelp::url_append_query(
_request.callbackUrl,
"tg_passport=success");
UrlClickHandler::doOpen(url);
_submitRequestId = 0;
_submitSuccess = true;
_view->showToast(lang(lng_passport_success));
App::CallDelayed(
Ui::Toast::DefaultDuration + st::toastFadeOutDuration,
this,
[=] { cancel(); });
}).fail([=](const RPCError &error) {
_submitRequestId = 0;
_view->show(Box<InformBox>(
"Failed sending data :(\n" + error.type()));
}).send();
@ -333,7 +340,8 @@ void FormController::submitPassword(const QString &password) {
validateSecureSecret(
bytes::make_span(data.vsecure_salt.v),
bytes::make_span(data.vsecure_secret.v),
bytes::make_span(passwordBytes));
bytes::make_span(passwordBytes),
data.vsecure_secret_id.v);
}).fail([=](const RPCError &error) {
_passwordCheckRequestId = 0;
if (MTP::isFloodError(error)) {
@ -349,7 +357,8 @@ void FormController::submitPassword(const QString &password) {
void FormController::validateSecureSecret(
bytes::const_span salt,
bytes::const_span encryptedSecret,
bytes::const_span password) {
bytes::const_span password,
uint64 serverSecretId) {
if (!salt.empty() && !encryptedSecret.empty()) {
_secret = DecryptSecureSecret(salt, encryptedSecret, password);
if (_secret.empty()) {
@ -361,8 +370,18 @@ void FormController::validateSecureSecret(
resetValue(value);
}
}
} else if (CountSecureSecretId(_secret) != serverSecretId) {
_secret.clear();
_secretId = 0;
LOG(("API Error: Wrong secure secret id. "
"Forgetting all files and data :("));
for (auto &[type, value] : _form.values) {
if (!value.data.original.isEmpty()) {
resetValue(value);
}
}
} else {
_secretId = CountSecureSecretHash(_secret);
_secretId = serverSecretId;
decryptValues();
}
}
@ -1327,7 +1346,7 @@ void FormController::generateSecret(bytes::const_span password) {
_password.newSecureSalt,
randomSaltPart);
auto secureSecretId = CountSecureSecretHash(secret);
auto secureSecretId = CountSecureSecretId(secret);
auto encryptedSecret = EncryptSecureSecret(
newSecureSaltFull,
secret,
@ -1642,9 +1661,27 @@ void FormController::parsePassword(const MTPDaccount_password &result) {
}
void FormController::cancel() {
if (!_submitSuccess) {
_view->show(Box<ConfirmBox>(
lang(lng_passport_stop_sure),
lang(lng_passport_stop),
[=] { cancelSure(); }));
} else {
cancelSure();
}
}
void FormController::cancelSure() {
if (!_cancelled) {
_cancelled = true;
crl::on_main(this, [=] {
const auto url = qthelp::url_append_query(
_request.callbackUrl,
_submitSuccess ? "tg_passport=success" : "tg_passport=cancel");
UrlClickHandler::doOpen(url);
const auto timeout = _view->closeGetDuration();
App::CallDelayed(timeout, this, [=] {
_controller->clearPassportForm();
});
}

View File

@ -287,7 +287,8 @@ private:
void validateSecureSecret(
bytes::const_span salt,
bytes::const_span encryptedSecret,
bytes::const_span password);
bytes::const_span password,
uint64 serverSecretId);
void decryptValues();
void decryptValue(Value &value);
bool validateValueSecrets(Value &value);
@ -344,6 +345,8 @@ private:
const MTPInputSecureValue &data);
FinalData prepareFinalData();
void cancelSure();
not_null<Window::Controller*> _controller;
FormRequest _request;
UserData *_bot = nullptr;
@ -369,6 +372,7 @@ private:
rpl::event_stream<> _secretReady;
rpl::event_stream<QString> _passwordError;
mtpRequestId _submitRequestId = 0;
bool _submitSuccess = false;
rpl::lifetime _uploaderSubscriptions;
rpl::lifetime _lifetime;

View File

@ -103,6 +103,11 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
case Scope::Type::Identity:
case Scope::Type::Address: {
auto list = QStringList();
const auto pushListValue = [&](const QString &value) {
if (const auto trimmed = value.trimmed(); !trimmed.isEmpty()) {
list.push_back(trimmed);
}
};
const auto &fields = scope.fields->data.parsed.fields;
const auto document = [&]() -> const Value* {
for (const auto &document : scope.documents) {
@ -113,7 +118,7 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
return nullptr;
}();
if (document && scope.documents.size() > 1) {
list.push_back([&] {
pushListValue([&] {
switch (document->type) {
case Value::Type::Passport:
return lang(lng_passport_identity_passport);
@ -145,7 +150,7 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
} else if (row.validate && !row.validate(i->second)) {
return QString();
}
list.push_back(format ? format(i->second) : i->second);
pushListValue(format ? format(i->second) : i->second);
} else if (!document) {
return QString();
} else {
@ -155,7 +160,7 @@ QString ComputeScopeRowReadyString(const Scope &scope) {
} else if (row.validate && !row.validate(i->second)) {
return QString();
}
list.push_back(i->second);
pushListValue(i->second);
}
}
return list.join(", ");

View File

@ -48,6 +48,8 @@ public:
virtual void showBox(object_ptr<BoxContent> box) = 0;
virtual void showToast(const QString &text) = 0;
virtual int closeGetDuration() = 0;
virtual ~ViewController() {
}

View File

@ -53,7 +53,7 @@ void Panel::initControls() {
}, lifetime());
_close->addClickHandler([=] {
hideAndDestroy();
_controller->cancelAuth();
});
_back->toggledValue(
@ -206,11 +206,13 @@ void Panel::destroyDelayed() {
_controller->cancelAuth();
}
void Panel::hideAndDestroy() {
int Panel::hideAndDestroyGetDuration() {
toggleOpacityAnimation(false);
if (_animationCache.isNull()) {
destroyDelayed();
return 0;
}
return st::callPanelDuration;
}
void Panel::showAskPassword() {

View File

@ -33,7 +33,7 @@ public:
Panel(not_null<PanelController*> controller);
void showAndActivate();
void hideAndDestroy();
int hideAndDestroyGetDuration();
void showAskPassword();
void showNoPassword();

View File

@ -975,6 +975,13 @@ void PanelController::cancelEditScope() {
}
}
int PanelController::closeGetDuration() {
if (_panel) {
return _panel->hideAndDestroyGetDuration();
}
return 0;
}
void PanelController::cancelAuth() {
_form->cancel();
}

View File

@ -97,6 +97,8 @@ public:
void showBox(object_ptr<BoxContent> box) override;
void showToast(const QString &text) override;
int closeGetDuration() override;
void cancelAuth();
rpl::lifetime &lifetime();