From 9f6130cd20118f571adf360239382ba8fc107814 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Mon, 16 Apr 2018 21:02:40 +0400
Subject: [PATCH] Allow 2sv password setup in passport.

---
 .../icons/passport_password_setup.png         | Bin 0 -> 6041 bytes
 .../icons/passport_password_setup@2x.png      | Bin 0 -> 11801 bytes
 Telegram/Resources/langs/lang.strings         |   5 +
 Telegram/SourceFiles/boxes/abstract_box.cpp   |  12 ++-
 Telegram/SourceFiles/boxes/abstract_box.h     |  33 +++++-
 Telegram/SourceFiles/boxes/passcode_box.cpp   |  22 ++--
 Telegram/SourceFiles/passport/passport.style  |   8 ++
 .../passport/passport_form_controller.cpp     |  39 ++++++-
 .../passport/passport_form_controller.h       |   4 +-
 .../passport/passport_form_view_controller.h  |  15 ++-
 .../SourceFiles/passport/passport_panel.cpp   |  16 +--
 .../SourceFiles/passport/passport_panel.h     |   6 +-
 .../passport/passport_panel_controller.cpp    |  54 ++++++++--
 .../passport/passport_panel_controller.h      |  10 +-
 .../passport/passport_panel_form.cpp          |  36 +++----
 .../passport/passport_panel_password.cpp      |  97 ++++++++++++++++--
 .../passport/passport_panel_password.h        |  17 ++-
 Telegram/SourceFiles/ui/wrap/padding_wrap.cpp |  31 ++++++
 Telegram/SourceFiles/ui/wrap/padding_wrap.h   |  36 +++++++
 Telegram/SourceFiles/ui/wrap/wrap.h           |  20 ----
 Telegram/SourceFiles/window/layer_widget.cpp  |   2 +-
 21 files changed, 359 insertions(+), 104 deletions(-)
 create mode 100644 Telegram/Resources/icons/passport_password_setup.png
 create mode 100644 Telegram/Resources/icons/passport_password_setup@2x.png

