Add checkRecoveryEmailAddressCode method.

GitOrigin-RevId: 9601d8227586f988dae26ffb230c6f12f0196193
This commit is contained in:
levlam 2019-02-10 23:16:52 +03:00
parent 0075f91e2e
commit de9f167bff
7 changed files with 75 additions and 18 deletions

View File

@ -109,8 +109,10 @@ authorizationStateClosing = AuthorizationState;
authorizationStateClosed = AuthorizationState;
//@description Represents the current state of 2-step verification @has_password True, if a 2-step verification password is set @password_hint Hint for the password; can be empty @has_recovery_email_address True, if a recovery email is set @has_passport_data True, if some Telegram Passport elements were saved @unconfirmed_recovery_email_address_pattern Pattern of the email address to which the confirmation email was sent
passwordState has_password:Bool password_hint:string has_recovery_email_address:Bool has_passport_data:Bool unconfirmed_recovery_email_address_pattern:string = PasswordState;
//@description Represents the current state of 2-step verification @has_password True, if a 2-step verification password is set @password_hint Hint for the password; can be empty
//@has_recovery_email_address True, if a recovery email is set @has_passport_data True, if some Telegram Passport elements were saved
//@recovery_email_address_code_info Information about the recovery email address to which the confirmation email was sent; may be null
passwordState has_password:Bool password_hint:string has_recovery_email_address:Bool has_passport_data:Bool recovery_email_address_code_info:emailAddressAuthenticationCodeInfo = PasswordState;
//@description Contains information about the current recovery email address @recovery_email_address Recovery email address
recoveryEmailAddress recovery_email_address:string = RecoveryEmailAddress;
@ -2585,17 +2587,20 @@ setDatabaseEncryptionKey new_encryption_key:bytes = Ok;
//@description Returns the current state of 2-step verification
getPasswordState = PasswordState;
//@description Changes the password for the user. If a new recovery email address is specified, then the error EMAIL_UNCONFIRMED is returned and the password change will not be applied until the new recovery email address has been confirmed. The application should periodically call getPasswordState to check whether the new email address has been confirmed
//@description Changes the password for the user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed
//@old_password Previous password of the user @new_password New password of the user; may be empty to remove the password @new_hint New password hint; may be empty @set_recovery_email_address Pass true if the recovery email address should be changed @new_recovery_email_address New recovery email address; may be empty
setPassword old_password:string new_password:string new_hint:string set_recovery_email_address:Bool new_recovery_email_address:string = PasswordState;
//@description Returns a recovery email address that was previously set up. This method can be used to verify a password provided by the user @password The password for the current user
//@description Returns a 2-step verification recovery email address that was previously set up. This method can be used to verify a password provided by the user @password The password for the current user
getRecoveryEmailAddress password:string = RecoveryEmailAddress;
//@description Changes the recovery email address of the user. If a new recovery email address is specified, then the error EMAIL_UNCONFIRMED is returned and the email address will not be changed until the new email has been confirmed. The application should periodically call getPasswordState to check whether the email address has been confirmed.
//@description Changes the 2-step verification recovery email address of the user. If a new recovery email address is specified, then the change will not be applied until the new recovery email address is confirmed
//-If new_recovery_email_address is the same as the email address that is currently set up, this call succeeds immediately and aborts all other requests waiting for an email confirmation @password Password of the current user @new_recovery_email_address New recovery email address
setRecoveryEmailAddress password:string new_recovery_email_address:string = PasswordState;
//@description Checks the 2-step verification recovery email address code @code Verification code
checkRecoveryEmailAddressCode code:string = Ok;
//@description Requests to send a password recovery code to an email address that was previously set up
requestPasswordRecovery = EmailAddressAuthenticationCodeInfo;

Binary file not shown.

View File

