Allow 2sv password setup in passport.

This commit is contained in:
John Preston
2018-04-16 21:02:40 +04:00
parent 5b615519e8
commit 9f6130cd20
21 changed files with 359 additions and 104 deletions
@@ -26,6 +26,9 @@ passportPasswordLabelBold: FlatLabel(passportPasswordLabel) {
linkFontOver: font(boxFontSize semibold underline);
}
}
passportPasswordSetupLabel: FlatLabel(passportPasswordLabel) {
minWidth: 0px;
}
passportPasswordHintLabel: passportPasswordLabel;
passportErrorLabel: FlatLabel(passportPasswordLabel) {
textFg: boxTextFgError;
@@ -223,3 +226,8 @@ passportDetailsSkip: 30px;
passportDetailsGenderSkip: 30px;
passportRequestTypeSkip: 16px;
passportPasswordAbout1Padding: margins(10px, 28px, 10px, 0px);
passportPasswordAbout2Padding: margins(10px, 0px, 10px, 28px);
passportPasswordIconHeight: 224px;
passportPasswordIcon: icon {{ "passport_password_setup", windowSubTextFg }};
@@ -388,6 +388,34 @@ void FormController::submitPassword(const QString &password) {
}).send();
}
void FormController::reloadPassword() {
requestPassword();
}
void FormController::cancelPassword() {
if (_passwordRequestId) {
return;
}
_passwordRequestId = request(MTPaccount_UpdatePasswordSettings(
MTP_bytes(QByteArray()),
MTP_account_passwordInputSettings(
MTP_flags(MTPDaccount_passwordInputSettings::Flag::f_email),
MTP_bytes(QByteArray()), // new_salt
MTP_bytes(QByteArray()), // new_password_hash
MTP_string(QString()), // hint
MTP_string(QString()), // email
MTP_bytes(QByteArray()), // new_secure_salt
MTP_bytes(QByteArray()), // new_secure_secret
MTP_long(0)) // new_secure_secret_hash
)).done([=](const MTPBool &result) {
_passwordRequestId = 0;
reloadPassword();
}).fail([=](const RPCError &error) {
_passwordRequestId = 0;
reloadPassword();
}).send();
}
void FormController::validateSecureSecret(
bytes::const_span salt,
bytes::const_span encryptedSecret,
@@ -525,8 +553,8 @@ rpl::producer<QString> FormController::passwordError() const {
return _passwordError.events();
}
QString FormController::passwordHint() const {
return _password.hint;
const PasswordSettings &FormController::passwordSettings() const {
return _password;
}
void FormController::uploadScan(
@@ -1702,6 +1730,9 @@ void FormController::formFail(const QString &error) {
}
void FormController::requestPassword() {
if (_passwordRequestId) {
return;
}
_passwordRequestId = request(MTPaccount_GetPassword(
)).done([=](const MTPaccount_Password &result) {
_passwordRequestId = 0;
@@ -1733,14 +1764,13 @@ void FormController::showForm() {
}
if (!_password.salt.empty()) {
_view->showAskPassword();
} else if (!_password.unconfirmedPattern.isEmpty()) {
_view->showPasswordUnconfirmed();
} else {
_view->showNoPassword();
}
}
void FormController::parsePassword(const MTPDaccount_noPassword &result) {
_password = PasswordSettings();
_password.unconfirmedPattern = qs(result.vemail_unconfirmed_pattern);
_password.newSalt = bytes::make_vector(result.vnew_salt.v);
_password.newSecureSalt = bytes::make_vector(result.vnew_secure_salt.v);
@@ -1748,6 +1778,7 @@ void FormController::parsePassword(const MTPDaccount_noPassword &result) {
}
void FormController::parsePassword(const MTPDaccount_password &result) {
_password = PasswordSettings();
_password.hint = qs(result.vhint);
_password.hasRecovery = mtpIsTrue(result.vhas_recovery);
_password.salt = bytes::make_vector(result.vcurrent_salt.v);
@@ -217,7 +217,9 @@ public:
std::vector<not_null<const Value*>> submitGetErrors();
void submitPassword(const QString &password);
rpl::producer<QString> passwordError() const;
QString passwordHint() const;
const PasswordSettings &passwordSettings() const;
void reloadPassword();
void cancelPassword();
bool canAddScan(not_null<const Value*> value) const;
void uploadScan(not_null<const Value*> value, QByteArray &&content);
@@ -42,11 +42,13 @@ class ViewController {
public:
virtual void showAskPassword() = 0;
virtual void showNoPassword() = 0;
virtual void showPasswordUnconfirmed() = 0;
virtual void showCriticalError(const QString &error) = 0;
virtual void editScope(int index) = 0;
virtual void showBox(object_ptr<BoxContent> box) = 0;
virtual void showBox(
object_ptr<BoxContent> box,
LayerOptions options,
anim::type animated) = 0;
virtual void showToast(const QString &text) = 0;
virtual void suggestReset(base::lambda<void()> callback) = 0;
@@ -56,9 +58,12 @@ public:
}
template <typename BoxType>
QPointer<BoxType> show(object_ptr<BoxType> content) {
auto result = QPointer<BoxType>(content.data());
showBox(std::move(content));
QPointer<BoxType> show(
object_ptr<BoxType> box,
LayerOptions options = LayerOption::KeepOther,
anim::type animated = anim::type::normal) {
auto result = QPointer<BoxType>(box.data());
showBox(std::move(box), options, animated);
return result;
}
@@ -226,12 +226,6 @@ void Panel::showNoPassword() {
setBackAllowed(false);
}
void Panel::showPasswordUnconfirmed() {
showInner(
base::make_unique_q<PanelPasswordUnconfirmed>(_body, _controller));
setBackAllowed(false);
}
void Panel::showCriticalError(const QString &error) {
auto container = base::make_unique_q<Ui::PaddingWrap<Ui::FlatLabel>>(
_body,
@@ -258,12 +252,12 @@ void Panel::showEditValue(object_ptr<Ui::RpWidget> from) {
showInner(base::unique_qptr<Ui::RpWidget>(from.data()));
}
void Panel::showBox(object_ptr<BoxContent> box) {
void Panel::showBox(
object_ptr<BoxContent> box,
LayerOptions options,
anim::type animated) {
ensureLayerCreated();
_layer->showBox(
std::move(box),
LayerOption::KeepOther,
anim::type::normal);
_layer->showBox(std::move(box), options, animated);
}
void Panel::ensureLayerCreated() {
@@ -37,11 +37,13 @@ public:
void showAskPassword();
void showNoPassword();
void showPasswordUnconfirmed();
void showForm();
void showCriticalError(const QString &error);
void showEditValue(object_ptr<Ui::RpWidget> form);
void showBox(object_ptr<BoxContent> box);
void showBox(
object_ptr<BoxContent> box,
LayerOptions options,
anim::type animated);
rpl::producer<> backRequests() const;
void setBackAllowed(bool allowed);
@@ -13,6 +13,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "passport/passport_panel_edit_contact.h"
#include "passport/passport_panel_edit_scans.h"
#include "passport/passport_panel.h"
#include "base/openssl_help.h"
#include "boxes/passcode_box.h"
#include "boxes/confirm_box.h"
#include "ui/toast/toast.h"
#include "ui/countryinput.h"
@@ -403,7 +405,11 @@ rpl::producer<QString> PanelController::passwordError() const {
}
QString PanelController::passwordHint() const {
return _form->passwordHint();
return _form->passwordSettings().hint;
}
QString PanelController::unconfirmedEmailPattern() const {
return _form->passwordSettings().unconfirmedPattern;
}
QString PanelController::defaultEmail() const {
@@ -414,6 +420,40 @@ QString PanelController::defaultPhoneNumber() const {
return _form->defaultPhoneNumber();
}
void PanelController::setupPassword() {
Expects(_panel != nullptr);
const auto &settings = _form->passwordSettings();
Assert(settings.salt.empty());
constexpr auto kRandomPart = 8;
auto newSalt = QByteArray(
reinterpret_cast<const char*>(settings.newSalt.data()),
settings.newSalt.size());
newSalt.resize(newSalt.size() + kRandomPart);
bytes::set_random(
bytes::make_span(newSalt).subspan(settings.newSalt.size()));
const auto currentSalt = QByteArray();
const auto hasRecovery = false;
const auto hint = QString();
auto box = show(Box<PasscodeBox>(
newSalt,
currentSalt,
hasRecovery,
hint));
box->connect(box, &PasscodeBox::reloadPassword, _panel.get(), [=] {
_form->reloadPassword();
});
}
void PanelController::cancelPasswordSubmit() {
const auto box = std::make_shared<QPointer<BoxContent>>();
*box = show(Box<ConfirmBox>(
lang(lng_passport_stop_password_sure),
lang(lng_passport_stop),
[=] { if (*box) (*box)->closeBox(); _form->cancelPassword(); }));
}
bool PanelController::canAddScan() const {
Expects(_editScope != nullptr);
Expects(_editDocument != nullptr);
@@ -683,11 +723,6 @@ void PanelController::showNoPassword() {
_panel->showNoPassword();
}
void PanelController::showPasswordUnconfirmed() {
ensurePanelCreated();
_panel->showPasswordUnconfirmed();
}
void PanelController::showCriticalError(const QString &error) {
ensurePanelCreated();
_panel->showCriticalError(error);
@@ -1060,8 +1095,11 @@ void PanelController::cancelAuth() {
_form->cancel();
}
void PanelController::showBox(object_ptr<BoxContent> box) {
_panel->showBox(std::move(box));
void PanelController::showBox(
object_ptr<BoxContent> box,
LayerOptions options,
anim::type animated) {
_panel->showBox(std::move(box), options, animated);
}
void PanelController::showToast(const QString &text) {
@@ -69,6 +69,10 @@ public:
void submitPassword(const QString &password);
rpl::producer<QString> passwordError() const;
QString passwordHint() const;
QString unconfirmedEmailPattern() const;
void setupPassword();
void cancelPasswordSubmit();
bool canAddScan() const;
void uploadScan(QByteArray &&content);
@@ -88,7 +92,6 @@ public:
void showAskPassword() override;
void showNoPassword() override;
void showPasswordUnconfirmed() override;
void showCriticalError(const QString &error) override;
void fillRows(
@@ -106,7 +109,10 @@ public:
const ValueMap &filesData) const;
void cancelEditScope();
void showBox(object_ptr<BoxContent> box) override;
void showBox(
object_ptr<BoxContent> box,
LayerOptions options,
anim::type animated) override;
void showToast(const QString &text) override;
void suggestReset(base::lambda<void()> callback) override;
@@ -220,25 +220,25 @@ not_null<Ui::RpWidget*> PanelForm::setupContent() {
_userpic->move((width - _userpic->width()) / 2, _userpic->y());
}, _userpic->lifetime());
auto about1 = object_ptr<Ui::FlatLabel>(
inner,
lng_passport_request1(lt_bot, App::peerName(bot)),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabelBold);
_about1 = about1.data();
inner->add(
object_ptr<Ui::IgnoreNaturalWidth>(inner, std::move(about1)),
st::passportFormAbout1Padding);
_about1 = inner->add(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
inner,
object_ptr<Ui::FlatLabel>(
inner,
lng_passport_request1(lt_bot, App::peerName(bot)),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabelBold)),
st::passportFormAbout1Padding)->entity();
auto about2 = object_ptr<Ui::FlatLabel>(
inner,
lang(lng_passport_request2),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabel);
_about2 = about2.data();
inner->add(
object_ptr<Ui::IgnoreNaturalWidth>(inner, std::move(about2)),
st::passportFormAbout2Padding);
_about2 = inner->add(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
inner,
object_ptr<Ui::FlatLabel>(
inner,
lang(lng_passport_request2),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabel)),
st::passportFormAbout2Padding)->entity();
inner->add(object_ptr<BoxContentDivider>(
inner,
@@ -11,8 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/special_buttons.h"
#include "lang/lang_keys.h"
#include "info/profile/info_profile_icon.h"
#include "styles/style_passport.h"
#include "styles/style_boxes.h"
@@ -148,14 +151,96 @@ PanelNoPassword::PanelNoPassword(
QWidget *parent,
not_null<PanelController*> controller)
: RpWidget(parent)
, _controller(controller) {
, _controller(controller)
, _inner(Ui::CreateChild<Ui::VerticalLayout>(this)) {
setupContent();
}
PanelPasswordUnconfirmed::PanelPasswordUnconfirmed(
QWidget *parent,
not_null<PanelController*> controller)
: RpWidget(parent)
, _controller(controller) {
void PanelNoPassword::setupContent() {
widthValue(
) | rpl::start_with_next([=](int newWidth) {
_inner->resizeToWidth(newWidth);
}, _inner->lifetime());
const auto about1 = _inner->add(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
_inner,
object_ptr<Ui::FlatLabel>(
_inner,
lng_passport_request1(
lt_bot,
App::peerName(_controller->bot())),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabelBold)),
st::passportPasswordAbout1Padding)->entity();
const auto about2 = _inner->add(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
_inner,
object_ptr<Ui::FlatLabel>(
_inner,
lang(lng_passport_request2),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabel)),
st::passportPasswordAbout2Padding)->entity();
const auto iconWrap = _inner->add(
object_ptr<Ui::CenterWrap<Ui::FixedHeightWidget>>(
_inner,
object_ptr<Ui::FixedHeightWidget>(
_inner,
st::passportPasswordIconHeight)));
iconWrap->entity()->resizeToWidth(st::passportPasswordIcon.width());
Ui::CreateChild<Info::Profile::FloatingIcon>(
iconWrap->entity(),
st::passportPasswordIcon,
QPoint(0, 0));
const auto about3 = _inner->add(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
_inner,
object_ptr<Ui::FlatLabel>(
_inner,
lang(lng_passport_create_password),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordSetupLabel)),
st::passportFormAbout2Padding)->entity();
refreshBottom();
}
void PanelNoPassword::refreshBottom() {
const auto pattern = _controller->unconfirmedEmailPattern();
_about.reset(_inner->add(
object_ptr<Ui::CenterWrap<Ui::FlatLabel>>(
_inner,
object_ptr<Ui::FlatLabel>(
_inner,
(pattern.isEmpty()
? lang(lng_passport_about_password)
: lng_passport_link_sent(lt_email, pattern)),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordSetupLabel)),
st::passportFormAbout2Padding)->entity());
const auto button = _inner->add(
object_ptr<Ui::CenterWrap<Ui::RoundButton>>(
_inner,
object_ptr<Ui::RoundButton>(
_inner,
langFactory(pattern.isEmpty()
? lng_passport_password_create
: lng_cancel),
st::defaultBoxButton)));
if (pattern.isEmpty()) {
button->entity()->addClickHandler([=] {
_controller->setupPassword();
});
} else {
button->entity()->addClickHandler([=] {
_controller->cancelPasswordSubmit();
});
}
_button.reset(button);
}
} // namespace Passport
@@ -15,6 +15,7 @@ class FlatLabel;
class LinkButton;
class RoundButton;
class UserpicButton;
class VerticalLayout;
} // namespace Ui
namespace Passport {
@@ -58,18 +59,14 @@ public:
not_null<PanelController*> controller);
private:
void setupContent();
void refreshBottom();
not_null<PanelController*> _controller;
};
class PanelPasswordUnconfirmed : public Ui::RpWidget {
public:
PanelPasswordUnconfirmed(
QWidget *parent,
not_null<PanelController*> controller);
private:
not_null<PanelController*> _controller;
not_null<Ui::VerticalLayout*> _inner;
base::unique_qptr<Ui::RpWidget> _about;
base::unique_qptr<Ui::RpWidget> _button;
};