Add separate authorizationStateWaitRegistration.

GitOrigin-RevId: 1e41124d6174e956ce74266c9140ad346cf8a6f0
This commit is contained in:
levlam 2019-07-16 22:08:34 +03:00
parent 93ee925d69
commit b1347c3226
18 changed files with 166 additions and 101 deletions

View File

@ -237,19 +237,21 @@ class TdExample {
need_restart_ = true;
std::cerr << "Terminated" << std::endl;
},
[this](td_api::authorizationStateWaitCode &wait_code) {
[this](td_api::authorizationStateWaitCode &) {
std::cerr << "Enter authentication code: ";
std::string code;
std::cin >> code;
send_query(td_api::make_object<td_api::checkAuthenticationCode>(code),
create_authentication_query_handler());
},
[this](td_api::authorizationStateWaitRegistration &) {
std::string first_name;
std::string last_name;
if (!wait_code.is_registered_) {
std::cerr << "Enter your first name: ";
std::cin >> first_name;
std::cerr << "Enter your last name: ";
std::cin >> last_name;
}
std::cerr << "Enter authentication code: ";
std::string code;
std::cin >> code;
send_query(td_api::make_object<td_api::checkAuthenticationCode>(code, first_name, last_name),
send_query(td_api::make_object<td_api::registerUser>(first_name, last_name),
create_authentication_query_handler());
},
[this](td_api::authorizationStateWaitPassword &) {

View File

@ -98,7 +98,13 @@ namespace TdExample
else if (_authorizationState is TdApi.AuthorizationStateWaitCode)
{
string code = ReadLine("Please enter authentication code: ");
_client.Send(new TdApi.CheckAuthenticationCode(code, "", ""), new AuthorizationRequestHandler());
_client.Send(new TdApi.CheckAuthenticationCode(code), new AuthorizationRequestHandler());
}
else if (_authorizationState is TdApi.AuthorizationStateWaitRegistration)
{
string firstName = ReadLine("Please enter your first name: ");
string lastName = ReadLine("Please enter your last name: ");
_client.Send(new TdApi.RegisterUser(firstName, lastName), new AuthorizationRequestHandler());
}
else if (_authorizationState is TdApi.AuthorizationStateWaitPassword)
{

View File

@ -117,7 +117,13 @@ public final class Example {
}
case TdApi.AuthorizationStateWaitCode.CONSTRUCTOR: {
String code = promptString("Please enter authentication code: ");
client.send(new TdApi.CheckAuthenticationCode(code, "", ""), new AuthorizationRequestHandler());
client.send(new TdApi.CheckAuthenticationCode(code), new AuthorizationRequestHandler());
break;
}
case TdApi.AuthorizationStateWaitRegistration.CONSTRUCTOR: {
String firstName = promptString("Please enter your first name: ");
String lastName = promptString("Please enter your last name: ");
client.send(new TdApi.RegisterUser(firstName, lastName), new AuthorizationRequestHandler());
break;
}
case TdApi.AuthorizationStateWaitPassword.CONSTRUCTOR: {

View File

@ -124,6 +124,12 @@ while True:
code = input('Please enter the authentication code you received: ')
td_send({'@type': 'checkAuthenticationCode', 'code': code})
# wait for first and last name for new users
if auth_state['@type'] == 'authorizationStateWaitRegistration':
first_name = input('Please enter your first name: ')
last_name = input('Please enter your last name: ')
td_send({'@type': 'registerUser', 'first_name': first_name, 'last_name': last_name})
# wait for password if present
if auth_state['@type'] == 'authorizationStateWaitPassword':
password = input('Please enter your password: ')

View File

@ -132,19 +132,19 @@ func updateAuthorizationState(authorizationState: Dictionary<String, Any>) {
client.queryAsync(query:["@type":"setAuthenticationPhoneNumber", "phone_number":phone], f:checkAuthenticationError)
case "authorizationStateWaitCode":
var code: String = ""
print("Enter (SMS) code: ")
code = myReadLine()
client.queryAsync(query:["@type":"checkAuthenticationCode", "code":code], f:checkAuthenticationError)
case "authorizationStateWaitRegistration":
var first_name: String = ""
var last_name: String = ""
var code: String = ""
if let is_registered = authorizationState["is_registered"] as? Bool, is_registered {
} else {
print("Enter your first name: ")
first_name = myReadLine()
print("Enter your last name: ")
last_name = myReadLine()
}
print("Enter (SMS) code: ")
code = myReadLine()
client.queryAsync(query:["@type":"checkAuthenticationCode", "code":code, "first_name":first_name, "last_name":last_name], f:checkAuthenticationError)
client.queryAsync(query:["@type":"registerUser", "first_name":first_name, "last_name":last_name], f:checkAuthenticationError)
case "authorizationStateWaitPassword":
print("Enter password: ")

View File

@ -100,7 +100,7 @@ namespace TdApp
{
var args = command.Split(" ".ToCharArray(), 2);
AcceptCommand(command);
_client.Send(new TdApi.CheckAuthenticationCode(args[1], String.Empty, String.Empty), _handler);
_client.Send(new TdApi.CheckAuthenticationCode(args[1]), _handler);
}
else if (command.StartsWith("cap"))
{

View File

@ -88,8 +88,11 @@ authorizationStateWaitEncryptionKey is_encrypted:Bool = AuthorizationState;
//@description TDLib needs the user's phone number to authorize
authorizationStateWaitPhoneNumber = AuthorizationState;
//@description TDLib needs the user's authentication code to finalize authorization @is_registered True, if the user is already registered @terms_of_service Telegram terms of service, which should be accepted before user can continue registration; may be null @code_info Information about the authorization code that was sent
authorizationStateWaitCode is_registered:Bool terms_of_service:termsOfService code_info:authenticationCodeInfo = AuthorizationState;
//@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;
//@description The user is unregistered and need to accept terms of service and enter his first name and last name to finish registration @terms_of_service Telegram terms of service
authorizationStateWaitRegistration terms_of_service:termsOfService = AuthorizationState;
//@description The user has been authorized, but needs to enter a password to start using the application @password_hint Hint for the password; may be empty @has_recovery_email_address True, if a recovery email address has been set up
//@recovery_email_address_pattern Pattern of the email address to which the recovery email was sent; empty until a recovery email has been sent
@ -2805,9 +2808,11 @@ setAuthenticationPhoneNumber phone_number:string settings:phoneNumberAuthenticat
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
//@first_name If the user is not yet registered, the first name of the user; 1-64 characters. You can also pass an empty string for unregistered user there to check verification code validness. In the latter case PHONE_NUMBER_UNOCCUPIED error will be returned for a valid code
//@last_name If the user is not yet registered; the last name of the user; optional; 0-64 characters
checkAuthenticationCode code:string first_name:string last_name:string = Ok;
checkAuthenticationCode code:string = Ok;
//@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
registerUser first_name:string last_name:string = Ok;
//@description Checks the authentication password for correctness. Works only when the current authorization state is authorizationStateWaitPassword @password The password to check
checkAuthenticationPassword password:string = Ok;

Binary file not shown.

View File

@ -99,9 +99,12 @@ tl_object_ptr<td_api::AuthorizationState> AuthManager::get_authorization_state_o
case State::Ok:
return make_tl_object<td_api::authorizationStateReady>();
case State::WaitCode:
return send_code_helper_.get_authorization_state_wait_code(terms_of_service_);
return send_code_helper_.get_authorization_state_wait_code();
case State::WaitPhoneNumber:
return make_tl_object<td_api::authorizationStateWaitPhoneNumber>();
case State::WaitRegistration:
return make_tl_object<td_api::authorizationStateWaitRegistration>(
terms_of_service_.get_terms_of_service_object());
case State::WaitPassword:
return make_tl_object<td_api::authorizationStateWaitPassword>(
wait_password_state_.hint_, wait_password_state_.has_recovery_, wait_password_state_.email_address_pattern_);
@ -169,7 +172,8 @@ void AuthManager::check_bot_token(uint64 query_id, string bot_token) {
void AuthManager::set_phone_number(uint64 query_id, string phone_number,
td_api::object_ptr<td_api::phoneNumberAuthenticationSettings> settings) {
if (state_ != State::WaitPhoneNumber) {
if ((state_ == State::WaitCode || state_ == State::WaitPassword) && net_query_id_ == 0) {
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, "setAuthenticationPhoneNumber unexpected"));
@ -218,20 +222,26 @@ void AuthManager::resend_authentication_code(uint64 query_id) {
NetQuery::Type::Common, NetQuery::AuthFlag::Off));
}
void AuthManager::check_code(uint64 query_id, string code, string first_name, string last_name) {
void AuthManager::check_code(uint64 query_id, string code) {
if (state_ != State::WaitCode) {
return on_query_error(query_id, Status::Error(8, "checkAuthenticationCode unexpected"));
}
code_ = code;
code_ = std::move(code);
on_new_query(query_id);
if (send_code_helper_.phone_registered() || first_name.empty()) {
start_net_query(NetQueryType::SignIn,
G()->net_query_creator().create(
create_storer(telegram_api::auth_signIn(send_code_helper_.phone_number().str(),
send_code_helper_.phone_code_hash().str(), code)),
send_code_helper_.phone_code_hash().str(), code_)),
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
} else {
}
void AuthManager::register_user(uint64 query_id, string first_name, string last_name) {
if (state_ != State::WaitRegistration) {
return on_query_error(query_id, Status::Error(8, "registerUser unexpected"));
}
on_new_query(query_id);
first_name = clean_name(first_name, MAX_NAME_LENGTH);
if (first_name.empty()) {
return on_query_error(Status::Error(8, "First name can't be empty"));
@ -240,12 +250,11 @@ void AuthManager::check_code(uint64 query_id, string code, string first_name, st
last_name = clean_name(last_name, MAX_NAME_LENGTH);
start_net_query(
NetQueryType::SignUp,
G()->net_query_creator().create(create_storer(telegram_api::auth_signUp(
send_code_helper_.phone_number().str(),
send_code_helper_.phone_code_hash().str(), code, first_name, last_name)),
G()->net_query_creator().create(create_storer(telegram_api::auth_signUp(send_code_helper_.phone_number().str(),
send_code_helper_.phone_code_hash().str(),
code_, first_name, last_name)),
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
}
}
void AuthManager::check_password(uint64 query_id, string password) {
if (state_ != State::WaitPassword) {
@ -374,7 +383,9 @@ void AuthManager::on_send_code_result(NetQueryPtr &result) {
LOG(INFO) << "Receive " << to_string(sent_code);
if (terms_of_service_.get_id().empty()) {
terms_of_service_ = TermsOfService(std::move(sent_code->terms_of_service_));
}
send_code_helper_.on_sent_code(std::move(sent_code));
@ -591,6 +602,12 @@ void AuthManager::on_result(NetQueryPtr result) {
DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::Off));
return;
}
if (type == NetQueryType::SignIn && result->error().message() == CSlice("PHONE_NUMBER_UNOCCUPIED")) {
code_ = "11111";
update_state(State::WaitRegistration);
on_query_ok();
return;
}
if (type != NetQueryType::LogOut) {
if (query_id_ != 0) {
if (state_ == State::WaitPhoneNumber) {
@ -686,6 +703,9 @@ bool AuthManager::load_state() {
terms_of_service_ = std::move(db_state.terms_of_service_);
} else if (db_state.state_ == State::WaitPassword) {
wait_password_state_ = std::move(db_state.wait_password_state_);
} else if (db_state.state_ == State::WaitRegistration) {
code_ = "11111"; // the code has already been checked
terms_of_service_ = std::move(db_state.terms_of_service_);
} else {
UNREACHABLE();
}
@ -694,21 +714,23 @@ bool AuthManager::load_state() {
}
void AuthManager::save_state() {
if (state_ != State::WaitCode && state_ != State::WaitPassword) {
if (state_ != State::WaitCode && state_ != State::WaitPassword && state_ != State::WaitRegistration) {
if (state_ != State::Closing) {
G()->td_db()->get_binlog_pmc()->erase("auth_state");
}
return;
}
DbState db_state;
DbState db_state = [&] {
if (state_ == State::WaitCode) {
db_state = DbState::wait_code(api_id_, api_hash_, send_code_helper_, terms_of_service_);
return DbState::wait_code(api_id_, api_hash_, send_code_helper_, terms_of_service_);
} else if (state_ == State::WaitPassword) {
db_state = DbState::wait_password(api_id_, api_hash_, wait_password_state_);
return DbState::wait_password(api_id_, api_hash_, wait_password_state_);
} else {
UNREACHABLE();
CHECK(state_ == State::WaitRegistration);
return DbState::wait_registration(api_id_, api_hash_, terms_of_service_);
}
}();
G()->td_db()->get_binlog_pmc()->set("auth_state", log_event_store(db_state).as_slice().str());
}

View File

@ -35,7 +35,8 @@ class AuthManager : public NetActor {
void set_phone_number(uint64 query_id, string phone_number,
td_api::object_ptr<td_api::phoneNumberAuthenticationSettings> settings);
void resend_authentication_code(uint64 query_id);
void check_code(uint64 query_id, string code, string first_name, string last_name);
void check_code(uint64 query_id, string code);
void register_user(uint64 query_id, string first_name, string last_name);
void check_bot_token(uint64 query_id, string bot_token);
void check_password(uint64 query_id, string password);
void request_password_recovery(uint64 query_id);
@ -57,6 +58,7 @@ class AuthManager : public NetActor {
WaitPhoneNumber,
WaitCode,
WaitPassword,
WaitRegistration,
Ok,
LoggingOut,
DestroyingKeys,
@ -102,30 +104,32 @@ class AuthManager : public NetActor {
// WaitCode
SendCodeHelper send_code_helper_;
TermsOfService terms_of_service_;
// WaitPassword
WaitPasswordState wait_password_state_;
// WaitRegistration
TermsOfService terms_of_service_;
DbState() = default;
// TODO layer 104+: remove terms_of_service
static DbState wait_code(int32 api_id, string api_hash, SendCodeHelper send_code_helper,
TermsOfService terms_of_service) {
DbState state;
state.state_ = State::WaitCode;
state.api_id_ = api_id;
state.api_hash_ = api_hash;
DbState state(State::WaitCode, api_id, api_hash);
state.send_code_helper_ = std::move(send_code_helper);
state.terms_of_service_ = std::move(terms_of_service);
state.state_timestamp_ = Timestamp::now();
return state;
}
static DbState wait_password(int32 api_id, string api_hash, WaitPasswordState wait_password_state) {
DbState state;
state.state_ = State::WaitPassword;
state.api_id_ = api_id;
state.api_hash_ = api_hash;
DbState state(State::WaitPassword, api_id, api_hash);
state.wait_password_state_ = std::move(wait_password_state);
state.state_timestamp_ = Timestamp::now();
return state;
}
static DbState wait_registration(int32 api_id, string api_hash, TermsOfService terms_of_service) {
DbState state(State::WaitRegistration, api_id, api_hash);
state.terms_of_service_ = std::move(terms_of_service);
return state;
}
@ -133,6 +137,11 @@ class AuthManager : public NetActor {
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
private:
DbState(State state, int32 api_id, string api_hash)
: state_(state), api_id_(api_id), api_hash_(api_hash), state_timestamp_(Timestamp::now()) {
}
};
bool load_state();
@ -148,7 +157,11 @@ class AuthManager : public NetActor {
// State::WaitCode
SendCodeHelper send_code_helper_;
string code_;
// State::WaitPassword
string password_;
// State::WaitRegistration
TermsOfService terms_of_service_;
// for bots

View File

@ -51,10 +51,12 @@ void AuthManager::DbState::store(StorerT &storer) const {
bool has_terms_of_service = !terms_of_service_.get_id().empty();
bool is_pbkdf2_supported = true;
bool is_srp_supported = true;
bool is_wait_registration_supported = true;
BEGIN_STORE_FLAGS();
STORE_FLAG(has_terms_of_service);
STORE_FLAG(is_pbkdf2_supported);
STORE_FLAG(is_srp_supported);
STORE_FLAG(is_wait_registration_supported);
END_STORE_FLAGS();
store(state_, storer);
store(api_id_, storer);
@ -69,6 +71,7 @@ void AuthManager::DbState::store(StorerT &storer) const {
store(send_code_helper_, storer);
} else if (state_ == State::WaitPassword) {
store(wait_password_state_, storer);
} else if (state_ == State::WaitRegistration) {
} else {
UNREACHABLE();
}
@ -80,13 +83,21 @@ void AuthManager::DbState::parse(ParserT &parser) {
bool has_terms_of_service = false;
bool is_pbkdf2_supported = false;
bool is_srp_supported = false;
bool is_wait_registration_supported = false;
if (parser.version() >= static_cast<int32>(Version::AddTermsOfService)) {
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_terms_of_service);
PARSE_FLAG(is_pbkdf2_supported);
PARSE_FLAG(is_srp_supported);
PARSE_FLAG(is_wait_registration_supported);
END_PARSE_FLAGS();
}
if (!is_wait_registration_supported) {
return parser.set_error("Have no wait registration support");
}
CHECK(is_pbkdf2_supported);
CHECK(is_srp_supported);
parse(state_, parser);
parse(api_id_, parser);
parse(api_hash_, parser);
@ -98,17 +109,9 @@ void AuthManager::DbState::parse(ParserT &parser) {
if (state_ == State::WaitCode) {
parse(send_code_helper_, parser);
if (parser.version() < static_cast<int32>(Version::AddTermsOfService)) {
return parser.set_error("Have no terms of service");
}
} else if (state_ == State::WaitPassword) {
if (!is_pbkdf2_supported) {
return parser.set_error("Need PBKDF2 support");
}
if (!is_srp_supported) {
return parser.set_error("Need SRP support");
}
parse(wait_password_state_, parser);
} else if (state_ == State::WaitRegistration) {
} else {
parser.set_error(PSTRING() << "Unexpected " << tag("state", static_cast<int32>(state_)));
}

View File

@ -11,17 +11,14 @@
namespace td {
void SendCodeHelper::on_sent_code(telegram_api::object_ptr<telegram_api::auth_sentCode> sent_code) {
phone_registered_ = (sent_code->flags_ & SENT_CODE_FLAG_IS_USER_REGISTERED) != 0;
phone_code_hash_ = sent_code->phone_code_hash_;
sent_code_info_ = get_authentication_code_info(std::move(sent_code->type_));
next_code_info_ = get_authentication_code_info(std::move(sent_code->next_type_));
next_code_timestamp_ = Timestamp::in((sent_code->flags_ & SENT_CODE_FLAG_HAS_TIMEOUT) != 0 ? sent_code->timeout_ : 0);
}
td_api::object_ptr<td_api::authorizationStateWaitCode> SendCodeHelper::get_authorization_state_wait_code(
const TermsOfService &terms_of_service) const {
return make_tl_object<td_api::authorizationStateWaitCode>(
phone_registered_, terms_of_service.get_terms_of_service_object(), get_authentication_code_info_object());
td_api::object_ptr<td_api::authorizationStateWaitCode> SendCodeHelper::get_authorization_state_wait_code() const {
return make_tl_object<td_api::authorizationStateWaitCode>(get_authentication_code_info_object());
}
td_api::object_ptr<td_api::authenticationCodeInfo> SendCodeHelper::get_authentication_code_info_object() const {

View File

@ -8,7 +8,6 @@
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/telegram/TermsOfService.h"
#include "td/utils/common.h"
#include "td/utils/Slice.h"
@ -20,8 +19,7 @@ namespace td {
class SendCodeHelper {
public:
void on_sent_code(telegram_api::object_ptr<telegram_api::auth_sentCode> sent_code);
td_api::object_ptr<td_api::authorizationStateWaitCode> get_authorization_state_wait_code(
const TermsOfService &terms_of_service) const;
td_api::object_ptr<td_api::authorizationStateWaitCode> get_authorization_state_wait_code() const;
td_api::object_ptr<td_api::authenticationCodeInfo> get_authentication_code_info_object() const;
Result<telegram_api::auth_resendCode> resend_code();
@ -45,9 +43,6 @@ class SendCodeHelper {
Slice phone_code_hash() const {
return phone_code_hash_;
}
bool phone_registered() const {
return phone_registered_;
}
template <class StorerT>
void store(StorerT &storer) const;
@ -77,7 +72,6 @@ class SendCodeHelper {
};
string phone_number_;
bool phone_registered_;
string phone_code_hash_;
SendCodeHelper::AuthenticationCodeInfo sent_code_info_;

View File

@ -32,7 +32,7 @@ template <class StorerT>
void SendCodeHelper::store(StorerT &storer) const {
using td::store;
store(phone_number_, storer);
store(phone_registered_, storer);
store(true, storer);
store(phone_code_hash_, storer);
store(sent_code_info_, storer);
store(next_code_info_, storer);
@ -41,9 +41,10 @@ void SendCodeHelper::store(StorerT &storer) const {
template <class ParserT>
void SendCodeHelper::parse(ParserT &parser) {
bool legacy_is_registered = false;
using td::parse;
parse(phone_number_, parser);
parse(phone_registered_, parser);
parse(legacy_is_registered, parser);
parse(phone_code_hash_, parser);
parse(sent_code_info_, parser);
parse(next_code_info_, parser);

View File

@ -3254,6 +3254,7 @@ bool Td::is_authentication_request(int32 id) {
case td_api::setAuthenticationPhoneNumber::ID:
case td_api::resendAuthenticationCode::ID:
case td_api::checkAuthenticationCode::ID:
case td_api::registerUser::ID:
case td_api::checkAuthenticationPassword::ID:
case td_api::requestAuthenticationPasswordRecovery::ID:
case td_api::recoverAuthenticationPassword::ID:
@ -4741,10 +4742,14 @@ void Td::on_request(uint64 id, const td_api::resendAuthenticationCode &request)
void Td::on_request(uint64 id, td_api::checkAuthenticationCode &request) {
CLEAN_INPUT_STRING(request.code_);
send_closure(auth_manager_actor_, &AuthManager::check_code, id, std::move(request.code_));
}
void Td::on_request(uint64 id, td_api::registerUser &request) {
CLEAN_INPUT_STRING(request.first_name_);
CLEAN_INPUT_STRING(request.last_name_);
send_closure(auth_manager_actor_, &AuthManager::check_code, id, std::move(request.code_),
std::move(request.first_name_), std::move(request.last_name_));
send_closure(auth_manager_actor_, &AuthManager::register_user, id, std::move(request.first_name_),
std::move(request.last_name_));
}
void Td::on_request(uint64 id, td_api::checkAuthenticationPassword &request) {

View File

@ -372,6 +372,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::checkAuthenticationCode &request);
void on_request(uint64 id, td_api::registerUser &request);
void on_request(uint64 id, td_api::checkAuthenticationPassword &request);
void on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request);

View File

@ -1264,14 +1264,14 @@ class CliClient final : public Actor {
} else if (op == "sdek" || op == "SetDatabaseEncryptionKey") {
send_request(td_api::make_object<td_api::setDatabaseEncryptionKey>(args));
} else if (op == "cac") {
string code;
send_request(td_api::make_object<td_api::checkAuthenticationCode>(args));
} else if (op == "ru") {
string first_name;
string last_name;
std::tie(code, args) = split(args);
std::tie(first_name, last_name) = split(args);
send_request(td_api::make_object<td_api::checkAuthenticationCode>(code, first_name, last_name));
send_request(td_api::make_object<td_api::registerUser>(first_name, last_name));
} else if (op == "cap") {
send_request(td_api::make_object<td_api::checkAuthenticationPassword>(args));
} else if (op == "cab" || op == "cabt") {

View File

@ -215,7 +215,10 @@ class DoAuthentication : public Task {
function = make_tl_object<td_api::setAuthenticationPhoneNumber>(phone_, nullptr);
break;
case td_api::authorizationStateWaitCode::ID:
function = make_tl_object<td_api::checkAuthenticationCode>(code_, name_, "");
function = make_tl_object<td_api::checkAuthenticationCode>(code_);
break;
case td_api::authorizationStateWaitRegistration::ID:
function = make_tl_object<td_api::registerUser>(name_, "");
break;
case td_api::authorizationStateWaitTdlibParameters::ID: {
auto parameters = td_api::make_object<td_api::tdlibParameters>();