tdesktop/Telegram/SourceFiles/api/api_confirm_phone.cpp

168 lines
5.0 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_confirm_phone.h"
#include "apiwrap.h"
#include "lang/lang_keys.h"
#include "main/main_account.h"
#include "main/main_session.h"
#include "ui/boxes/confirm_box.h"
#include "ui/boxes/confirm_phone_box.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "window/window_session_controller.h"
namespace Api {
ConfirmPhone::ConfirmPhone(not_null<ApiWrap*> api)
: _api(&api->instance()) {
}
void ConfirmPhone::resolve(
not_null<Window::SessionController*> controller,
const QString &phone,
const QString &hash) {
if (_sendRequestId) {
return;
}
_sendRequestId = _api.request(MTPaccount_SendConfirmPhoneCode(
MTP_string(hash),
MTP_codeSettings(
MTP_flags(0),
MTPVector<MTPbytes>(),
MTPstring(),
MTPBool())
)).done([=](const MTPauth_SentCode &result) {
_sendRequestId = 0;
result.match([&](const MTPDauth_sentCode &data) {
const auto bad = [](const char *type) {
LOG(("API Error: Should not be '%1'.").arg(type));
return 0;
};
const auto sentCodeLength = data.vtype().match([&](
const MTPDauth_sentCodeTypeApp &data) {
LOG(("Error: should not be in-app code!"));
return 0;
}, [&](const MTPDauth_sentCodeTypeSms &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeFragmentSms &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeCall &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeFlashCall &) {
return bad("FlashCall");
}, [&](const MTPDauth_sentCodeTypeMissedCall &) {
return bad("MissedCall");
}, [&](const MTPDauth_sentCodeTypeFirebaseSms &) {
return bad("FirebaseSms");
}, [&](const MTPDauth_sentCodeTypeEmailCode &) {
return bad("EmailCode");
}, [&](const MTPDauth_sentCodeTypeSmsWord &) {
return bad("SmsWord");
}, [&](const MTPDauth_sentCodeTypeSmsPhrase &) {
return bad("SmsPhrase");
}, [&](const MTPDauth_sentCodeTypeSetUpEmailRequired &) {
return bad("SetUpEmailRequired");
});
const auto fragmentUrl = data.vtype().match([](
const MTPDauth_sentCodeTypeFragmentSms &data) {
return qs(data.vurl());
}, [](const auto &) { return QString(); });
const auto phoneHash = qs(data.vphone_code_hash());
const auto timeout = [&]() -> std::optional<int> {
if (const auto nextType = data.vnext_type()) {
if (nextType->type() == mtpc_auth_codeTypeCall) {
return data.vtimeout().value_or(60);
}
}
return std::nullopt;
}();
auto box = Box<Ui::ConfirmPhoneBox>(
phone,
sentCodeLength,
fragmentUrl,
timeout);
const auto boxWeak = Ui::MakeWeak(box.data());
using LoginCode = rpl::event_stream<QString>;
const auto codeHandles = box->lifetime().make_state<LoginCode>();
controller->session().account().setHandleLoginCode([=](
const QString &code) {
codeHandles->fire_copy(code);
});
box->resendRequests(
) | rpl::start_with_next([=] {
_api.request(MTPauth_ResendCode(
MTP_string(phone),
MTP_string(phoneHash)
)).done([=] {
if (boxWeak) {
boxWeak->callDone();
}
}).send();
}, box->lifetime());
rpl::merge(
codeHandles->events(),
box->checkRequests()
) | rpl::start_with_next([=](const QString &code) {
if (_checkRequestId) {
return;
}
_checkRequestId = _api.request(MTPaccount_ConfirmPhone(
MTP_string(phoneHash),
MTP_string(code)
)).done([=] {
_checkRequestId = 0;
controller->show(
Ui::MakeInformBox(
tr::lng_confirm_phone_success(
tr::now,
lt_phone,
Ui::FormatPhone(phone))),
Ui::LayerOption::CloseOther);
}).fail([=](const MTP::Error &error) {
_checkRequestId = 0;
if (!boxWeak) {
return;
}
const auto errorText = MTP::IsFloodError(error)
? tr::lng_flood_error(tr::now)
: (error.type() == (u"PHONE_CODE_EMPTY"_q)
|| error.type() == (u"PHONE_CODE_INVALID"_q))
? tr::lng_bad_code(tr::now)
: Lang::Hard::ServerError();
boxWeak->showServerError(errorText);
}).handleFloodErrors().send();
}, box->lifetime());
box->boxClosing(
) | rpl::start_with_next([=] {
controller->session().account().setHandleLoginCode(nullptr);
}, box->lifetime());
controller->show(std::move(box), Ui::LayerOption::CloseOther);
}, [](const MTPDauth_sentCodeSuccess &) {
LOG(("API Error: Unexpected auth.sentCodeSuccess "
"(Api::ConfirmPhone)."));
});
}).fail([=](const MTP::Error &error) {
_sendRequestId = 0;
_checkRequestId = 0;
const auto errorText = MTP::IsFloodError(error)
? tr::lng_flood_error(tr::now)
: (error.code() == 400)
? tr::lng_confirm_phone_link_invalid(tr::now)
: Lang::Hard::ServerError();
controller->show(
Ui::MakeInformBox(errorText),
Ui::LayerOption::CloseOther);
}).handleFloodErrors().send();
}
} // namespace Api