mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Added ability to reset cloud password without recovery email.
This commit is contained in:
parent
fedd8bece3
commit
bcbf009a62
6 changed files with 282 additions and 25 deletions
|
@ -564,6 +564,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_settings_cloud_password_skip_hint" = "Skip hint";
|
||||
"lng_settings_cloud_password_save" = "Save and Finish";
|
||||
"lng_settings_cloud_password_email_confirm" = "Confirm and Finish";
|
||||
"lng_settings_cloud_password_reset_in" = "You can reset your password in {duration}.";
|
||||
|
||||
"lng_clear_payment_info_title" = "Clear payment info";
|
||||
"lng_clear_payment_info_sure" = "Are you sure you want to clear your payment and shipping info?";
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "settings/cloud_password/settings_cloud_password_email_confirm.h"
|
||||
|
||||
#include "api/api_cloud_password.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/core_cloud_password.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "settings/cloud_password/settings_cloud_password_common.h"
|
||||
|
@ -17,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "settings/cloud_password/settings_cloud_password_manage.h"
|
||||
#include "settings/cloud_password/settings_cloud_password_start.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/sent_code_field.h"
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
|
@ -155,7 +157,65 @@ void EmailConfirm::setupContent() {
|
|||
newInput->hideError();
|
||||
});
|
||||
});
|
||||
resend->setVisible(recoverEmailPattern.isEmpty());
|
||||
|
||||
if (!recoverEmailPattern.isEmpty()) {
|
||||
resend->setText(tr::lng_signin_try_password(tr::now));
|
||||
|
||||
resend->setClickedCallback([=] {
|
||||
const auto reset = [=](Fn<void()> close) {
|
||||
if (_requestLifetime) {
|
||||
return;
|
||||
}
|
||||
_requestLifetime = cloudPassword().resetPassword(
|
||||
) | rpl::start_with_next_error_done([=](
|
||||
Api::CloudPassword::ResetRetryDate retryDate) {
|
||||
_requestLifetime.destroy();
|
||||
const auto left = std::max(
|
||||
retryDate - base::unixtime::now(),
|
||||
60);
|
||||
controller()->show(Ui::MakeInformBox(
|
||||
tr::lng_cloud_password_reset_later(
|
||||
tr::now,
|
||||
lt_duration,
|
||||
Ui::FormatResetCloudPasswordIn(left))));
|
||||
}, [=](const QString &type) {
|
||||
_requestLifetime.destroy();
|
||||
}, [=] {
|
||||
_requestLifetime.destroy();
|
||||
|
||||
cloudPassword().reload();
|
||||
using PasswordState = Core::CloudPasswordState;
|
||||
_requestLifetime = cloudPassword().state(
|
||||
) | rpl::filter([=](const PasswordState &s) {
|
||||
return s.pendingResetDate != 0;
|
||||
}) | rpl::take(
|
||||
1
|
||||
) | rpl::start_with_next([=](const PasswordState &s) {
|
||||
const auto left = (s.pendingResetDate
|
||||
- base::unixtime::now());
|
||||
if (left > 0) {
|
||||
_requestLifetime.destroy();
|
||||
controller()->show(Ui::MakeInformBox(
|
||||
tr::lng_settings_cloud_password_reset_in(
|
||||
tr::now,
|
||||
lt_duration,
|
||||
Ui::FormatResetCloudPasswordIn(left))));
|
||||
setStepData(StepData());
|
||||
showBack();
|
||||
}
|
||||
});
|
||||
});
|
||||
_requestLifetime.add(close);
|
||||
};
|
||||
|
||||
controller()->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_cloud_password_reset_with_email(),
|
||||
.confirmed = reset,
|
||||
.confirmText = tr::lng_cloud_password_reset_ok(),
|
||||
.confirmStyle = &st::attentionBoxButton,
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
const auto button = AddDoneButton(
|
||||
content,
|
||||
|
|
|
@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "api/api_cloud_password.h"
|
||||
#include "base/qt_signal_producer.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/core_cloud_password.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "lottie/lottie_icon.h"
|
||||
|
@ -17,12 +19,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "settings/cloud_password/settings_cloud_password_hint.h"
|
||||
#include "settings/cloud_password/settings_cloud_password_manage.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_settings.h"
|
||||
|
||||
namespace Settings {
|
||||
|
@ -93,6 +97,12 @@ public:
|
|||
[[nodiscard]] rpl::producer<std::vector<Type>> removeFromStack() override;
|
||||
|
||||
private:
|
||||
void setupRecoverButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Ui::LinkButton*> button,
|
||||
not_null<Ui::FlatLabel*> info,
|
||||
Fn<void()> recoverCallback);
|
||||
|
||||
rpl::variable<std::vector<Type>> _removesFromStack;
|
||||
rpl::lifetime _requestLifetime;
|
||||
|
||||
|
@ -192,32 +202,72 @@ void Input::setupContent() {
|
|||
}
|
||||
}, hintInfo->lifetime());
|
||||
|
||||
const auto recover = AddLinkButton(content, newInput);
|
||||
recover->setText(tr::lng_signin_recover(tr::now));
|
||||
recover->setClickedCallback([=] {
|
||||
auto recoverCallback = [=] {
|
||||
if (_requestLifetime) {
|
||||
return;
|
||||
}
|
||||
_requestLifetime = cloudPassword().requestPasswordRecovery(
|
||||
) | rpl::start_with_next_error([=](const QString &pattern) {
|
||||
_requestLifetime.destroy();
|
||||
const auto state = cloudPassword().stateCurrent();
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
if (state->hasRecovery) {
|
||||
_requestLifetime = cloudPassword().requestPasswordRecovery(
|
||||
) | rpl::start_with_next_error([=](const QString &pattern) {
|
||||
_requestLifetime.destroy();
|
||||
|
||||
auto data = stepData();
|
||||
data.processRecover = currentStepProcessRecover;
|
||||
data.processRecover.emailPattern = pattern;
|
||||
setStepData(std::move(data));
|
||||
showOther(CloudPasswordEmailConfirmId());
|
||||
}, [=](const QString &type) {
|
||||
_requestLifetime.destroy();
|
||||
auto data = stepData();
|
||||
data.processRecover = currentStepProcessRecover;
|
||||
data.processRecover.emailPattern = pattern;
|
||||
setStepData(std::move(data));
|
||||
showOther(CloudPasswordEmailConfirmId());
|
||||
}, [=](const QString &type) {
|
||||
_requestLifetime.destroy();
|
||||
|
||||
error->show();
|
||||
if (MTP::IsFloodError(type)) {
|
||||
error->setText(tr::lng_flood_error(tr::now));
|
||||
} else {
|
||||
error->setText(Lang::Hard::ServerError());
|
||||
}
|
||||
});
|
||||
});
|
||||
error->show();
|
||||
if (MTP::IsFloodError(type)) {
|
||||
error->setText(tr::lng_flood_error(tr::now));
|
||||
} else {
|
||||
error->setText(Lang::Hard::ServerError());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const auto callback = [=](Fn<void()> close) {
|
||||
if (_requestLifetime) {
|
||||
return;
|
||||
}
|
||||
close();
|
||||
_requestLifetime = cloudPassword().resetPassword(
|
||||
) | rpl::start_with_error_done([=](const QString &type) {
|
||||
_requestLifetime.destroy();
|
||||
}, [=] {
|
||||
_requestLifetime.destroy();
|
||||
});
|
||||
};
|
||||
controller()->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_cloud_password_reset_no_email(),
|
||||
.confirmed = callback,
|
||||
.confirmText = tr::lng_cloud_password_reset_ok(),
|
||||
.cancelText = tr::lng_cancel(),
|
||||
.confirmStyle = &st::attentionBoxButton,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
const auto recover = AddLinkButton(content, newInput);
|
||||
const auto resetInfo = Ui::CreateChild<Ui::FlatLabel>(
|
||||
content,
|
||||
QString(),
|
||||
st::boxDividerLabel);
|
||||
recover->geometryValue(
|
||||
) | rpl::start_with_next([=](const QRect &r) {
|
||||
resetInfo->moveToLeft(r.x(), r.y() + st::passcodeTextLine);
|
||||
}, resetInfo->lifetime());
|
||||
|
||||
setupRecoverButton(
|
||||
content,
|
||||
recover,
|
||||
resetInfo,
|
||||
std::move(recoverCallback));
|
||||
} else if (currentStepProcessRecover.setNewPassword && reenterInput) {
|
||||
const auto skip = AddLinkButton(content, reenterInput);
|
||||
skip->setText(tr::lng_settings_auto_night_disable(tr::now));
|
||||
|
@ -278,6 +328,14 @@ void Input::setupContent() {
|
|||
}, [=] {
|
||||
_requestLifetime.destroy();
|
||||
|
||||
if (const auto state = cloudPassword().stateCurrent()) {
|
||||
if (state->pendingResetDate > 0) {
|
||||
auto lifetime = rpl::lifetime();
|
||||
lifetime = cloudPassword().cancelResetPassword(
|
||||
) | rpl::start_with_next([] {});
|
||||
}
|
||||
}
|
||||
|
||||
auto data = stepData();
|
||||
data.currentPassword = pass;
|
||||
setStepData(std::move(data));
|
||||
|
@ -352,6 +410,142 @@ void Input::setupContent() {
|
|||
Ui::ResizeFitChild(this, content);
|
||||
}
|
||||
|
||||
void Input::setupRecoverButton(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Ui::LinkButton*> button,
|
||||
not_null<Ui::FlatLabel*> info,
|
||||
Fn<void()> recoverCallback) {
|
||||
|
||||
struct Status {
|
||||
enum class SuggestAction {
|
||||
Recover,
|
||||
Reset,
|
||||
CancelReset,
|
||||
};
|
||||
SuggestAction suggest = SuggestAction::Recover;
|
||||
TimeId left = 0;
|
||||
};
|
||||
|
||||
struct State {
|
||||
base::Timer timer;
|
||||
rpl::variable<Status> status;
|
||||
};
|
||||
|
||||
const auto state = container->lifetime().make_state<State>();
|
||||
|
||||
const auto updateStatus = [=] {
|
||||
const auto passwordState = cloudPassword().stateCurrent();
|
||||
const auto date = passwordState ? passwordState->pendingResetDate : 0;
|
||||
const auto left = (date - base::unixtime::now());
|
||||
state->status = Status{
|
||||
.suggest = ((left > 0)
|
||||
? Status::SuggestAction::CancelReset
|
||||
: date
|
||||
? Status::SuggestAction::Reset
|
||||
: Status::SuggestAction::Recover),
|
||||
.left = left,
|
||||
};
|
||||
};
|
||||
state->timer.setCallback(updateStatus);
|
||||
updateStatus();
|
||||
|
||||
state->status.value(
|
||||
) | rpl::start_with_next([=](const Status &status) {
|
||||
switch (status.suggest) {
|
||||
case Status::SuggestAction::Recover: {
|
||||
info->setText(QString());
|
||||
button->setText(tr::lng_signin_recover(tr::now));
|
||||
} break;
|
||||
case Status::SuggestAction::Reset: {
|
||||
info->setText(QString());
|
||||
button->setText(tr::lng_cloud_password_reset_ready(tr::now));
|
||||
} break;
|
||||
case Status::SuggestAction::CancelReset: {
|
||||
info->setText(
|
||||
tr::lng_settings_cloud_password_reset_in(
|
||||
tr::now,
|
||||
lt_duration,
|
||||
Ui::FormatResetCloudPasswordIn(status.left)));
|
||||
button->setText(
|
||||
tr::lng_cloud_password_reset_cancel_title(tr::now));
|
||||
} break;
|
||||
}
|
||||
}, container->lifetime());
|
||||
|
||||
cloudPassword().state(
|
||||
) | rpl::start_with_next([=](const Core::CloudPasswordState &passState) {
|
||||
updateStatus();
|
||||
state->timer.cancel();
|
||||
if (passState.pendingResetDate) {
|
||||
state->timer.callEach(999);
|
||||
}
|
||||
}, container->lifetime());
|
||||
|
||||
button->setClickedCallback([=] {
|
||||
const auto passState = cloudPassword().stateCurrent();
|
||||
if (_requestLifetime || !passState) {
|
||||
return;
|
||||
}
|
||||
updateStatus();
|
||||
const auto suggest = state->status.current().suggest;
|
||||
if (suggest == Status::SuggestAction::Recover) {
|
||||
recoverCallback();
|
||||
} else if (suggest == Status::SuggestAction::CancelReset) {
|
||||
const auto cancel = [=](Fn<void()> close) {
|
||||
if (_requestLifetime) {
|
||||
return;
|
||||
}
|
||||
close();
|
||||
_requestLifetime = cloudPassword().cancelResetPassword(
|
||||
) | rpl::start_with_error_done([=](const QString &error) {
|
||||
_requestLifetime.destroy();
|
||||
}, [=] {
|
||||
_requestLifetime.destroy();
|
||||
});
|
||||
};
|
||||
controller()->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_cloud_password_reset_cancel_sure(),
|
||||
.confirmed = cancel,
|
||||
.confirmText = tr::lng_box_yes(),
|
||||
.cancelText = tr::lng_box_no(),
|
||||
}));
|
||||
} else if (suggest == Status::SuggestAction::Reset) {
|
||||
_requestLifetime = cloudPassword().resetPassword(
|
||||
) | rpl::start_with_next_error_done([=](
|
||||
Api::CloudPassword::ResetRetryDate retryDate) {
|
||||
_requestLifetime.destroy();
|
||||
const auto left = std::max(
|
||||
retryDate - base::unixtime::now(),
|
||||
60);
|
||||
controller()->show(Ui::MakeInformBox(
|
||||
tr::lng_cloud_password_reset_later(
|
||||
tr::now,
|
||||
lt_duration,
|
||||
Ui::FormatResetCloudPasswordIn(left))));
|
||||
}, [=](const QString &type) {
|
||||
_requestLifetime.destroy();
|
||||
}, [=] {
|
||||
_requestLifetime.destroy();
|
||||
|
||||
cloudPassword().reload();
|
||||
using PasswordState = Core::CloudPasswordState;
|
||||
_requestLifetime = cloudPassword().state(
|
||||
) | rpl::filter([=](const PasswordState &s) {
|
||||
return !s.hasPassword;
|
||||
}) | rpl::take(
|
||||
1
|
||||
) | rpl::start_with_next([=](const PasswordState &s) {
|
||||
_requestLifetime.destroy();
|
||||
controller()->show(Ui::MakeInformBox(
|
||||
tr::lng_cloud_password_removed()));
|
||||
setStepData(StepData());
|
||||
showBack();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace CloudPassword
|
||||
|
||||
Type CloudPasswordInputId() {
|
||||
|
|
|
@ -21,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "settings/settings_local_passcode.h"
|
||||
#include "settings/settings_privacy_controllers.h"
|
||||
#include "base/timer_rpl.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "boxes/edit_privacy_box.h"
|
||||
#include "boxes/passcode_box.h"
|
||||
#include "boxes/auto_lock_box.h"
|
||||
|
@ -457,7 +456,6 @@ void SetupCloudPassword(
|
|||
rpl::duplicate(noconfirmed),
|
||||
_1 && !_2));
|
||||
disable->entity()->addClickHandler(remove);
|
||||
#endif
|
||||
|
||||
auto resetAt = session->api().cloudPassword().state(
|
||||
) | rpl::map([](const State &state) {
|
||||
|
@ -574,7 +572,6 @@ void SetupCloudPassword(
|
|||
}
|
||||
});
|
||||
|
||||
#if 0
|
||||
const auto abort = container->add(
|
||||
object_ptr<Ui::SlideWrap<Button>>(
|
||||
container,
|
||||
|
|
|
@ -436,4 +436,8 @@ QString FormatMuteForTiny(float64 sec) {
|
|||
: QString();
|
||||
}
|
||||
|
||||
QString FormatResetCloudPasswordIn(float64 sec) {
|
||||
return (sec >= 3600) ? FormatTTL(sec) : FormatDurationText(sec);
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -31,6 +31,7 @@ inline constexpr auto FileStatusSizeFailed = 0x7FFFFFF2;
|
|||
[[nodiscard]] QString FormatTTLTiny(float64 ttl);
|
||||
[[nodiscard]] QString FormatMuteFor(float64 sec);
|
||||
[[nodiscard]] QString FormatMuteForTiny(float64 sec);
|
||||
[[nodiscard]] QString FormatResetCloudPasswordIn(float64 sec);
|
||||
|
||||
struct CurrencyRule {
|
||||
const char *international = "";
|
||||
|
|
Loading…
Add table
Reference in a new issue