diff --git a/Telegram/Resources/icons/passport_password_setup.png b/Telegram/Resources/icons/passport_password_setup.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa56c75125fb5718ec00a0f12ad0be20c5329a7a
GIT binary patch
literal 6041
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
Oh_Zq@wBm_n`2PXD^19^!

literal 0
HcmV?d00001

diff --git a/Telegram/Resources/icons/passport_password_setup@2x.png b/Telegram/Resources/icons/passport_password_setup@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..77fa1391d347c20220eca69987a02b00cc33f36e
GIT binary patch
literal 11801
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

literal 0
HcmV?d00001

diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 90be90624..fe64ace2e 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -1516,6 +1516,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_passport_title" = "Telegram passport";
 "lng_passport_request1" = "{bot} requests access to your personal data";
 "lng_passport_request2" = "to sign you up for their services";
+"lng_passport_create_password" = "Please create a password which will be used\nto encrypt your personal data.";
+"lng_passport_about_password" = "This password will also be required whenever\nyou log in to a new device.";
+"lng_passport_password_create" = "Create a password";
+"lng_passport_link_sent" = "Confirmation link was sent to your email\n{email}";
+"lng_passport_stop_password_sure" = "Are you sure you want to stop your password setup?";
 "lng_passport_password_placeholder" = "Your password";
 "lng_passport_next" = "Next";
 "lng_passport_password_wrong" = "The password you entered is not valid.";
diff --git a/Telegram/SourceFiles/boxes/abstract_box.cpp b/Telegram/SourceFiles/boxes/abstract_box.cpp
index a475ffeae..9b1687580 100644
--- a/Telegram/SourceFiles/boxes/abstract_box.cpp
+++ b/Telegram/SourceFiles/boxes/abstract_box.cpp
@@ -227,8 +227,9 @@ void BoxContent::paintEvent(QPaintEvent *e) {
 	}
 }
 
-AbstractBox::AbstractBox(QWidget *parent, object_ptr<BoxContent> content)
-: LayerWidget(parent)
+AbstractBox::AbstractBox(not_null<Window::LayerStackWidget*> layer, object_ptr<BoxContent> content)
+: LayerWidget(layer)
+, _layer(layer)
 , _content(std::move(content)) {
 	subscribe(Lang::Current().updated(), [this] { refreshLang(); });
 	_content->setParent(this);
@@ -330,6 +331,13 @@ bool AbstractBox::hasTitle() const {
 	return (_title != nullptr) || !_additionalTitle.isEmpty();
 }
 
+void AbstractBox::showBox(
+		object_ptr<BoxContent> box,
+		LayerOptions options,
+		anim::type animated) {
+	_layer->showBox(std::move(box), options, animated);
+}
+
 void AbstractBox::updateSize() {
 	setDimensions(width(), _maxContentHeight);
 }
diff --git a/Telegram/SourceFiles/boxes/abstract_box.h b/Telegram/SourceFiles/boxes/abstract_box.h
index 8983812f1..84f4f6ea2 100644
--- a/Telegram/SourceFiles/boxes/abstract_box.h
+++ b/Telegram/SourceFiles/boxes/abstract_box.h
@@ -23,6 +23,8 @@ class FlatLabel;
 class FadeShadow;
 } // namespace Ui
 
+class BoxContent;
+
 class BoxContentDelegate {
 public:
 	virtual void setLayerType(bool layerType) = 0;
@@ -34,11 +36,25 @@ public:
 	virtual QPointer<Ui::RoundButton> addLeftButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) = 0;
 	virtual void updateButtonsPositions() = 0;
 
+	virtual void showBox(
+		object_ptr<BoxContent> box,
+		LayerOptions options,
+		anim::type animated) = 0;
 	virtual void setDimensions(int newWidth, int maxHeight) = 0;
 	virtual void setNoContentMargin(bool noContentMargin) = 0;
 	virtual bool isBoxShown() const = 0;
 	virtual void closeBox() = 0;
 
+	template <typename BoxType>
+	QPointer<BoxType> show(
+			object_ptr<BoxType> content,
+			LayerOptions options = LayerOption::KeepOther,
+			anim::type animated = anim::type::normal) {
+		auto result = QPointer<BoxType>(content.data());
+		showBox(std::move(content), options, animated);
+		return result;
+	}
+
 };
 
 class BoxContent : public Ui::RpWidget, protected base::Subscriber {
@@ -163,6 +179,10 @@ protected:
 	void resizeEvent(QResizeEvent *e) override;
 	void paintEvent(QPaintEvent *e) override;
 
+	not_null<BoxContentDelegate*> getDelegate() const {
+		return _delegate;
+	}
+
 private slots:
 	void onScroll();
 	void onInnerResize();
@@ -179,10 +199,6 @@ private:
 	void updateShadowsVisibility();
 	object_ptr<TWidget> doTakeInnerWidget();
 
-	BoxContentDelegate *getDelegate() const {
-		Expects(_delegate != nullptr);
-		return _delegate;
-	}
 	BoxContentDelegate *_delegate = nullptr;
 
 	bool _preparing = false;
@@ -205,13 +221,19 @@ class AbstractBox
 	, public BoxContentDelegate
 	, protected base::Subscriber {
 public:
-	AbstractBox(QWidget *parent, object_ptr<BoxContent> content);
+	AbstractBox(
+		not_null<Window::LayerStackWidget*> layer,
+		object_ptr<BoxContent> content);
 
 	void parentResized() override;
 
 	void setLayerType(bool layerType) override;
 	void setTitle(base::lambda<TextWithEntities()> titleFactory) override;
 	void setAdditionalTitle(base::lambda<QString()> additionalFactory) override;
+	void showBox(
+		object_ptr<BoxContent> box,
+		LayerOptions options,
+		anim::type animated) override;
 
 	void clearButtons() override;
 	QPointer<Ui::RoundButton> addButton(base::lambda<QString()> textFactory, base::lambda<void()> clickCallback, const style::RoundButton &st) override;
@@ -262,6 +284,7 @@ private:
 	int countRealHeight() const;
 	void updateSize();
 
+	not_null<Window::LayerStackWidget*> _layer;
 	int _fullHeight = 0;
 
 	bool _noContentMargin = false;
diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp
index 2926864a3..6eb117381 100644
--- a/Telegram/SourceFiles/boxes/passcode_box.cpp
+++ b/Telegram/SourceFiles/boxes/passcode_box.cpp
@@ -190,7 +190,7 @@ void PasscodeBox::setPasswordDone(const MTPBool &result) {
 	_setRequest = 0;
 	emit reloadPassword();
 	auto text = lang(_reenterPasscode->isHidden() ? lng_cloud_password_removed : (_oldPasscode->isHidden() ? lng_cloud_password_was_set : lng_cloud_password_updated));
-	Ui::show(Box<InformBox>(text));
+	getDelegate()->show(Box<InformBox>(text), LayerOption::CloseOther);
 }
 
 void PasscodeBox::closeReplacedBy() {
@@ -244,7 +244,9 @@ bool PasscodeBox::setPasswordFail(const RPCError &error) {
 		_recoverEmail->showError();
 		update();
 	} else if (err == qstr("EMAIL_UNCONFIRMED")) {
-		Ui::show(Box<InformBox>(lang(lng_cloud_password_almost)));
+		getDelegate()->show(
+			Box<InformBox>(lang(lng_cloud_password_almost)),
+			LayerOption::CloseOther);
 		emit reloadPassword();
 	}
 	return true;
@@ -307,9 +309,9 @@ void PasscodeBox::save(bool force) {
 		}
 		if (!_recoverEmail->isHidden() && email.isEmpty() && !force) {
 			_skipEmailWarning = true;
-			_replacedBy = Ui::show(Box<ConfirmBox>(lang(lng_cloud_password_about_recover), lang(lng_cloud_password_skip_email), st::attentionBoxButton, base::lambda_guarded(this, [this] {
+			_replacedBy = getDelegate()->show(Box<ConfirmBox>(lang(lng_cloud_password_about_recover), lang(lng_cloud_password_skip_email), st::attentionBoxButton, base::lambda_guarded(this, [this] {
 				save(true);
-			})), LayerOption::KeepOther);
+			})));
 		} else {
 			QByteArray newPasswordData = pwd.isEmpty() ? QByteArray() : (_newSalt + pwd.toUtf8() + _newSalt);
 			QByteArray newPasswordHash = pwd.isEmpty() ? QByteArray() : QByteArray(32, Qt::Uninitialized);
@@ -407,9 +409,7 @@ void PasscodeBox::recoverExpired() {
 void PasscodeBox::recover() {
 	if (_pattern == "-") return;
 
-	const auto box = Ui::show(
-		Box<RecoverBox>(_pattern),
-		LayerOption::KeepOther);
+	const auto box = getDelegate()->show(Box<RecoverBox>(_pattern));
 	connect(box, &RecoverBox::reloadPassword, this, &PasscodeBox::reloadPassword);
 	connect(box, &RecoverBox::recoveryExpired, this, &PasscodeBox::recoverExpired);
 	_replacedBy = box;
@@ -494,7 +494,9 @@ void RecoverBox::codeSubmitDone(bool recover, const MTPauth_Authorization &resul
 	_submitRequest = 0;
 
 	emit reloadPassword();
-	Ui::show(Box<InformBox>(lang(lng_cloud_password_removed)));
+	getDelegate()->show(
+		Box<InformBox>(lang(lng_cloud_password_removed)),
+		LayerOption::CloseOther);
 }
 
 bool RecoverBox::codeSubmitFail(const RPCError &error) {
@@ -512,7 +514,9 @@ bool RecoverBox::codeSubmitFail(const RPCError &error) {
 	const QString &err = error.type();
 	if (err == qstr("PASSWORD_EMPTY")) {
 		emit reloadPassword();
-		Ui::show(Box<InformBox>(lang(lng_cloud_password_removed)));
+		getDelegate()->show(
+			Box<InformBox>(lang(lng_cloud_password_removed)),
+			LayerOption::CloseOther);
 		return true;
 	} else if (err == qstr("PASSWORD_RECOVERY_NA")) {
 		closeBox();
diff --git a/Telegram/SourceFiles/passport/passport.style b/Telegram/SourceFiles/passport/passport.style
index 627c0b1d4..9fa1d40ce 100644
--- a/Telegram/SourceFiles/passport/passport.style
+++ b/Telegram/SourceFiles/passport/passport.style
@@ -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 }};
diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp
index 3fb2e78c4..b5f8c7df5 100644
--- a/Telegram/SourceFiles/passport/passport_form_controller.cpp
+++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp
@@ -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);
diff --git a/Telegram/SourceFiles/passport/passport_form_controller.h b/Telegram/SourceFiles/passport/passport_form_controller.h
index 45f9d6e81..215d7e503 100644
--- a/Telegram/SourceFiles/passport/passport_form_controller.h
+++ b/Telegram/SourceFiles/passport/passport_form_controller.h
@@ -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);
diff --git a/Telegram/SourceFiles/passport/passport_form_view_controller.h b/Telegram/SourceFiles/passport/passport_form_view_controller.h
index 6ef43feab..4a46b4e19 100644
--- a/Telegram/SourceFiles/passport/passport_form_view_controller.h
+++ b/Telegram/SourceFiles/passport/passport_form_view_controller.h
@@ -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;
 	}
 
diff --git a/Telegram/SourceFiles/passport/passport_panel.cpp b/Telegram/SourceFiles/passport/passport_panel.cpp
index 7a47f254b..f7d464b00 100644
--- a/Telegram/SourceFiles/passport/passport_panel.cpp
+++ b/Telegram/SourceFiles/passport/passport_panel.cpp
@@ -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() {
diff --git a/Telegram/SourceFiles/passport/passport_panel.h b/Telegram/SourceFiles/passport/passport_panel.h
index abb705f82..73ce87413 100644
--- a/Telegram/SourceFiles/passport/passport_panel.h
+++ b/Telegram/SourceFiles/passport/passport_panel.h
@@ -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);
diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.cpp b/Telegram/SourceFiles/passport/passport_panel_controller.cpp
index 38ebb4e52..f9b036e0a 100644
--- a/Telegram/SourceFiles/passport/passport_panel_controller.cpp
+++ b/Telegram/SourceFiles/passport/passport_panel_controller.cpp
@@ -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) {
diff --git a/Telegram/SourceFiles/passport/passport_panel_controller.h b/Telegram/SourceFiles/passport/passport_panel_controller.h
index 1adb33197..f2bf6fa19 100644
--- a/Telegram/SourceFiles/passport/passport_panel_controller.h
+++ b/Telegram/SourceFiles/passport/passport_panel_controller.h
@@ -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;
 
diff --git a/Telegram/SourceFiles/passport/passport_panel_form.cpp b/Telegram/SourceFiles/passport/passport_panel_form.cpp
index af3258b03..f52dbad9a 100644
--- a/Telegram/SourceFiles/passport/passport_panel_form.cpp
+++ b/Telegram/SourceFiles/passport/passport_panel_form.cpp
@@ -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,
diff --git a/Telegram/SourceFiles/passport/passport_panel_password.cpp b/Telegram/SourceFiles/passport/passport_panel_password.cpp
index b5b8684a1..5596c01ae 100644
--- a/Telegram/SourceFiles/passport/passport_panel_password.cpp
+++ b/Telegram/SourceFiles/passport/passport_panel_password.cpp
@@ -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
diff --git a/Telegram/SourceFiles/passport/passport_panel_password.h b/Telegram/SourceFiles/passport/passport_panel_password.h
index 2a6233d52..14de59bfd 100644
--- a/Telegram/SourceFiles/passport/passport_panel_password.h
+++ b/Telegram/SourceFiles/passport/passport_panel_password.h
@@ -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;
 
 };
 
diff --git a/Telegram/SourceFiles/ui/wrap/padding_wrap.cpp b/Telegram/SourceFiles/ui/wrap/padding_wrap.cpp
index 100a986e1..33ec9ba23 100644
--- a/Telegram/SourceFiles/ui/wrap/padding_wrap.cpp
+++ b/Telegram/SourceFiles/ui/wrap/padding_wrap.cpp
@@ -67,4 +67,35 @@ int PaddingWrap<RpWidget>::resizeGetHeight(int newWidth) {
 	return heightNoMargins();
 }
 
+CenterWrap<RpWidget>::CenterWrap(
+	QWidget *parent,
+	object_ptr<RpWidget> &&child)
+: Parent(parent, std::move(child)) {
+	if (const auto weak = wrapped()) {
+		wrappedSizeUpdated(weak->size());
+	}
+}
+
+int CenterWrap<RpWidget>::naturalWidth() const {
+	return -1;
+}
+
+int CenterWrap<RpWidget>::resizeGetHeight(int newWidth) {
+	updateWrappedPosition(newWidth);
+	return heightNoMargins();
+}
+
+void CenterWrap<RpWidget>::wrappedSizeUpdated(QSize size) {
+	updateWrappedPosition(width());
+}
+
+void CenterWrap<RpWidget>::updateWrappedPosition(int forWidth) {
+	if (const auto weak = wrapped()) {
+		const auto margins = weak->getMargins();
+		weak->moveToLeft(
+			(forWidth - weak->width()) / 2 + margins.left(),
+			margins.top());
+	}
+}
+
 } // namespace Ui
diff --git a/Telegram/SourceFiles/ui/wrap/padding_wrap.h b/Telegram/SourceFiles/ui/wrap/padding_wrap.h
index 4f529a505..24bf1a888 100644
--- a/Telegram/SourceFiles/ui/wrap/padding_wrap.h
+++ b/Telegram/SourceFiles/ui/wrap/padding_wrap.h
@@ -54,6 +54,42 @@ public:
 
 };
 
+template <typename Widget = RpWidget>
+class CenterWrap;
+
+template <>
+class CenterWrap<RpWidget> : public Wrap<RpWidget> {
+	using Parent = Wrap<RpWidget>;
+
+public:
+	CenterWrap(
+		QWidget *parent,
+		object_ptr<RpWidget> &&child);
+
+	int naturalWidth() const override;
+
+protected:
+	int resizeGetHeight(int newWidth) override;
+	void wrappedSizeUpdated(QSize size) override;
+
+private:
+	void updateWrappedPosition(int forWidth);
+
+};
+
+template <typename Widget>
+class CenterWrap : public Wrap<Widget, CenterWrap<RpWidget>> {
+	using Parent = Wrap<Widget, CenterWrap<RpWidget>>;
+
+public:
+	CenterWrap(
+		QWidget *parent,
+		object_ptr<Widget> &&child)
+	: Parent(parent, std::move(child)) {
+	}
+
+};
+
 class FixedHeightWidget : public RpWidget {
 public:
 	FixedHeightWidget(QWidget *parent, int height)
diff --git a/Telegram/SourceFiles/ui/wrap/wrap.h b/Telegram/SourceFiles/ui/wrap/wrap.h
index be855168f..221dae1a3 100644
--- a/Telegram/SourceFiles/ui/wrap/wrap.h
+++ b/Telegram/SourceFiles/ui/wrap/wrap.h
@@ -183,24 +183,4 @@ private:
 
 };
 
-class IgnoreNaturalWidth : public Wrap<RpWidget> {
-	using Parent = Wrap<RpWidget>;
-
-public:
-	IgnoreNaturalWidth(QWidget *parent, object_ptr<RpWidget> &&child)
-	: Parent(parent, std::move(child)) {
-		if (auto weak = wrapped()) {
-			auto margins = weak->getMargins();
-			resizeToWidth(weak->width()
-				- margins.left()
-				- margins.right());
-		}
-	}
-
-	int naturalWidth() const override {
-		return -1;
-	}
-
-};
-
 } // namespace Ui
diff --git a/Telegram/SourceFiles/window/layer_widget.cpp b/Telegram/SourceFiles/window/layer_widget.cpp
index 3a8ce5008..f5ef4d5d9 100644
--- a/Telegram/SourceFiles/window/layer_widget.cpp
+++ b/Telegram/SourceFiles/window/layer_widget.cpp
@@ -686,7 +686,7 @@ LayerWidget *LayerStackWidget::pushBox(
 
 	if (_layers.size() > 1) {
 		if (!_background->animating()) {
-			layer->show();
+			layer->setVisible(true);
 			showFinished();
 		}
 	} else {