@ -181,7 +181,8 @@ void PasswordManager::get_secure_secret(string password, Promise<secure_storage:
return do_get_secure_secret(true, std::move(password), std::move(promise));
}
void PasswordManager::do_get_secure_secret(bool recursive, string password, Promise<secure_storage::Secret> promise) {
void PasswordManager::do_get_secure_secret(bool allow_recursive, string password,
Promise<secure_storage::Secret> promise) {
if (secret_) {
return promise.set_value(secret_.value().clone());
}
@ -189,7 +190,7 @@ void PasswordManager::do_get_secure_secret(bool recursive, string password, Prom
return promise.set_error(Status::Error(400, "PASSWORD_HASH_INVALID"));
}
get_full_state(
password, PromiseCreator::lambda([password, recursive, promise = std::move(promise),
password, PromiseCreator::lambda([password, allow_recursive, promise = std::move(promise),
actor_id = actor_id(this)](Result<PasswordFullState> r_state) mutable {
if (r_state.is_error()) {
return promise.set_error(r_state.move_as_error());
@ -202,7 +203,7 @@ void PasswordManager::do_get_secure_secret(bool recursive, string password, Prom
send_closure(actor_id, &PasswordManager::cache_secret, state.private_state.secret.value().clone());
return promise.set_value(std::move(state.private_state.secret.value()));
}
if (!recursive) {
if (!allow_recursive) {
return promise.set_error(Status::Error(400, "Failed to get Telegram Passport secret"));
}
@ -379,6 +380,19 @@ void PasswordManager::get_recovery_email_address(string password,
}));
}
void PasswordManager::check_recovery_email_address_code(string code, Promise<Unit> promise) {
auto query =
G()->net_query_creator().create(create_storer(telegram_api::account_confirmPasswordEmail(std::move(code))));
send_with_promise(std::move(query),
PromiseCreator::lambda([promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::account_confirmPasswordEmail>(std::move(r_query));
if (r_result.is_error()) {
return promise.set_error(r_result.move_as_error());
}
return promise.set_value(Unit());
}));
}
void PasswordManager::send_email_address_verification_code(
string email, Promise<td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo>> promise) {
last_verified_email_address_ = email;
@ -457,8 +471,7 @@ void PasswordManager::update_password_settings(UpdateSettings update_settings, P
return promise.set_error(r_update_settings.move_as_error());
}
if (!r_update_settings.ok()) {
promise.set_error(Status::Error(5, "account_updatePasswordSettings returned false"));
return;
return promise.set_error(Status::Error(5, "account_updatePasswordSettings returned false"));
}
send_closure(actor_id, &PasswordManager::get_state, std::move(promise));
});
@ -557,11 +570,17 @@ void PasswordManager::do_update_password_settings_impl(UpdateSettings update_set
auto query = G()->net_query_creator().create(
create_storer(telegram_api::account_updatePasswordSettings(std::move(current_hash), std::move(new_settings))));
send_with_promise(std::move(query),
PromiseCreator::lambda([promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
send_with_promise(std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)](
Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::account_updatePasswordSettings>(std::move(r_query));
if (r_result.is_error()) {
if (r_result.error().code() == 400 && r_result.error().message() == "EMAIL_UNCONFIRMED") {
Slice prefix("EMAIL_UNCONFIRMED");
Slice message = r_result.error().message();
if (r_result.error().code() == 400 && begins_with(message, prefix)) {
if (message.size() >= prefix.size() + 2 && message[prefix.size()] == '_') {
send_closure(actor_id, &PasswordManager::on_get_code_length,
to_integer<int32>(message.substr(prefix.size() + 1)));
}
return promise.set_value(true);
}
return promise.set_error(r_result.move_as_error());
@ -570,6 +589,16 @@ void PasswordManager::do_update_password_settings_impl(UpdateSettings update_set
}));
}
void PasswordManager::on_get_code_length(int32 code_length) {
if (code_length <= 0 || code_length > 100) {
LOG(ERROR) << "Receive invalid code length " << code_length;
return;
}
LOG(INFO) << "Set code length to " << code_length;
last_code_length_ = code_length;
}
void PasswordManager::get_state(Promise<State> promise) {
do_get_state(PromiseCreator::lambda([promise = std::move(promise)](Result<PasswordState> r_state) mutable {
if (r_state.is_error()) {
@ -582,7 +611,7 @@ void PasswordManager::get_state(Promise<State> promise) {
void PasswordManager::do_get_state(Promise<PasswordState> promise) {
auto query = G()->net_query_creator().create(create_storer(telegram_api::account_getPassword()));
send_with_promise(
std::move(query), PromiseCreator::lambda([actor_id = actor_id(this),
std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), code_length = last_code_length_,
promise = std::move(promise)](Result<NetQueryPtr> r_query) mutable {
auto r_result = fetch_result<telegram_api::account_getPassword>(std::move(r_query));
if (r_result.is_error()) {
@ -623,6 +652,7 @@ void PasswordManager::do_get_state(Promise<PasswordState> promise) {
send_closure(actor_id, &PasswordManager::drop_cached_secret);
}
state.unconfirmed_recovery_email_address_pattern = std::move(password->email_unconfirmed_pattern_);
state.code_length = code_length;
CHECK(password->new_algo_ != nullptr);
switch (password->new_algo_->get_id()) {

View File

@ -66,6 +66,7 @@ class PasswordManager : public NetQueryCallback {
string recovery_email_address, Promise<State> promise);
void set_recovery_email_address(string password, string new_recovery_email_address, Promise<State> promise);
void get_recovery_email_address(string password, Promise<tl_object_ptr<td_api::recoveryEmailAddress>> promise);
void check_recovery_email_address_code(string code, Promise<Unit> promise);
void send_email_address_verification_code(
string email, Promise<td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo>> promise);
@ -96,6 +97,7 @@ class PasswordManager : public NetQueryCallback {
bool has_recovery_email_address = false;
bool has_secure_values = false;
string unconfirmed_recovery_email_address_pattern;
int32 code_length = 0;
string current_client_salt;
string current_server_salt;
@ -111,8 +113,13 @@ class PasswordManager : public NetQueryCallback {
string new_secure_salt;
State as_td_api() const {
td_api::object_ptr<td_api::emailAddressAuthenticationCodeInfo> code_info;
if (!unconfirmed_recovery_email_address_pattern.empty()) {
code_info = td_api::make_object<td_api::emailAddressAuthenticationCodeInfo>(
unconfirmed_recovery_email_address_pattern, code_length);
}
return td_api::make_object<td_api::passwordState>(has_password, password_hint, has_recovery_email_address,
has_secure_values, unconfirmed_recovery_email_address_pattern);
has_secure_values, std::move(code_info));
}
};
@ -147,6 +154,8 @@ class PasswordManager : public NetQueryCallback {
string last_verified_email_address_;
int32 last_code_length_ = 0;
static Result<secure_storage::Secret> decrypt_secure_secret(
Slice password, tl_object_ptr<telegram_api::SecurePasswordKdfAlgo> algo_ptr, Slice secret, int64 secret_id);
@ -162,9 +171,10 @@ class PasswordManager : public NetQueryCallback {
void do_update_password_settings(UpdateSettings update_settings, PasswordFullState full_state, Promise<bool> promise);
void do_update_password_settings_impl(UpdateSettings update_settings, PasswordState state,
PasswordPrivateState private_state, Promise<bool> promise);
void on_get_code_length(int32 code_length);
void do_get_state(Promise<PasswordState> promise);
void get_full_state(string password, Promise<PasswordFullState> promise);
void do_get_secure_secret(bool recursive, string passwod, Promise<secure_storage::Secret> promise);
void do_get_secure_secret(bool allow_recursive, string password, Promise<secure_storage::Secret> promise);
void do_get_full_state(string password, PasswordState state, Promise<PasswordFullState> promise);
void cache_secret(secure_storage::Secret secret);
void drop_cached_secret();

View File

@ -4650,6 +4650,14 @@ void Td::on_request(uint64 id, td_api::getRecoveryEmailAddress &request) {
std::move(promise));
}
void Td::on_request(uint64 id, td_api::checkRecoveryEmailAddressCode &request) {
CHECK_IS_USER();
CLEAN_INPUT_STRING(request.code_);
CREATE_OK_REQUEST_PROMISE();
send_closure(password_manager_, &PasswordManager::check_recovery_email_address_code, request.code_,
std::move(promise));
}
void Td::on_request(uint64 id, td_api::requestPasswordRecovery &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();

View File

@ -377,6 +377,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, td_api::setRecoveryEmailAddress &request);
void on_request(uint64 id, td_api::checkRecoveryEmailAddressCode &request);
void on_request(uint64 id, td_api::requestPasswordRecovery &request);
void on_request(uint64 id, td_api::recoverPassword &request);

View File

@ -1360,6 +1360,10 @@ class CliClient final : public Actor {
string recovery_email_address;
std::tie(password, recovery_email_address) = split(args);
send_request(make_tl_object<td_api::setRecoveryEmailAddress>(password, recovery_email_address));
} else if (op == "grea" || op == "GetRecoveryEmailAddress") {
send_request(make_tl_object<td_api::getRecoveryEmailAddress>(args));
} else if (op == "creac") {
send_request(make_tl_object<td_api::checkRecoveryEmailAddressCode>(args));
} else if (op == "spncc") {
send_request(make_tl_object<td_api::sendPhoneNumberVerificationCode>(args, false, false));
} else if (op == "cpncc") {
@ -1370,8 +1374,6 @@ class CliClient final : public Actor {
send_request(make_tl_object<td_api::requestPasswordRecovery>());
} else if (op == "rp" || op == "RecoverPassword") {
send_request(make_tl_object<td_api::recoverPassword>(args));
} else if (op == "grea" || op == "GetRecoveryEmailAddress") {
send_request(make_tl_object<td_api::getRecoveryEmailAddress>(args));
} else if (op == "gtp" || op == "GetTemporaryPassword") {
send_request(make_tl_object<td_api::getTemporaryPasswordState>());
} else if (op == "ctp" || op == "CreateTemporaryPassword") {