Support QR code authentication.
GitOrigin-RevId: 140381ee80339b5ac2e15f149ad3a37688200e88
This commit is contained in:
parent
3a203e6674
commit
9f60d0bae1
@ -86,12 +86,15 @@ authorizationStateWaitTdlibParameters = AuthorizationState;
|
|||||||
//@description TDLib needs an encryption key to decrypt the local database @is_encrypted True, if the database is currently encrypted
|
//@description TDLib needs an encryption key to decrypt the local database @is_encrypted True, if the database is currently encrypted
|
||||||
authorizationStateWaitEncryptionKey is_encrypted:Bool = AuthorizationState;
|
authorizationStateWaitEncryptionKey is_encrypted:Bool = AuthorizationState;
|
||||||
|
|
||||||
//@description TDLib needs the user's phone number to authorize
|
//@description TDLib needs the user's phone number to authorize. Call `setAuthenticationPhoneNumber` to provide the phone number, or use `requestQrCodeAuthentication`, or `checkAuthenticationBotToken` for other authentication options
|
||||||
authorizationStateWaitPhoneNumber = AuthorizationState;
|
authorizationStateWaitPhoneNumber = AuthorizationState;
|
||||||
|
|
||||||
//@description TDLib needs the user's authentication code to authorize @code_info Information about the authorization code that was sent
|
//@description TDLib needs the user's authentication code to authorize @code_info Information about the authorization code that was sent
|
||||||
authorizationStateWaitCode code_info:authenticationCodeInfo = AuthorizationState;
|
authorizationStateWaitCode code_info:authenticationCodeInfo = AuthorizationState;
|
||||||
|
|
||||||
|
//@description The user needs to confirm authorization on another logged in device by scanning a QR code with the provided link @link A tg:// URL for the QR code. The link will be updated frequently
|
||||||
|
authorizationStateWaitOtherDeviceConfirmation link:string = AuthorizationState;
|
||||||
|
|
||||||
//@description The user is unregistered and need to accept terms of service and enter their first name and last name to finish registration @terms_of_service Telegram terms of service
|
//@description The user is unregistered and need to accept terms of service and enter their first name and last name to finish registration @terms_of_service Telegram terms of service
|
||||||
authorizationStateWaitRegistration terms_of_service:termsOfService = AuthorizationState;
|
authorizationStateWaitRegistration terms_of_service:termsOfService = AuthorizationState;
|
||||||
|
|
||||||
@ -3012,6 +3015,9 @@ resendAuthenticationCode = Ok;
|
|||||||
//@description Checks the authentication code. Works only when the current authorization state is authorizationStateWaitCode @code The verification code received via SMS, Telegram message, phone call, or flash call
|
//@description Checks the authentication code. Works only when the current authorization state is authorizationStateWaitCode @code The verification code received via SMS, Telegram message, phone call, or flash call
|
||||||
checkAuthenticationCode code:string = Ok;
|
checkAuthenticationCode code:string = Ok;
|
||||||
|
|
||||||
|
//@description Requests QR code authentication by scanning a QR code on another logged in device. Works only when the current authorization state is authorizationStateWaitPhoneNumber @other_user_ids List of user identifiers of other users currently using the client
|
||||||
|
requestQrCodeAuthentication other_user_ids:vector<int32> = Ok;
|
||||||
|
|
||||||
//@description Finishes user registration. Works only when the current authorization state is authorizationStateWaitRegistration
|
//@description Finishes user registration. Works only when the current authorization state is authorizationStateWaitRegistration
|
||||||
//@first_name The first name of the user; 1-64 characters @last_name The last name of the user; 0-64 characters
|
//@first_name The first name of the user; 1-64 characters @last_name The last name of the user; 0-64 characters
|
||||||
registerUser first_name:string last_name:string = Ok;
|
registerUser first_name:string last_name:string = Ok;
|
||||||
@ -3038,6 +3044,10 @@ close = Ok;
|
|||||||
destroy = Ok;
|
destroy = Ok;
|
||||||
|
|
||||||
|
|
||||||
|
//@description Confirms QR code authentication on another device. Returns created session on success @link A link from a QR code. The link must be scanned by the in-app camera
|
||||||
|
confirmQrCodeAuthentication link:string = Session;
|
||||||
|
|
||||||
|
|
||||||
//@description Returns all updates needed to restore current TDLib state, i.e. all actual UpdateAuthorizationState/UpdateUser/UpdateNewChat and others. This is especially usefull if TDLib is run in a separate process. This is an offline method. Can be called before authorization
|
//@description Returns all updates needed to restore current TDLib state, i.e. all actual UpdateAuthorizationState/UpdateUser/UpdateNewChat and others. This is especially usefull if TDLib is run in a separate process. This is an offline method. Can be called before authorization
|
||||||
getCurrentState = Updates;
|
getCurrentState = Updates;
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1076,8 +1076,6 @@ auth.loginToken#629f1980 expires:int token:bytes = auth.LoginToken;
|
|||||||
auth.loginTokenMigrateTo#68e9916 dc_id:int token:bytes = auth.LoginToken;
|
auth.loginTokenMigrateTo#68e9916 dc_id:int token:bytes = auth.LoginToken;
|
||||||
auth.loginTokenSuccess#390d5c5e authorization:auth.Authorization = auth.LoginToken;
|
auth.loginTokenSuccess#390d5c5e authorization:auth.Authorization = auth.LoginToken;
|
||||||
|
|
||||||
auth.loginTokenInfo#5203303a dc_id:int auth_key_id:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string ip:string region:string = auth.LoginTokenInfo;
|
|
||||||
|
|
||||||
account.contentSettings#57e28221 flags:# sensitive_enabled:flags.0?true sensitive_can_change:flags.1?true = account.ContentSettings;
|
account.contentSettings#57e28221 flags:# sensitive_enabled:flags.0?true sensitive_can_change:flags.1?true = account.ContentSettings;
|
||||||
|
|
||||||
messages.inactiveChats#a927fec5 dates:Vector<int> chats:Vector<Chat> users:Vector<User> = messages.InactiveChats;
|
messages.inactiveChats#a927fec5 dates:Vector<int> chats:Vector<Chat> users:Vector<User> = messages.InactiveChats;
|
||||||
@ -1109,8 +1107,7 @@ auth.cancelCode#1f040578 phone_number:string phone_code_hash:string = Bool;
|
|||||||
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
auth.dropTempAuthKeys#8e48a188 except_auth_keys:Vector<long> = Bool;
|
||||||
auth.exportLoginToken#b1b41517 api_id:int api_hash:string except_ids:Vector<int> = auth.LoginToken;
|
auth.exportLoginToken#b1b41517 api_id:int api_hash:string except_ids:Vector<int> = auth.LoginToken;
|
||||||
auth.importLoginToken#95ac5ce4 token:bytes = auth.LoginToken;
|
auth.importLoginToken#95ac5ce4 token:bytes = auth.LoginToken;
|
||||||
auth.acceptLoginToken#42e731b9 token:bytes = Updates;
|
auth.acceptLoginToken#e894ad4d token:bytes = Authorization;
|
||||||
auth.checkLoginToken#7d4fd4b0 token:bytes = auth.LoginTokenInfo;
|
|
||||||
|
|
||||||
account.registerDevice#68976c6f flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
|
account.registerDevice#68976c6f flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector<int> = Bool;
|
||||||
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
account.unregisterDevice#3076c4bf token_type:int token:string other_uids:Vector<int> = Bool;
|
||||||
|
Binary file not shown.
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "td/actor/PromiseFuture.h"
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
|
||||||
|
#include "td/utils/base64.h"
|
||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/ScopeGuard.h"
|
#include "td/utils/ScopeGuard.h"
|
||||||
@ -96,18 +97,21 @@ bool AuthManager::is_authorized() const {
|
|||||||
|
|
||||||
tl_object_ptr<td_api::AuthorizationState> AuthManager::get_authorization_state_object(State authorization_state) const {
|
tl_object_ptr<td_api::AuthorizationState> AuthManager::get_authorization_state_object(State authorization_state) const {
|
||||||
switch (authorization_state) {
|
switch (authorization_state) {
|
||||||
case State::Ok:
|
|
||||||
return make_tl_object<td_api::authorizationStateReady>();
|
|
||||||
case State::WaitCode:
|
|
||||||
return send_code_helper_.get_authorization_state_wait_code();
|
|
||||||
case State::WaitPhoneNumber:
|
case State::WaitPhoneNumber:
|
||||||
return make_tl_object<td_api::authorizationStateWaitPhoneNumber>();
|
return make_tl_object<td_api::authorizationStateWaitPhoneNumber>();
|
||||||
case State::WaitRegistration:
|
case State::WaitCode:
|
||||||
return make_tl_object<td_api::authorizationStateWaitRegistration>(
|
return send_code_helper_.get_authorization_state_wait_code();
|
||||||
terms_of_service_.get_terms_of_service_object());
|
case State::WaitQrCodeConfirmation:
|
||||||
|
return make_tl_object<td_api::authorizationStateWaitOtherDeviceConfirmation>("tg://login?" +
|
||||||
|
base64url_encode(login_token_));
|
||||||
case State::WaitPassword:
|
case State::WaitPassword:
|
||||||
return make_tl_object<td_api::authorizationStateWaitPassword>(
|
return make_tl_object<td_api::authorizationStateWaitPassword>(
|
||||||
wait_password_state_.hint_, wait_password_state_.has_recovery_, wait_password_state_.email_address_pattern_);
|
wait_password_state_.hint_, wait_password_state_.has_recovery_, wait_password_state_.email_address_pattern_);
|
||||||
|
case State::WaitRegistration:
|
||||||
|
return make_tl_object<td_api::authorizationStateWaitRegistration>(
|
||||||
|
terms_of_service_.get_terms_of_service_object());
|
||||||
|
case State::Ok:
|
||||||
|
return make_tl_object<td_api::authorizationStateReady>();
|
||||||
case State::LoggingOut:
|
case State::LoggingOut:
|
||||||
case State::DestroyingKeys:
|
case State::DestroyingKeys:
|
||||||
return make_tl_object<td_api::authorizationStateLoggingOut>();
|
return make_tl_object<td_api::authorizationStateLoggingOut>();
|
||||||
@ -143,9 +147,9 @@ void AuthManager::check_bot_token(uint64 query_id, string bot_token) {
|
|||||||
}
|
}
|
||||||
if (state_ != State::WaitPhoneNumber && state_ != State::Ok) {
|
if (state_ != State::WaitPhoneNumber && state_ != State::Ok) {
|
||||||
// TODO do not allow State::Ok
|
// TODO do not allow State::Ok
|
||||||
return on_query_error(query_id, Status::Error(8, "checkAuthenticationBotToken unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to checkAuthenticationBotToken unexpected"));
|
||||||
}
|
}
|
||||||
if (!send_code_helper_.phone_number().empty()) {
|
if (!send_code_helper_.phone_number().empty() || was_qr_code_request_) {
|
||||||
return on_query_error(
|
return on_query_error(
|
||||||
query_id, Status::Error(8, "Cannot set bot token after authentication beginning. You need to log out first"));
|
query_id, Status::Error(8, "Cannot set bot token after authentication beginning. You need to log out first"));
|
||||||
}
|
}
|
||||||
@ -173,6 +177,69 @@ void AuthManager::check_bot_token(uint64 query_id, string bot_token) {
|
|||||||
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuthManager::request_qr_code_authentication(uint64 query_id, vector<int32> other_user_ids) {
|
||||||
|
if (state_ != State::WaitPhoneNumber) {
|
||||||
|
if ((state_ == State::WaitCode || state_ == State::WaitPassword || state_ == State::WaitRegistration) &&
|
||||||
|
net_query_id_ == 0) {
|
||||||
|
// ok
|
||||||
|
} else {
|
||||||
|
return on_query_error(query_id, Status::Error(8, "Call to requestQrCodeAuthentication unexpected"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (was_check_bot_token_) {
|
||||||
|
return on_query_error(
|
||||||
|
query_id,
|
||||||
|
Status::Error(8,
|
||||||
|
"Cannot request QR code authentication after bot token was entered. You need to log out first"));
|
||||||
|
}
|
||||||
|
for (auto &other_user_id : other_user_ids) {
|
||||||
|
UserId user_id(other_user_id);
|
||||||
|
if (!user_id.is_valid()) {
|
||||||
|
return on_query_error(query_id, Status::Error(400, "Invalid user_id among other user_ids"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
other_user_ids_ = std::move(other_user_ids);
|
||||||
|
send_code_helper_ = SendCodeHelper();
|
||||||
|
terms_of_service_ = TermsOfService();
|
||||||
|
was_qr_code_request_ = true;
|
||||||
|
|
||||||
|
on_new_query(query_id);
|
||||||
|
|
||||||
|
send_export_login_token_query();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::send_export_login_token_query() {
|
||||||
|
poll_export_login_code_timeout_.cancel_timeout();
|
||||||
|
start_net_query(NetQueryType::RequestQrCode,
|
||||||
|
G()->net_query_creator().create(create_storer(telegram_api::auth_exportLoginToken(
|
||||||
|
api_id_, api_hash_, vector<int32>(other_user_ids_))),
|
||||||
|
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::set_login_token_expires_at(double login_token_expires_at) {
|
||||||
|
login_token_expires_at_ = login_token_expires_at;
|
||||||
|
poll_export_login_code_timeout_.cancel_timeout();
|
||||||
|
poll_export_login_code_timeout_.set_callback(std::move(on_update_login_token_static));
|
||||||
|
poll_export_login_code_timeout_.set_callback_data(static_cast<void *>(G()->td().get_actor_unsafe()));
|
||||||
|
poll_export_login_code_timeout_.set_timeout_at(login_token_expires_at_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::on_update_login_token_static(void *td) {
|
||||||
|
static_cast<Td *>(td)->auth_manager_->on_update_login_token();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::on_update_login_token() {
|
||||||
|
if (G()->close_flag()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state_ != State::WaitQrCodeConfirmation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
send_export_login_token_query();
|
||||||
|
}
|
||||||
|
|
||||||
void AuthManager::set_phone_number(uint64 query_id, string phone_number,
|
void AuthManager::set_phone_number(uint64 query_id, string phone_number,
|
||||||
td_api::object_ptr<td_api::phoneNumberAuthenticationSettings> settings) {
|
td_api::object_ptr<td_api::phoneNumberAuthenticationSettings> settings) {
|
||||||
if (state_ != State::WaitPhoneNumber) {
|
if (state_ != State::WaitPhoneNumber) {
|
||||||
@ -180,7 +247,7 @@ void AuthManager::set_phone_number(uint64 query_id, string phone_number,
|
|||||||
net_query_id_ == 0) {
|
net_query_id_ == 0) {
|
||||||
// ok
|
// ok
|
||||||
} else {
|
} else {
|
||||||
return on_query_error(query_id, Status::Error(8, "setAuthenticationPhoneNumber unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to setAuthenticationPhoneNumber unexpected"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (was_check_bot_token_) {
|
if (was_check_bot_token_) {
|
||||||
@ -191,6 +258,9 @@ void AuthManager::set_phone_number(uint64 query_id, string phone_number,
|
|||||||
return on_query_error(query_id, Status::Error(8, "Phone number can't be empty"));
|
return on_query_error(query_id, Status::Error(8, "Phone number can't be empty"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
other_user_ids_.clear();
|
||||||
|
was_qr_code_request_ = false;
|
||||||
|
|
||||||
auto r_send_code = send_code_helper_.send_code(phone_number, settings, api_id_, api_hash_);
|
auto r_send_code = send_code_helper_.send_code(phone_number, settings, api_id_, api_hash_);
|
||||||
if (r_send_code.is_error()) {
|
if (r_send_code.is_error()) {
|
||||||
send_code_helper_ = SendCodeHelper();
|
send_code_helper_ = SendCodeHelper();
|
||||||
@ -203,15 +273,14 @@ void AuthManager::set_phone_number(uint64 query_id, string phone_number,
|
|||||||
|
|
||||||
on_new_query(query_id);
|
on_new_query(query_id);
|
||||||
|
|
||||||
auto unique_id = UniqueId::next();
|
|
||||||
start_net_query(NetQueryType::SendCode,
|
start_net_query(NetQueryType::SendCode,
|
||||||
G()->net_query_creator().create(unique_id, create_storer(r_send_code.move_as_ok()), DcId::main(),
|
G()->net_query_creator().create(create_storer(r_send_code.move_as_ok()), DcId::main(),
|
||||||
NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthManager::resend_authentication_code(uint64 query_id) {
|
void AuthManager::resend_authentication_code(uint64 query_id) {
|
||||||
if (state_ != State::WaitCode || was_check_bot_token_) {
|
if (state_ != State::WaitCode) {
|
||||||
return on_query_error(query_id, Status::Error(8, "resendAuthenticationCode unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to resendAuthenticationCode unexpected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto r_resend_code = send_code_helper_.resend_code();
|
auto r_resend_code = send_code_helper_.resend_code();
|
||||||
@ -228,7 +297,7 @@ void AuthManager::resend_authentication_code(uint64 query_id) {
|
|||||||
|
|
||||||
void AuthManager::check_code(uint64 query_id, string code) {
|
void AuthManager::check_code(uint64 query_id, string code) {
|
||||||
if (state_ != State::WaitCode) {
|
if (state_ != State::WaitCode) {
|
||||||
return on_query_error(query_id, Status::Error(8, "checkAuthenticationCode unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to checkAuthenticationCode unexpected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
code_ = std::move(code);
|
code_ = std::move(code);
|
||||||
@ -242,7 +311,7 @@ void AuthManager::check_code(uint64 query_id, string code) {
|
|||||||
|
|
||||||
void AuthManager::register_user(uint64 query_id, string first_name, string last_name) {
|
void AuthManager::register_user(uint64 query_id, string first_name, string last_name) {
|
||||||
if (state_ != State::WaitRegistration) {
|
if (state_ != State::WaitRegistration) {
|
||||||
return on_query_error(query_id, Status::Error(8, "registerUser unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to registerUser unexpected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
on_new_query(query_id);
|
on_new_query(query_id);
|
||||||
@ -262,7 +331,7 @@ void AuthManager::register_user(uint64 query_id, string first_name, string last_
|
|||||||
|
|
||||||
void AuthManager::check_password(uint64 query_id, string password) {
|
void AuthManager::check_password(uint64 query_id, string password) {
|
||||||
if (state_ != State::WaitPassword) {
|
if (state_ != State::WaitPassword) {
|
||||||
return on_query_error(query_id, Status::Error(8, "checkAuthenticationPassword unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to checkAuthenticationPassword unexpected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Have SRP id " << wait_password_state_.srp_id_;
|
LOG(INFO) << "Have SRP id " << wait_password_state_.srp_id_;
|
||||||
@ -275,7 +344,7 @@ void AuthManager::check_password(uint64 query_id, string password) {
|
|||||||
|
|
||||||
void AuthManager::request_password_recovery(uint64 query_id) {
|
void AuthManager::request_password_recovery(uint64 query_id) {
|
||||||
if (state_ != State::WaitPassword) {
|
if (state_ != State::WaitPassword) {
|
||||||
return on_query_error(query_id, Status::Error(8, "requestAuthenticationPasswordRecovery unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to requestAuthenticationPasswordRecovery unexpected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
on_new_query(query_id);
|
on_new_query(query_id);
|
||||||
@ -286,7 +355,7 @@ void AuthManager::request_password_recovery(uint64 query_id) {
|
|||||||
|
|
||||||
void AuthManager::recover_password(uint64 query_id, string code) {
|
void AuthManager::recover_password(uint64 query_id, string code) {
|
||||||
if (state_ != State::WaitPassword) {
|
if (state_ != State::WaitPassword) {
|
||||||
return on_query_error(query_id, Status::Error(8, "recoverAuthenticationPassword unexpected"));
|
return on_query_error(query_id, Status::Error(8, "Call to recoverAuthenticationPassword unexpected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
on_new_query(query_id);
|
on_new_query(query_id);
|
||||||
@ -381,10 +450,6 @@ void AuthManager::start_net_query(NetQueryType net_query_type, NetQueryPtr net_q
|
|||||||
void AuthManager::on_send_code_result(NetQueryPtr &result) {
|
void AuthManager::on_send_code_result(NetQueryPtr &result) {
|
||||||
auto r_sent_code = fetch_result<telegram_api::auth_sendCode>(result->ok());
|
auto r_sent_code = fetch_result<telegram_api::auth_sendCode>(result->ok());
|
||||||
if (r_sent_code.is_error()) {
|
if (r_sent_code.is_error()) {
|
||||||
if (r_sent_code.error().message() == CSlice("PHONE_NUMBER_BANNED")) {
|
|
||||||
LOG(PLAIN) << "Your phone number was banned for suspicious activity. If you think that this is a mistake, please "
|
|
||||||
"write to recover@telegram.org your phone number and other details to recover the account.";
|
|
||||||
}
|
|
||||||
return on_query_error(r_sent_code.move_as_error());
|
return on_query_error(r_sent_code.move_as_error());
|
||||||
}
|
}
|
||||||
auto sent_code = r_sent_code.move_as_ok();
|
auto sent_code = r_sent_code.move_as_ok();
|
||||||
@ -397,6 +462,85 @@ void AuthManager::on_send_code_result(NetQueryPtr &result) {
|
|||||||
on_query_ok();
|
on_query_ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AuthManager::on_request_qr_code_result(NetQueryPtr &result, bool is_import) {
|
||||||
|
Status status;
|
||||||
|
if (result->is_ok()) {
|
||||||
|
auto r_login_token = fetch_result<telegram_api::auth_exportLoginToken>(result->ok());
|
||||||
|
if (r_login_token.is_ok()) {
|
||||||
|
auto login_token = r_login_token.move_as_ok();
|
||||||
|
|
||||||
|
if (is_import) {
|
||||||
|
CHECK(DcId::is_valid(imported_dc_id_));
|
||||||
|
G()->net_query_dispatcher().set_main_dc_id(imported_dc_id_);
|
||||||
|
imported_dc_id_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
on_get_login_token(std::move(login_token));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = r_login_token.move_as_error();
|
||||||
|
} else {
|
||||||
|
status = std::move(result->error());
|
||||||
|
}
|
||||||
|
CHECK(status.is_error());
|
||||||
|
|
||||||
|
LOG(INFO) << "Receive " << status << " for login token " << (is_import ? "import" : "export");
|
||||||
|
if (is_import) {
|
||||||
|
imported_dc_id_ = -1;
|
||||||
|
}
|
||||||
|
if (query_id_ != 0) {
|
||||||
|
on_query_error(std::move(status));
|
||||||
|
} else {
|
||||||
|
login_code_retry_delay_ = td::clamp(2 * login_code_retry_delay_, 1, 60);
|
||||||
|
set_login_token_expires_at(Time::now() + login_code_retry_delay_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AuthManager::on_get_login_token(tl_object_ptr<telegram_api::auth_LoginToken> login_token) {
|
||||||
|
LOG(INFO) << "Receive " << to_string(login_token);
|
||||||
|
|
||||||
|
login_code_retry_delay_ = 0;
|
||||||
|
|
||||||
|
CHECK(login_token != nullptr);
|
||||||
|
switch (login_token->get_id()) {
|
||||||
|
case telegram_api::auth_loginToken::ID: {
|
||||||
|
auto token = move_tl_object_as<telegram_api::auth_loginToken>(login_token);
|
||||||
|
login_token_ = token->token_.as_slice().str();
|
||||||
|
set_login_token_expires_at(Time::now() + td::max(token->expires_ - G()->server_time(), 1.0));
|
||||||
|
update_state(State::WaitQrCodeConfirmation, true);
|
||||||
|
if (query_id_ != 0) {
|
||||||
|
on_query_ok();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case telegram_api::auth_loginTokenMigrateTo::ID: {
|
||||||
|
auto token = move_tl_object_as<telegram_api::auth_loginTokenMigrateTo>(login_token);
|
||||||
|
if (!DcId::is_valid(token->dc_id_)) {
|
||||||
|
LOG(ERROR) << "Receive wrong DC " << token->dc_id_;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (query_id_ != 0) {
|
||||||
|
on_query_ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
imported_dc_id_ = token->dc_id_;
|
||||||
|
start_net_query(NetQueryType::ImportQrCode,
|
||||||
|
G()->net_query_creator().create(
|
||||||
|
create_storer(telegram_api::auth_importLoginToken(std::move(token->token_))),
|
||||||
|
DcId::internal(token->dc_id_), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case telegram_api::auth_loginTokenSuccess::ID: {
|
||||||
|
auto token = move_tl_object_as<telegram_api::auth_loginTokenSuccess>(login_token);
|
||||||
|
on_get_authorization(std::move(token->authorization_));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AuthManager::on_get_password_result(NetQueryPtr &result) {
|
void AuthManager::on_get_password_result(NetQueryPtr &result) {
|
||||||
auto r_password = fetch_result<telegram_api::account_getPassword>(result->ok());
|
auto r_password = fetch_result<telegram_api::account_getPassword>(result->ok());
|
||||||
if (r_password.is_error()) {
|
if (r_password.is_error()) {
|
||||||
@ -427,6 +571,8 @@ void AuthManager::on_get_password_result(NetQueryPtr &result) {
|
|||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
} else if (was_qr_code_request_) {
|
||||||
|
send_export_login_token_query();
|
||||||
} else {
|
} else {
|
||||||
start_net_query(NetQueryType::SignIn,
|
start_net_query(NetQueryType::SignIn,
|
||||||
G()->net_query_creator().create(
|
G()->net_query_creator().create(
|
||||||
@ -464,15 +610,15 @@ void AuthManager::on_request_password_recovery_result(NetQueryPtr &result) {
|
|||||||
on_query_ok();
|
on_query_ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthManager::on_authentication_result(NetQueryPtr &result, bool expected_flag) {
|
void AuthManager::on_authentication_result(NetQueryPtr &result, bool is_error_expected) {
|
||||||
auto r_sign_in = fetch_result<telegram_api::auth_signIn>(result->ok());
|
auto r_sign_in = fetch_result<telegram_api::auth_signIn>(result->ok());
|
||||||
if (r_sign_in.is_error()) {
|
if (r_sign_in.is_error()) {
|
||||||
if (expected_flag && query_id_ != 0) {
|
if (is_error_expected && query_id_ != 0) {
|
||||||
return on_query_error(r_sign_in.move_as_error());
|
return on_query_error(r_sign_in.move_as_error());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
on_authorization(r_sign_in.move_as_ok());
|
on_get_authorization(r_sign_in.move_as_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthManager::on_log_out_result(NetQueryPtr &result) {
|
void AuthManager::on_log_out_result(NetQueryPtr &result) {
|
||||||
@ -543,7 +689,7 @@ void AuthManager::on_delete_account_result(NetQueryPtr &result) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthManager::on_authorization(tl_object_ptr<telegram_api::auth_Authorization> auth_ptr) {
|
void AuthManager::on_get_authorization(tl_object_ptr<telegram_api::auth_Authorization> auth_ptr) {
|
||||||
if (state_ == State::Ok) {
|
if (state_ == State::Ok) {
|
||||||
LOG(WARNING) << "Ignore duplicated auth.Authorization";
|
LOG(WARNING) << "Ignore duplicated auth.Authorization";
|
||||||
if (query_id_ != 0) {
|
if (query_id_ != 0) {
|
||||||
@ -572,7 +718,7 @@ void AuthManager::on_authorization(tl_object_ptr<telegram_api::auth_Authorizatio
|
|||||||
code_.clear();
|
code_.clear();
|
||||||
password_.clear();
|
password_.clear();
|
||||||
state_ = State::Ok;
|
state_ = State::Ok;
|
||||||
td->contacts_manager_->on_get_user(std::move(auth->user_), "on_authorization", true);
|
td->contacts_manager_->on_get_user(std::move(auth->user_), "on_get_authorization", true);
|
||||||
update_state(State::Ok, true);
|
update_state(State::Ok, true);
|
||||||
if (!td->contacts_manager_->get_my_id().is_valid()) {
|
if (!td->contacts_manager_->get_my_id().is_valid()) {
|
||||||
LOG(ERROR) << "Server doesn't send proper authorization";
|
LOG(ERROR) << "Server doesn't send proper authorization";
|
||||||
@ -587,7 +733,7 @@ void AuthManager::on_authorization(tl_object_ptr<telegram_api::auth_Authorizatio
|
|||||||
}
|
}
|
||||||
td->notification_manager_->init();
|
td->notification_manager_->init();
|
||||||
send_closure(td->top_dialog_manager_, &TopDialogManager::do_start_up);
|
send_closure(td->top_dialog_manager_, &TopDialogManager::do_start_up);
|
||||||
td->updates_manager_->get_difference("on_authorization");
|
td->updates_manager_->get_difference("on_get_authorization");
|
||||||
td->on_online_updated(false, true);
|
td->on_online_updated(false, true);
|
||||||
td->schedule_get_terms_of_service(0);
|
td->schedule_get_terms_of_service(0);
|
||||||
if (!is_bot()) {
|
if (!is_bot()) {
|
||||||
@ -604,28 +750,41 @@ void AuthManager::on_result(NetQueryPtr result) {
|
|||||||
result->clear();
|
result->clear();
|
||||||
};
|
};
|
||||||
NetQueryType type = NetQueryType::None;
|
NetQueryType type = NetQueryType::None;
|
||||||
|
LOG(INFO) << "Receive result of query " << result->id() << ", expecting " << net_query_id_ << " with type "
|
||||||
|
<< static_cast<int32>(net_query_type_);
|
||||||
if (result->id() == net_query_id_) {
|
if (result->id() == net_query_id_) {
|
||||||
net_query_id_ = 0;
|
net_query_id_ = 0;
|
||||||
type = net_query_type_;
|
type = net_query_type_;
|
||||||
net_query_type_ = NetQueryType::None;
|
net_query_type_ = NetQueryType::None;
|
||||||
if (result->is_error()) {
|
if (result->is_error()) {
|
||||||
if (type == NetQueryType::SignIn && result->error().code() == 401 &&
|
if ((type == NetQueryType::SignIn || type == NetQueryType::RequestQrCode || type == NetQueryType::ImportQrCode) &&
|
||||||
result->error().message() == CSlice("SESSION_PASSWORD_NEEDED")) {
|
result->error().code() == 401 && result->error().message() == CSlice("SESSION_PASSWORD_NEEDED")) {
|
||||||
start_net_query(NetQueryType::GetPassword,
|
start_net_query(NetQueryType::GetPassword,
|
||||||
G()->net_query_creator().create(create_storer(telegram_api::account_getPassword()),
|
G()->net_query_creator().create(create_storer(telegram_api::account_getPassword()),
|
||||||
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type != NetQueryType::LogOut) {
|
if (result->error().message() == CSlice("PHONE_NUMBER_BANNED")) {
|
||||||
|
LOG(PLAIN)
|
||||||
|
<< "Your phone number was banned for suspicious activity. If you think that this is a mistake, please "
|
||||||
|
"write to recover@telegram.org your phone number and other details to recover the account.";
|
||||||
|
}
|
||||||
|
if (type != NetQueryType::LogOut && type != NetQueryType::DeleteAccount) {
|
||||||
if (query_id_ != 0) {
|
if (query_id_ != 0) {
|
||||||
if (state_ == State::WaitPhoneNumber) {
|
if (state_ == State::WaitPhoneNumber) {
|
||||||
|
other_user_ids_.clear();
|
||||||
send_code_helper_ = SendCodeHelper();
|
send_code_helper_ = SendCodeHelper();
|
||||||
terms_of_service_ = TermsOfService();
|
terms_of_service_ = TermsOfService();
|
||||||
|
was_qr_code_request_ = false;
|
||||||
|
was_check_bot_token_ = false;
|
||||||
}
|
}
|
||||||
on_query_error(std::move(result->error()));
|
on_query_error(std::move(result->error()));
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (type != NetQueryType::RequestQrCode && type != NetQueryType::ImportQrCode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (result->is_ok() && result->ok_tl_constructor() == telegram_api::auth_authorization::ID) {
|
} else if (result->is_ok() && result->ok_tl_constructor() == telegram_api::auth_authorization::ID) {
|
||||||
type = NetQueryType::Authentication;
|
type = NetQueryType::Authentication;
|
||||||
@ -647,6 +806,12 @@ void AuthManager::on_result(NetQueryPtr result) {
|
|||||||
case NetQueryType::SendCode:
|
case NetQueryType::SendCode:
|
||||||
on_send_code_result(result);
|
on_send_code_result(result);
|
||||||
break;
|
break;
|
||||||
|
case NetQueryType::RequestQrCode:
|
||||||
|
on_request_qr_code_result(result, false);
|
||||||
|
break;
|
||||||
|
case NetQueryType::ImportQrCode:
|
||||||
|
on_request_qr_code_result(result, true);
|
||||||
|
break;
|
||||||
case NetQueryType::GetPassword:
|
case NetQueryType::GetPassword:
|
||||||
on_get_password_result(result);
|
on_get_password_result(result);
|
||||||
break;
|
break;
|
||||||
@ -708,6 +873,10 @@ bool AuthManager::load_state() {
|
|||||||
LOG(INFO) << "Load auth_state from database: " << tag("state", static_cast<int32>(db_state.state_));
|
LOG(INFO) << "Load auth_state from database: " << tag("state", static_cast<int32>(db_state.state_));
|
||||||
if (db_state.state_ == State::WaitCode) {
|
if (db_state.state_ == State::WaitCode) {
|
||||||
send_code_helper_ = std::move(db_state.send_code_helper_);
|
send_code_helper_ = std::move(db_state.send_code_helper_);
|
||||||
|
} else if (db_state.state_ == State::WaitQrCodeConfirmation) {
|
||||||
|
other_user_ids_ = std::move(db_state.other_user_ids_);
|
||||||
|
login_token_ = std::move(db_state.login_token_);
|
||||||
|
set_login_token_expires_at(db_state.login_token_expires_at_);
|
||||||
} else if (db_state.state_ == State::WaitPassword) {
|
} else if (db_state.state_ == State::WaitPassword) {
|
||||||
wait_password_state_ = std::move(db_state.wait_password_state_);
|
wait_password_state_ = std::move(db_state.wait_password_state_);
|
||||||
} else if (db_state.state_ == State::WaitRegistration) {
|
} else if (db_state.state_ == State::WaitRegistration) {
|
||||||
@ -721,7 +890,8 @@ bool AuthManager::load_state() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AuthManager::save_state() {
|
void AuthManager::save_state() {
|
||||||
if (state_ != State::WaitCode && state_ != State::WaitPassword && state_ != State::WaitRegistration) {
|
if (state_ != State::WaitCode && state_ != State::WaitQrCodeConfirmation && state_ != State::WaitPassword &&
|
||||||
|
state_ != State::WaitRegistration) {
|
||||||
if (state_ != State::Closing) {
|
if (state_ != State::Closing) {
|
||||||
G()->td_db()->get_binlog_pmc()->erase("auth_state");
|
G()->td_db()->get_binlog_pmc()->erase("auth_state");
|
||||||
}
|
}
|
||||||
@ -731,6 +901,9 @@ void AuthManager::save_state() {
|
|||||||
DbState db_state = [&] {
|
DbState db_state = [&] {
|
||||||
if (state_ == State::WaitCode) {
|
if (state_ == State::WaitCode) {
|
||||||
return DbState::wait_code(api_id_, api_hash_, send_code_helper_);
|
return DbState::wait_code(api_id_, api_hash_, send_code_helper_);
|
||||||
|
} else if (state_ == State::WaitQrCodeConfirmation) {
|
||||||
|
return DbState::wait_qr_code_confirmation(api_id_, api_hash_, other_user_ids_, login_token_,
|
||||||
|
login_token_expires_at_);
|
||||||
} else if (state_ == State::WaitPassword) {
|
} else if (state_ == State::WaitPassword) {
|
||||||
return DbState::wait_password(api_id_, api_hash_, wait_password_state_);
|
return DbState::wait_password(api_id_, api_hash_, wait_password_state_);
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "td/telegram/telegram_api.h"
|
#include "td/telegram/telegram_api.h"
|
||||||
|
|
||||||
#include "td/actor/actor.h"
|
#include "td/actor/actor.h"
|
||||||
|
#include "td/actor/PromiseFuture.h"
|
||||||
|
#include "td/actor/Timeout.h"
|
||||||
|
|
||||||
#include "td/utils/common.h"
|
#include "td/utils/common.h"
|
||||||
#include "td/utils/Status.h"
|
#include "td/utils/Status.h"
|
||||||
@ -37,6 +39,7 @@ class AuthManager : public NetActor {
|
|||||||
void resend_authentication_code(uint64 query_id);
|
void resend_authentication_code(uint64 query_id);
|
||||||
void check_code(uint64 query_id, string code);
|
void check_code(uint64 query_id, string code);
|
||||||
void register_user(uint64 query_id, string first_name, string last_name);
|
void register_user(uint64 query_id, string first_name, string last_name);
|
||||||
|
void request_qr_code_authentication(uint64 query_id, vector<int32> other_user_ids);
|
||||||
void check_bot_token(uint64 query_id, string bot_token);
|
void check_bot_token(uint64 query_id, string bot_token);
|
||||||
void check_password(uint64 query_id, string password);
|
void check_password(uint64 query_id, string password);
|
||||||
void request_password_recovery(uint64 query_id);
|
void request_password_recovery(uint64 query_id);
|
||||||
@ -44,6 +47,8 @@ class AuthManager : public NetActor {
|
|||||||
void logout(uint64 query_id);
|
void logout(uint64 query_id);
|
||||||
void delete_account(uint64 query_id, const string &reason);
|
void delete_account(uint64 query_id, const string &reason);
|
||||||
|
|
||||||
|
void on_update_login_token();
|
||||||
|
|
||||||
void on_authorization_lost();
|
void on_authorization_lost();
|
||||||
void on_closing(bool destroy_flag);
|
void on_closing(bool destroy_flag);
|
||||||
|
|
||||||
@ -57,6 +62,7 @@ class AuthManager : public NetActor {
|
|||||||
None,
|
None,
|
||||||
WaitPhoneNumber,
|
WaitPhoneNumber,
|
||||||
WaitCode,
|
WaitCode,
|
||||||
|
WaitQrCodeConfirmation,
|
||||||
WaitPassword,
|
WaitPassword,
|
||||||
WaitRegistration,
|
WaitRegistration,
|
||||||
Ok,
|
Ok,
|
||||||
@ -69,6 +75,8 @@ class AuthManager : public NetActor {
|
|||||||
SignIn,
|
SignIn,
|
||||||
SignUp,
|
SignUp,
|
||||||
SendCode,
|
SendCode,
|
||||||
|
RequestQrCode,
|
||||||
|
ImportQrCode,
|
||||||
GetPassword,
|
GetPassword,
|
||||||
CheckPassword,
|
CheckPassword,
|
||||||
RequestPasswordRecovery,
|
RequestPasswordRecovery,
|
||||||
@ -105,6 +113,11 @@ class AuthManager : public NetActor {
|
|||||||
// WaitCode
|
// WaitCode
|
||||||
SendCodeHelper send_code_helper_;
|
SendCodeHelper send_code_helper_;
|
||||||
|
|
||||||
|
// WaitQrCodeConfirmation
|
||||||
|
vector<int32> other_user_ids_;
|
||||||
|
string login_token_;
|
||||||
|
double login_token_expires_at_ = 0;
|
||||||
|
|
||||||
// WaitPassword
|
// WaitPassword
|
||||||
WaitPasswordState wait_password_state_;
|
WaitPasswordState wait_password_state_;
|
||||||
|
|
||||||
@ -118,6 +131,15 @@ class AuthManager : public NetActor {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DbState wait_qr_code_confirmation(int32 api_id, string api_hash, vector<int32> other_user_ids,
|
||||||
|
string login_token, double login_token_expires_at) {
|
||||||
|
DbState state(State::WaitQrCodeConfirmation, api_id, api_hash);
|
||||||
|
state.other_user_ids_ = std::move(other_user_ids);
|
||||||
|
state.login_token_ = std::move(login_token);
|
||||||
|
state.login_token_expires_at_ = login_token_expires_at;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
static DbState wait_password(int32 api_id, string api_hash, WaitPasswordState wait_password_state) {
|
static DbState wait_password(int32 api_id, string api_hash, WaitPasswordState wait_password_state) {
|
||||||
DbState state(State::WaitPassword, api_id, api_hash);
|
DbState state(State::WaitPassword, api_id, api_hash);
|
||||||
state.wait_password_state_ = std::move(wait_password_state);
|
state.wait_password_state_ = std::move(wait_password_state);
|
||||||
@ -157,6 +179,12 @@ class AuthManager : public NetActor {
|
|||||||
SendCodeHelper send_code_helper_;
|
SendCodeHelper send_code_helper_;
|
||||||
string code_;
|
string code_;
|
||||||
|
|
||||||
|
// State::WaitQrCodeConfirmation
|
||||||
|
vector<int32> other_user_ids_;
|
||||||
|
string login_token_;
|
||||||
|
double login_token_expires_at_ = 0.0;
|
||||||
|
int32 imported_dc_id_ = -1;
|
||||||
|
|
||||||
// State::WaitPassword
|
// State::WaitPassword
|
||||||
string password_;
|
string password_;
|
||||||
|
|
||||||
@ -165,10 +193,15 @@ class AuthManager : public NetActor {
|
|||||||
|
|
||||||
// for bots
|
// for bots
|
||||||
string bot_token_;
|
string bot_token_;
|
||||||
|
|
||||||
uint64 query_id_ = 0;
|
uint64 query_id_ = 0;
|
||||||
|
|
||||||
WaitPasswordState wait_password_state_;
|
WaitPasswordState wait_password_state_;
|
||||||
|
|
||||||
|
int32 login_code_retry_delay_ = 0;
|
||||||
|
Timeout poll_export_login_code_timeout_;
|
||||||
|
|
||||||
|
bool was_qr_code_request_ = false;
|
||||||
bool was_check_bot_token_ = false;
|
bool was_check_bot_token_ = false;
|
||||||
bool is_bot_ = false;
|
bool is_bot_ = false;
|
||||||
uint64 net_query_id_ = 0;
|
uint64 net_query_id_ = 0;
|
||||||
@ -182,15 +215,20 @@ class AuthManager : public NetActor {
|
|||||||
void on_query_ok();
|
void on_query_ok();
|
||||||
void start_net_query(NetQueryType net_query_type, NetQueryPtr net_query);
|
void start_net_query(NetQueryType net_query_type, NetQueryPtr net_query);
|
||||||
|
|
||||||
|
static void on_update_login_token_static(void *td);
|
||||||
|
void send_export_login_token_query();
|
||||||
|
void set_login_token_expires_at(double login_token_expires_at);
|
||||||
void destroy_auth_keys();
|
void destroy_auth_keys();
|
||||||
|
|
||||||
void on_send_code_result(NetQueryPtr &result);
|
void on_send_code_result(NetQueryPtr &result);
|
||||||
|
void on_request_qr_code_result(NetQueryPtr &result, bool is_import);
|
||||||
void on_get_password_result(NetQueryPtr &result);
|
void on_get_password_result(NetQueryPtr &result);
|
||||||
void on_request_password_recovery_result(NetQueryPtr &result);
|
void on_request_password_recovery_result(NetQueryPtr &result);
|
||||||
void on_authentication_result(NetQueryPtr &result, bool expected_flag);
|
void on_authentication_result(NetQueryPtr &result, bool expected_flag);
|
||||||
void on_log_out_result(NetQueryPtr &result);
|
void on_log_out_result(NetQueryPtr &result);
|
||||||
void on_delete_account_result(NetQueryPtr &result);
|
void on_delete_account_result(NetQueryPtr &result);
|
||||||
void on_authorization(tl_object_ptr<telegram_api::auth_Authorization> auth_ptr);
|
void on_get_login_token(tl_object_ptr<telegram_api::auth_LoginToken> login_token);
|
||||||
|
void on_get_authorization(tl_object_ptr<telegram_api::auth_Authorization> auth_ptr);
|
||||||
|
|
||||||
void on_result(NetQueryPtr result) override;
|
void on_result(NetQueryPtr result) override;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "td/telegram/AuthManager.h"
|
#include "td/telegram/AuthManager.h"
|
||||||
|
#include "td/telegram/logevent/LogEventHelper.h"
|
||||||
#include "td/telegram/SendCodeHelper.hpp"
|
#include "td/telegram/SendCodeHelper.hpp"
|
||||||
#include "td/telegram/Version.h"
|
#include "td/telegram/Version.h"
|
||||||
|
|
||||||
@ -53,12 +53,14 @@ void AuthManager::DbState::store(StorerT &storer) const {
|
|||||||
bool is_srp_supported = true;
|
bool is_srp_supported = true;
|
||||||
bool is_wait_registration_supported = true;
|
bool is_wait_registration_supported = true;
|
||||||
bool is_wait_registration_stores_phone_number = true;
|
bool is_wait_registration_stores_phone_number = true;
|
||||||
|
bool is_wait_qr_code_confirmation_supported = true;
|
||||||
BEGIN_STORE_FLAGS();
|
BEGIN_STORE_FLAGS();
|
||||||
STORE_FLAG(has_terms_of_service);
|
STORE_FLAG(has_terms_of_service);
|
||||||
STORE_FLAG(is_pbkdf2_supported);
|
STORE_FLAG(is_pbkdf2_supported);
|
||||||
STORE_FLAG(is_srp_supported);
|
STORE_FLAG(is_srp_supported);
|
||||||
STORE_FLAG(is_wait_registration_supported);
|
STORE_FLAG(is_wait_registration_supported);
|
||||||
STORE_FLAG(is_wait_registration_stores_phone_number);
|
STORE_FLAG(is_wait_registration_stores_phone_number);
|
||||||
|
STORE_FLAG(is_wait_qr_code_confirmation_supported);
|
||||||
END_STORE_FLAGS();
|
END_STORE_FLAGS();
|
||||||
store(state_, storer);
|
store(state_, storer);
|
||||||
store(api_id_, storer);
|
store(api_id_, storer);
|
||||||
@ -71,6 +73,10 @@ void AuthManager::DbState::store(StorerT &storer) const {
|
|||||||
|
|
||||||
if (state_ == State::WaitCode) {
|
if (state_ == State::WaitCode) {
|
||||||
store(send_code_helper_, storer);
|
store(send_code_helper_, storer);
|
||||||
|
} else if (state_ == State::WaitQrCodeConfirmation) {
|
||||||
|
store(other_user_ids_, storer);
|
||||||
|
store(login_token_, storer);
|
||||||
|
store_time(login_token_expires_at_, storer);
|
||||||
} else if (state_ == State::WaitPassword) {
|
} else if (state_ == State::WaitPassword) {
|
||||||
store(wait_password_state_, storer);
|
store(wait_password_state_, storer);
|
||||||
} else if (state_ == State::WaitRegistration) {
|
} else if (state_ == State::WaitRegistration) {
|
||||||
@ -88,6 +94,7 @@ void AuthManager::DbState::parse(ParserT &parser) {
|
|||||||
bool is_srp_supported = false;
|
bool is_srp_supported = false;
|
||||||
bool is_wait_registration_supported = false;
|
bool is_wait_registration_supported = false;
|
||||||
bool is_wait_registration_stores_phone_number = false;
|
bool is_wait_registration_stores_phone_number = false;
|
||||||
|
bool is_wait_qr_code_confirmation_supported = false;
|
||||||
if (parser.version() >= static_cast<int32>(Version::AddTermsOfService)) {
|
if (parser.version() >= static_cast<int32>(Version::AddTermsOfService)) {
|
||||||
BEGIN_PARSE_FLAGS();
|
BEGIN_PARSE_FLAGS();
|
||||||
PARSE_FLAG(has_terms_of_service);
|
PARSE_FLAG(has_terms_of_service);
|
||||||
@ -95,13 +102,16 @@ void AuthManager::DbState::parse(ParserT &parser) {
|
|||||||
PARSE_FLAG(is_srp_supported);
|
PARSE_FLAG(is_srp_supported);
|
||||||
PARSE_FLAG(is_wait_registration_supported);
|
PARSE_FLAG(is_wait_registration_supported);
|
||||||
PARSE_FLAG(is_wait_registration_stores_phone_number);
|
PARSE_FLAG(is_wait_registration_stores_phone_number);
|
||||||
|
PARSE_FLAG(is_wait_qr_code_confirmation_supported);
|
||||||
END_PARSE_FLAGS();
|
END_PARSE_FLAGS();
|
||||||
}
|
}
|
||||||
if (!is_wait_registration_supported || !is_wait_registration_stores_phone_number) {
|
if (!is_wait_qr_code_confirmation_supported) {
|
||||||
return parser.set_error("Have no wait registration support");
|
return parser.set_error("Have no QR code confirmation support");
|
||||||
}
|
}
|
||||||
CHECK(is_pbkdf2_supported);
|
CHECK(is_pbkdf2_supported);
|
||||||
CHECK(is_srp_supported);
|
CHECK(is_srp_supported);
|
||||||
|
CHECK(is_wait_registration_supported);
|
||||||
|
CHECK(is_wait_registration_stores_phone_number);
|
||||||
|
|
||||||
parse(state_, parser);
|
parse(state_, parser);
|
||||||
parse(api_id_, parser);
|
parse(api_id_, parser);
|
||||||
@ -114,6 +124,10 @@ void AuthManager::DbState::parse(ParserT &parser) {
|
|||||||
|
|
||||||
if (state_ == State::WaitCode) {
|
if (state_ == State::WaitCode) {
|
||||||
parse(send_code_helper_, parser);
|
parse(send_code_helper_, parser);
|
||||||
|
} else if (state_ == State::WaitQrCodeConfirmation) {
|
||||||
|
parse(other_user_ids_, parser);
|
||||||
|
parse(login_token_, parser);
|
||||||
|
parse_time(login_token_expires_at_, parser);
|
||||||
} else if (state_ == State::WaitPassword) {
|
} else if (state_ == State::WaitPassword) {
|
||||||
parse(wait_password_state_, parser);
|
parse(wait_password_state_, parser);
|
||||||
} else if (state_ == State::WaitRegistration) {
|
} else if (state_ == State::WaitRegistration) {
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "td/db/SqliteKeyValue.h"
|
#include "td/db/SqliteKeyValue.h"
|
||||||
#include "td/db/SqliteKeyValueAsync.h"
|
#include "td/db/SqliteKeyValueAsync.h"
|
||||||
|
|
||||||
|
#include "td/utils/base64.h"
|
||||||
#include "td/utils/buffer.h"
|
#include "td/utils/buffer.h"
|
||||||
#include "td/utils/format.h"
|
#include "td/utils/format.h"
|
||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
@ -124,11 +125,50 @@ class GetAccountTtlQuery : public Td::ResultHandler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static td_api::object_ptr<td_api::session> convert_authorization_object(
|
||||||
|
tl_object_ptr<telegram_api::authorization> &&authorization) {
|
||||||
|
CHECK(authorization != nullptr);
|
||||||
|
bool is_current = (authorization->flags_ & telegram_api::authorization::CURRENT_MASK) != 0;
|
||||||
|
bool is_official_application = (authorization->flags_ & telegram_api::authorization::OFFICIAL_APP_MASK) != 0;
|
||||||
|
bool is_password_pending = (authorization->flags_ & telegram_api::authorization::PASSWORD_PENDING_MASK) != 0;
|
||||||
|
|
||||||
|
return td_api::make_object<td_api::session>(
|
||||||
|
authorization->hash_, is_current, is_password_pending, authorization->api_id_, authorization->app_name_,
|
||||||
|
authorization->app_version_, is_official_application, authorization->device_model_, authorization->platform_,
|
||||||
|
authorization->system_version_, authorization->date_created_, authorization->date_active_, authorization->ip_,
|
||||||
|
authorization->country_, authorization->region_);
|
||||||
|
}
|
||||||
|
|
||||||
|
class AcceptLoginTokenQuery : public Td::ResultHandler {
|
||||||
|
Promise<td_api::object_ptr<td_api::session>> promise_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AcceptLoginTokenQuery(Promise<td_api::object_ptr<td_api::session>> &&promise)
|
||||||
|
: promise_(std::move(promise)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void send(const string &login_token) {
|
||||||
|
send_query(
|
||||||
|
G()->net_query_creator().create(create_storer(telegram_api::auth_acceptLoginToken(BufferSlice(login_token)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_result(uint64 id, BufferSlice packet) override {
|
||||||
|
auto result_ptr = fetch_result<telegram_api::auth_acceptLoginToken>(packet);
|
||||||
|
if (result_ptr.is_error()) {
|
||||||
|
return on_error(id, result_ptr.move_as_error());
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(DEBUG) << "Receive result for AcceptLoginTokenQuery: " << to_string(result_ptr.ok());
|
||||||
|
promise_.set_value(convert_authorization_object(std::move(result_ptr.move_as_ok())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_error(uint64 id, Status status) override {
|
||||||
|
promise_.set_error(std::move(status));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class GetAuthorizationsQuery : public Td::ResultHandler {
|
class GetAuthorizationsQuery : public Td::ResultHandler {
|
||||||
Promise<tl_object_ptr<td_api::sessions>> promise_;
|
Promise<tl_object_ptr<td_api::sessions>> promise_;
|
||||||
static constexpr int32 AUTHORIZATION_FLAG_IS_CURRENT = 1 << 0;
|
|
||||||
static constexpr int32 AUTHORIZATION_FLAG_IS_OFFICIAL_APPLICATION = 1 << 1;
|
|
||||||
static constexpr int32 AUTHORIZATION_FLAG_IS_PASSWORD_PENDING = 1 << 2;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GetAuthorizationsQuery(Promise<tl_object_ptr<td_api::sessions>> &&promise) : promise_(std::move(promise)) {
|
explicit GetAuthorizationsQuery(Promise<tl_object_ptr<td_api::sessions>> &&promise) : promise_(std::move(promise)) {
|
||||||
@ -147,21 +187,8 @@ class GetAuthorizationsQuery : public Td::ResultHandler {
|
|||||||
auto ptr = result_ptr.move_as_ok();
|
auto ptr = result_ptr.move_as_ok();
|
||||||
LOG(INFO) << "Receive result for GetAuthorizationsQuery: " << to_string(ptr);
|
LOG(INFO) << "Receive result for GetAuthorizationsQuery: " << to_string(ptr);
|
||||||
|
|
||||||
auto results = make_tl_object<td_api::sessions>();
|
auto results =
|
||||||
results->sessions_.reserve(ptr->authorizations_.size());
|
make_tl_object<td_api::sessions>(transform(std::move(ptr->authorizations_), convert_authorization_object));
|
||||||
for (auto &authorization : ptr->authorizations_) {
|
|
||||||
CHECK(authorization != nullptr);
|
|
||||||
bool is_current = (authorization->flags_ & AUTHORIZATION_FLAG_IS_CURRENT) != 0;
|
|
||||||
bool is_official_application = (authorization->flags_ & AUTHORIZATION_FLAG_IS_OFFICIAL_APPLICATION) != 0;
|
|
||||||
bool is_password_pending = (authorization->flags_ & AUTHORIZATION_FLAG_IS_PASSWORD_PENDING) != 0;
|
|
||||||
|
|
||||||
results->sessions_.push_back(make_tl_object<td_api::session>(
|
|
||||||
authorization->hash_, is_current, is_password_pending, authorization->api_id_, authorization->app_name_,
|
|
||||||
authorization->app_version_, is_official_application, authorization->device_model_, authorization->platform_,
|
|
||||||
authorization->system_version_, authorization->date_created_, authorization->date_active_, authorization->ip_,
|
|
||||||
authorization->country_, authorization->region_));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(results->sessions_.begin(), results->sessions_.end(),
|
std::sort(results->sessions_.begin(), results->sessions_.end(),
|
||||||
[](const td_api::object_ptr<td_api::session> &lhs, const td_api::object_ptr<td_api::session> &rhs) {
|
[](const td_api::object_ptr<td_api::session> &lhs, const td_api::object_ptr<td_api::session> &rhs) {
|
||||||
if (lhs->is_current_ != rhs->is_current_) {
|
if (lhs->is_current_ != rhs->is_current_) {
|
||||||
@ -4112,6 +4139,19 @@ void ContactsManager::get_account_ttl(Promise<int32> &&promise) const {
|
|||||||
td_->create_handler<GetAccountTtlQuery>(std::move(promise))->send();
|
td_->create_handler<GetAccountTtlQuery>(std::move(promise))->send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContactsManager::confirm_qr_code_authentication(string link,
|
||||||
|
Promise<td_api::object_ptr<td_api::session>> &&promise) {
|
||||||
|
Slice prefix("tg://login?");
|
||||||
|
if (!begins_with(to_lower(link), prefix)) {
|
||||||
|
return promise.set_error(Status::Error(400, "AUTH_TOKEN_INVALID"));
|
||||||
|
}
|
||||||
|
auto r_token = base64url_decode(Slice(link).substr(prefix.size()));
|
||||||
|
if (r_token.is_error()) {
|
||||||
|
return promise.set_error(Status::Error(400, "AUTH_TOKEN_INVALID"));
|
||||||
|
}
|
||||||
|
td_->create_handler<AcceptLoginTokenQuery>(std::move(promise))->send(r_token.ok());
|
||||||
|
}
|
||||||
|
|
||||||
void ContactsManager::get_active_sessions(Promise<tl_object_ptr<td_api::sessions>> &&promise) const {
|
void ContactsManager::get_active_sessions(Promise<tl_object_ptr<td_api::sessions>> &&promise) const {
|
||||||
td_->create_handler<GetAuthorizationsQuery>(std::move(promise))->send();
|
td_->create_handler<GetAuthorizationsQuery>(std::move(promise))->send();
|
||||||
}
|
}
|
||||||
|
@ -260,6 +260,8 @@ class ContactsManager : public Actor {
|
|||||||
void set_account_ttl(int32 account_ttl, Promise<Unit> &&promise) const;
|
void set_account_ttl(int32 account_ttl, Promise<Unit> &&promise) const;
|
||||||
void get_account_ttl(Promise<int32> &&promise) const;
|
void get_account_ttl(Promise<int32> &&promise) const;
|
||||||
|
|
||||||
|
void confirm_qr_code_authentication(string link, Promise<td_api::object_ptr<td_api::session>> &&promise);
|
||||||
|
|
||||||
void get_active_sessions(Promise<tl_object_ptr<td_api::sessions>> &&promise) const;
|
void get_active_sessions(Promise<tl_object_ptr<td_api::sessions>> &&promise) const;
|
||||||
void terminate_session(int64 session_id, Promise<Unit> &&promise) const;
|
void terminate_session(int64 session_id, Promise<Unit> &&promise) const;
|
||||||
void terminate_all_other_sessions(Promise<Unit> &&promise) const;
|
void terminate_all_other_sessions(Promise<Unit> &&promise) const;
|
||||||
|
@ -3450,6 +3450,7 @@ bool Td::is_authentication_request(int32 id) {
|
|||||||
case td_api::resendAuthenticationCode::ID:
|
case td_api::resendAuthenticationCode::ID:
|
||||||
case td_api::checkAuthenticationCode::ID:
|
case td_api::checkAuthenticationCode::ID:
|
||||||
case td_api::registerUser::ID:
|
case td_api::registerUser::ID:
|
||||||
|
case td_api::requestQrCodeAuthentication::ID:
|
||||||
case td_api::checkAuthenticationPassword::ID:
|
case td_api::checkAuthenticationPassword::ID:
|
||||||
case td_api::requestAuthenticationPasswordRecovery::ID:
|
case td_api::requestAuthenticationPasswordRecovery::ID:
|
||||||
case td_api::recoverAuthenticationPassword::ID:
|
case td_api::recoverAuthenticationPassword::ID:
|
||||||
@ -4957,6 +4958,11 @@ void Td::on_request(uint64 id, td_api::registerUser &request) {
|
|||||||
std::move(request.last_name_));
|
std::move(request.last_name_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Td::on_request(uint64 id, td_api::requestQrCodeAuthentication &request) {
|
||||||
|
send_closure(auth_manager_actor_, &AuthManager::request_qr_code_authentication, id,
|
||||||
|
std::move(request.other_user_ids_));
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, td_api::checkAuthenticationPassword &request) {
|
void Td::on_request(uint64 id, td_api::checkAuthenticationPassword &request) {
|
||||||
CLEAN_INPUT_STRING(request.password_);
|
CLEAN_INPUT_STRING(request.password_);
|
||||||
send_closure(auth_manager_actor_, &AuthManager::check_password, id, std::move(request.password_));
|
send_closure(auth_manager_actor_, &AuthManager::check_password, id, std::move(request.password_));
|
||||||
@ -4993,6 +4999,12 @@ void Td::on_request(uint64 id, td_api::checkAuthenticationBotToken &request) {
|
|||||||
send_closure(auth_manager_actor_, &AuthManager::check_bot_token, id, std::move(request.token_));
|
send_closure(auth_manager_actor_, &AuthManager::check_bot_token, id, std::move(request.token_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Td::on_request(uint64 id, td_api::confirmQrCodeAuthentication &request) {
|
||||||
|
CLEAN_INPUT_STRING(request.link_);
|
||||||
|
CREATE_REQUEST_PROMISE();
|
||||||
|
contacts_manager_->confirm_qr_code_authentication(std::move(request.link_), std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
void Td::on_request(uint64 id, const td_api::getCurrentState &request) {
|
void Td::on_request(uint64 id, const td_api::getCurrentState &request) {
|
||||||
vector<td_api::object_ptr<td_api::Update>> updates;
|
vector<td_api::object_ptr<td_api::Update>> updates;
|
||||||
|
|
||||||
|
@ -374,6 +374,8 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::registerUser &request);
|
void on_request(uint64 id, td_api::registerUser &request);
|
||||||
|
|
||||||
|
void on_request(uint64 id, td_api::requestQrCodeAuthentication &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::checkAuthenticationPassword &request);
|
void on_request(uint64 id, td_api::checkAuthenticationPassword &request);
|
||||||
|
|
||||||
void on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request);
|
void on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request);
|
||||||
@ -388,6 +390,8 @@ class Td final : public NetQueryCallback {
|
|||||||
|
|
||||||
void on_request(uint64 id, td_api::checkAuthenticationBotToken &request);
|
void on_request(uint64 id, td_api::checkAuthenticationBotToken &request);
|
||||||
|
|
||||||
|
void on_request(uint64 id, td_api::confirmQrCodeAuthentication &request);
|
||||||
|
|
||||||
void on_request(uint64 id, const td_api::getCurrentState &request);
|
void on_request(uint64 id, const td_api::getCurrentState &request);
|
||||||
|
|
||||||
void on_request(uint64 id, td_api::getPasswordState &request);
|
void on_request(uint64 id, td_api::getPasswordState &request);
|
||||||
|
@ -623,7 +623,12 @@ void UpdatesManager::on_get_updates(tl_object_ptr<telegram_api::Updates> &&updat
|
|||||||
LOG(INFO) << "Receive " << to_string(updates_ptr);
|
LOG(INFO) << "Receive " << to_string(updates_ptr);
|
||||||
}
|
}
|
||||||
if (!td_->auth_manager_->is_authorized()) {
|
if (!td_->auth_manager_->is_authorized()) {
|
||||||
LOG(INFO) << "Ignore updates received before authorization or after logout";
|
if (updates_type == telegram_api::updateShort::ID &&
|
||||||
|
static_cast<const telegram_api::updateShort *>(updates_ptr.get())->update_->get_id() ==
|
||||||
|
telegram_api::updateLoginToken::ID) {
|
||||||
|
return td_->auth_manager_->on_update_login_token();
|
||||||
|
}
|
||||||
|
LOG(INFO) << "Ignore received before authorization or after logout " << to_string(updates_ptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1975,12 +1980,13 @@ void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateDeleteScheduled
|
|||||||
td_->messages_manager_->on_update_delete_scheduled_messages(DialogId(update->peer_), std::move(message_ids));
|
td_->messages_manager_->on_update_delete_scheduled_messages(DialogId(update->peer_), std::move(message_ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateLoginToken> update, bool /*force_apply*/) {
|
||||||
|
LOG(INFO) << "Receive updateLoginToken after authorization";
|
||||||
|
}
|
||||||
|
|
||||||
// unsupported updates
|
// unsupported updates
|
||||||
|
|
||||||
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateTheme> update, bool /*force_apply*/) {
|
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateTheme> update, bool /*force_apply*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdatesManager::on_update(tl_object_ptr<telegram_api::updateLoginToken> update, bool /*force_apply*/) {
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -285,11 +285,11 @@ class UpdatesManager : public Actor {
|
|||||||
void on_update(tl_object_ptr<telegram_api::updateNewScheduledMessage> update, bool /*force_apply*/);
|
void on_update(tl_object_ptr<telegram_api::updateNewScheduledMessage> update, bool /*force_apply*/);
|
||||||
void on_update(tl_object_ptr<telegram_api::updateDeleteScheduledMessages> update, bool /*force_apply*/);
|
void on_update(tl_object_ptr<telegram_api::updateDeleteScheduledMessages> update, bool /*force_apply*/);
|
||||||
|
|
||||||
|
void on_update(tl_object_ptr<telegram_api::updateLoginToken> update, bool /*force_apply*/);
|
||||||
|
|
||||||
// unsupported updates
|
// unsupported updates
|
||||||
|
|
||||||
void on_update(tl_object_ptr<telegram_api::updateTheme> update, bool /*force_apply*/);
|
void on_update(tl_object_ptr<telegram_api::updateTheme> update, bool /*force_apply*/);
|
||||||
|
|
||||||
void on_update(tl_object_ptr<telegram_api::updateLoginToken> update, bool /*force_apply*/);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -1327,8 +1327,12 @@ class CliClient final : public Actor {
|
|||||||
send_request(td_api::make_object<td_api::registerUser>(first_name, last_name));
|
send_request(td_api::make_object<td_api::registerUser>(first_name, last_name));
|
||||||
} else if (op == "cap") {
|
} else if (op == "cap") {
|
||||||
send_request(td_api::make_object<td_api::checkAuthenticationPassword>(args));
|
send_request(td_api::make_object<td_api::checkAuthenticationPassword>(args));
|
||||||
} else if (op == "cab" || op == "cabt") {
|
} else if (op == "cabt") {
|
||||||
send_request(td_api::make_object<td_api::checkAuthenticationBotToken>(args));
|
send_request(td_api::make_object<td_api::checkAuthenticationBotToken>(args));
|
||||||
|
} else if (op == "qr") {
|
||||||
|
send_request(td_api::make_object<td_api::requestQrCodeAuthentication>(as_user_ids(args)));
|
||||||
|
} else if (op == "cqr") {
|
||||||
|
send_request(td_api::make_object<td_api::confirmQrCodeAuthentication>(args));
|
||||||
} else if (op == "gcs") {
|
} else if (op == "gcs") {
|
||||||
send_request(td_api::make_object<td_api::getCurrentState>());
|
send_request(td_api::make_object<td_api::getCurrentState>());
|
||||||
} else if (op == "rapr") {
|
} else if (op == "rapr") {
|
||||||
|
@ -324,7 +324,7 @@ void NetQueryDispatcher::set_main_dc_id(int32 new_main_dc_id) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Update: " << tag("main_dc_id", main_dc_id_.load(std::memory_order_relaxed));
|
LOG(INFO) << "Update main DcId from " << main_dc_id_.load(std::memory_order_relaxed) << " to " << new_main_dc_id;
|
||||||
if (is_dc_inited(main_dc_id_.load(std::memory_order_relaxed))) {
|
if (is_dc_inited(main_dc_id_.load(std::memory_order_relaxed))) {
|
||||||
send_closure_later(dcs_[main_dc_id_ - 1].main_session_, &SessionMultiProxy::update_main_flag, false);
|
send_closure_later(dcs_[main_dc_id_ - 1].main_session_, &SessionMultiProxy::update_main_flag, false);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,9 @@ class Timeout final : public Actor {
|
|||||||
void set_timeout_in(double timeout) {
|
void set_timeout_in(double timeout) {
|
||||||
Actor::set_timeout_in(timeout);
|
Actor::set_timeout_in(timeout);
|
||||||
}
|
}
|
||||||
|
void set_timeout_at(double timeout) {
|
||||||
|
Actor::set_timeout_at(timeout);
|
||||||
|
}
|
||||||
void cancel_timeout() {
|
void cancel_timeout() {
|
||||||
if (has_timeout()) {
|
if (has_timeout()) {
|
||||||
Actor::cancel_timeout();
|
Actor::cancel_timeout();
|
||||||
@ -52,10 +55,6 @@ class Timeout final : public Actor {
|
|||||||
Callback callback_{};
|
Callback callback_{};
|
||||||
Data data_{};
|
Data data_{};
|
||||||
|
|
||||||
void set_timeout_at(double timeout) {
|
|
||||||
Actor::set_timeout_at(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void timeout_expired() override {
|
void timeout_expired() override {
|
||||||
CHECK(!has_timeout());
|
CHECK(!has_timeout());
|
||||||
CHECK(callback_ != Callback());
|
CHECK(callback_ != Callback());
|
||||||
|
Loading…
Reference in New Issue
Block a user