Start passport support: handle link, receive form.

This commit is contained in:
John Preston 2018-03-18 12:51:14 +04:00
parent e122353bfb
commit ddb4527159
18 changed files with 471 additions and 58 deletions

View File

@ -191,6 +191,7 @@ inputPhoto#fb95c6c4 id:long access_hash:long = InputPhoto;
inputFileLocation#14637196 volume_id:long local_id:int secret:long = InputFileLocation;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#430f0724 id:long access_hash:long version:int = InputFileLocation;
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
inputAppEvent#770656a8 time:double type:string peer:long data:string = InputAppEvent;
@ -583,12 +584,12 @@ authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string s
account.authorizations#1250abde authorizations:Vector<Authorization> = account.Authorizations;
account.noPassword#96dabc18 new_salt:bytes email_unconfirmed_pattern:string = account.Password;
account.password#7c18141c current_salt:bytes new_salt:bytes hint:string has_recovery:Bool email_unconfirmed_pattern:string = account.Password;
account.noPassword#c86371bd new_salt:bytes secret_random:bytes email_unconfirmed_pattern:string = account.Password;
account.password#49efccf5 current_salt:bytes new_salt:bytes secret_random:bytes hint:string has_recovery:Bool email_unconfirmed_pattern:string = account.Password;
account.passwordSettings#b7b72ab3 email:string = account.PasswordSettings;
account.passwordSettings#f8ebfc3f email:string secure_secret:bytes = account.PasswordSettings;
account.passwordInputSettings#86916deb flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string = account.PasswordInputSettings;
account.passwordInputSettings#20ce9e59 flags:# new_salt:flags.0?bytes new_password_hash:flags.0?bytes hint:flags.0?string email:flags.1?string new_secure_secret:flags.2?bytes = account.PasswordInputSettings;
auth.passwordRecovery#137948a5 email_pattern:string = auth.PasswordRecovery;
@ -964,6 +965,37 @@ help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vect
help.termsOfServiceUpdateEmpty#e3309f7f expires:int = help.TermsOfServiceUpdate;
help.termsOfServiceUpdate#28ecf961 expires:int terms_of_service:help.TermsOfService = help.TermsOfServiceUpdate;
inputSecureFileUploaded#c53ed020 id:long parts:int md5_checksum:string file_hash:string = InputSecureFile;
inputSecureFile#5367e5be id:long access_hash:long = InputSecureFile;
secureFileEmpty#64199744 = SecureFile;
secureFile#40ad69ba id:long access_hash:long size:int dc_id:int file_hash:string = SecureFile;
secureValueEmpty#f0cec6e0 name:string = SecureValue;
secureValueData#6c3bf275 name:string data:bytes hash:string secret:bytes = SecureValue;
secureValueFile#a145a158 name:string file:Vector<SecureFile> hash:string secret:bytes = SecureValue;
secureValueText#1bb37ce3 name:string text:string hash:string = SecureValue;
inputSecureValueData#627bcf0d name:string data:bytes hash:string secret:bytes = InputSecureValue;
inputSecureValueFile#e24f9466 name:string file:Vector<InputSecureFile> hash:string secret:bytes = InputSecureValue;
inputSecureValueText#955a14bb name:string text:string hash:string = InputSecureValue;
secureValueHash#e4c2677 name:string hash:string = SecureValueHash;
authFieldTypeIdentity#4413b5d = AuthFieldType;
authFieldTypeAddress#63bbccf3 = AuthFieldType;
authFieldTypePhone#b56120ff = AuthFieldType;
authFieldTypeEmail#4cc9fd06 = AuthFieldType;
authField#ed81c3dc flags:# type:AuthFieldType data:SecureValue document:flags.0?SecureValue = AuthField;
account.secureValueResultSaved#f4e0ab11 = account.SecureValueResult;
account.secureValueVerificationNeeded#9192a1db code_hash:string = account.SecureValueResult;
account.authorizationForm#40997b71 flags:# accepted:flags.0?true request_write:flags.1?true bot_id:int fields:Vector<AuthField> accepted_fields:Vector<AuthFieldType> users:Vector<User> = account.AuthorizationForm;
account.authorizationResult#836727ce user_data:DataJSON accepted_fields:Vector<AuthFieldType> = account.AuthorizationResult;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1019,6 +1051,11 @@ account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPass
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
account.resetWebAuthorization#2d01b9ef hash:long = Bool;
account.resetWebAuthorizations#682d2594 = Bool;
account.getSecureValue#d86fa683 user_id:InputUser name:Vector<string> = Vector<SecureValue>;
account.saveSecureValue#9fc2a624 data:InputSecureValue = account.SecureValueResult;
account.verifySecureValue#68367bed name:string code_hash:string code:string = Bool;
account.getAuthorizationForm#2f003837 flags:# bot_id:int scope:Vector<string> origin:flags.0?string package_name:flags.1?string bundle_id:flags.2?string public_key:flags.3?string = account.AuthorizationForm;
account.acceptAuthorization#df98a3f5 flags:# request_write:flags.4?true bot_id:int scope:Vector<string> origin:flags.0?string package_name:flags.1?string bundle_id:flags.2?string public_key:flags.3?string accepted_fields:Vector<AuthFieldType> value_hashes:Vector<secureValueHash> = account.AuthorizationResult;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;

View File

@ -2397,12 +2397,6 @@ std::vector<not_null<DocumentData*>> *ApiWrap::stickersByEmoji(
auto &entry = _stickersByEmoji[emoji];
entry.list.clear();
entry.list.reserve(data.vstickers.v.size());
for (const auto &sticker : data.vstickers.v) {
const auto document = _session->data().document(sticker);
if (document->sticker()) {
entry.list.push_back(document);
}
}
entry.hash = data.vhash.v;
entry.received = getms(true);
_session->data().notifyStickersUpdated();

View File

@ -327,8 +327,19 @@ void PasscodeBox::save(bool force) {
if (_oldPasscode->isHidden() || _newPasscode->isHidden()) {
flags |= MTPDaccount_passwordInputSettings::Flag::f_email;
}
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(_newSalt), MTP_bytes(newPasswordHash), MTP_string(hint), MTP_string(email)));
_setRequest = MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(oldPasswordHash), settings), rpcDone(&PasscodeBox::setPasswordDone), rpcFail(&PasscodeBox::setPasswordFail));
const auto newSecureSecret = base::byte_vector();
_setRequest = MTP::send(
MTPaccount_UpdatePasswordSettings(
MTP_bytes(oldPasswordHash),
MTP_account_passwordInputSettings(
MTP_flags(flags),
MTP_bytes(_newSalt),
MTP_bytes(newPasswordHash),
MTP_string(hint),
MTP_string(email),
MTP_bytes(newSecureSecret))),
rpcDone(&PasscodeBox::setPasswordDone),
rpcFail(&PasscodeBox::setPasswordFail));
}
} else {
cSetPasscodeBadTries(0);

View File

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_cloud_manager.h"
#include "lang/lang_hardcoded.h"
#include "core/update_checker.h"
#include "passport/passport_form_controller.h"
#include "observer_peer.h"
#include "storage/file_upload.h"
#include "mainwidget.h"
@ -907,6 +908,24 @@ bool Messenger::openLocalUrl(const QString &url) {
auto params = url_parse_params(proxyMatch->captured(1), UrlParamNameTransform::ToLower);
ProxiesBoxController::ShowApplyConfirmation(ProxyData::Type::Mtproto, params);
return true;
} else if (auto authMatch = regex_match(qsl("^auth/?\\?(.+)(#|$)"), command, matchOptions)) {
const auto params = url_parse_params(
authMatch->captured(1),
UrlParamNameTransform::ToLower);
if (const auto botId = params.value("bot_id", QString()).toInt()) {
const auto scope = params.value("scope", QString()).split(',');
const auto callback = params.value("callback_url", QString());
const auto publicKey = params.value("public_key", QString());
if (const auto window = App::wnd()) {
if (const auto controller = window->controller()) {
controller->showAuthForm(Passport::FormRequest(
botId,
scope,
callback,
publicKey));
}
}
}
}
return false;
}

View File

@ -8,9 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/auth_key.h"
#include <openssl/aes.h>
extern "C" {
#include <openssl/modes.h>
}
namespace MTP {

View File

@ -0,0 +1,216 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "passport/passport_form_controller.h"
#include "boxes/confirm_box.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
namespace Passport {
FormRequest::FormRequest(
UserId botId,
const QStringList &scope,
const QString &callbackUrl,
const QString &publicKey)
: botId(botId)
, scope(scope)
, callbackUrl(callbackUrl)
, publicKey(publicKey) {
}
FormController::Field::Field(Type type) : type(type) {
}
FormController::FormController(
not_null<Window::Controller*> controller,
const FormRequest &request)
: _controller(controller)
, _request(request) {
const auto url = QUrl(_request.callbackUrl);
_origin = url.scheme() + "://" + url.host();
}
void FormController::show() {
requestForm();
requestPassword();
}
void FormController::requestForm() {
auto scope = QVector<MTPstring>();
scope.reserve(_request.scope.size());
for (const auto &element : _request.scope) {
scope.push_back(MTP_string(element));
}
auto normalizedKey = _request.publicKey;
normalizedKey.replace("\r\n", "\n");
const auto bytes = normalizedKey.toUtf8();
request(MTPaccount_GetAuthorizationForm(
MTP_flags(MTPaccount_GetAuthorizationForm::Flag::f_origin
| MTPaccount_GetAuthorizationForm::Flag::f_public_key),
MTP_int(_request.botId),
MTP_vector<MTPstring>(std::move(scope)),
MTP_string(_origin),
MTPstring(), // package_name
MTPstring(), // bundle_id
MTP_bytes(bytes)
)).done([=](const MTPaccount_AuthorizationForm &result) {
formDone(result);
}).fail([=](const RPCError &error) {
formFail(error);
}).send();
}
auto FormController::convertValue(
const MTPSecureValue &value) const -> Value {
auto result = Value();
switch (value.type()) {
case mtpc_secureValueEmpty: {
const auto &data = value.c_secureValueEmpty();
result.name = qs(data.vname);
} break;
case mtpc_secureValueData: {
const auto &data = value.c_secureValueData();
result.name = qs(data.vname);
result.data = data.vdata.v;
result.dataHash = data.vhash.v;
result.dataSecret = data.vsecret.v;
} break;
case mtpc_secureValueText: {
const auto &data = value.c_secureValueText();
result.name = qs(data.vname);
result.text = qs(data.vtext);
result.textHash = data.vhash.v;
} break;
case mtpc_secureValueFile: {
const auto &data = value.c_secureValueFile();
result.name = qs(data.vname);
result.filesHash = data.vhash.v;
result.filesSecret = data.vsecret.v;
for (const auto &file : data.vfile.v) {
switch (file.type()) {
case mtpc_secureFileEmpty: {
result.files.push_back(File());
} break;
case mtpc_secureFile: {
const auto &fields = file.c_secureFile();
auto normal = File();
normal.id = fields.vid.v;
normal.accessHash = fields.vaccess_hash.v;
normal.size = fields.vsize.v;
normal.dcId = fields.vdc_id.v;
normal.fileHash = qba(fields.vfile_hash);
result.files.push_back(std::move(normal));
} break;
}
}
} break;
}
return result;
}
void FormController::formDone(const MTPaccount_AuthorizationForm &result) {
parseForm(result);
showForm();
}
void FormController::parseForm(const MTPaccount_AuthorizationForm &result) {
Expects(result.type() == mtpc_account_authorizationForm);
const auto &data = result.c_account_authorizationForm();
_form.requestWrite = data.is_request_write();
if (_request.botId != data.vbot_id.v) {
LOG(("API Error: Wrong account.authorizationForm.bot_id."));
_request.botId = data.vbot_id.v;
}
App::feedUsers(data.vusers);
for (const auto &field : data.vfields.v) {
Assert(field.type() == mtpc_authField);
using Type = Field::Type;
const auto &data = field.c_authField();
const auto type = [&] {
switch (data.vtype.type()) {
case mtpc_authFieldTypeIdentity: return Type::Identity;
case mtpc_authFieldTypeAddress: return Type::Address;
case mtpc_authFieldTypeEmail: return Type::Email;
case mtpc_authFieldTypePhone: return Type::Phone;
}
Unexpected("Type in authField.type.");
}();
auto entry = Field(type);
entry.data = convertValue(data.vdata);
if (data.has_document()) {
entry.document = convertValue(data.vdocument);
}
_form.fields.push_back(std::move(entry));
}
_bot = App::userLoaded(_request.botId);
}
void FormController::showForm() {
if (!_bot) {
Ui::show(Box<InformBox>("Could not get authorization bot."));
return;
}
auto text = QString("Auth request:\n");
for (const auto &field : _form.fields) {
switch (field.type) {
case Field::Type::Identity: text += "- identity\n"; break;
case Field::Type::Address: text += "- address\n"; break;
case Field::Type::Email: text += "- email\n"; break;
case Field::Type::Phone: text += "- phone\n"; break;
}
}
if (_form.requestWrite) {
text += "and bot @" + _bot->username + " requests write permission.";
} else {
text += "and bot @" + _bot->username + " does not request write permission.";
}
Ui::show(Box<InformBox>(text));
// Ui::show(Box<FormBox>(this));
}
void FormController::formFail(const RPCError &error) {
// #TODO langs
Ui::show(Box<InformBox>("Could not get authorization form."));
}
void FormController::requestPassword() {
request(MTPaccount_GetPassword(
)).done([=](const MTPaccount_Password &result) {
passwordDone(result);
}).send();
}
void FormController::passwordDone(const MTPaccount_Password &result) {
switch (result.type()) {
case mtpc_account_noPassword:
createPassword(result.c_account_noPassword());
break;
case mtpc_account_password:
checkPassword(result.c_account_password());
break;
}
}
void FormController::passwordFail(const RPCError &error) {
Ui::show(Box<InformBox>("Could not get authorization form."));
}
void FormController::createPassword(const MTPDaccount_noPassword &result) {
Ui::show(Box<InformBox>("You need 2fa password!")); // #TODO
}
void FormController::checkPassword(const MTPDaccount_password &result) {
}
} // namespace Passport

View File

@ -0,0 +1,103 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
namespace Window {
class Controller;
} // namespace Window
namespace Passport {
struct FormRequest {
FormRequest(
UserId botId,
const QStringList &scope,
const QString &callbackUrl,
const QString &publicKey);
UserId botId;
QStringList scope;
QString callbackUrl;
QString publicKey;
};
class FormController : private MTP::Sender {
public:
FormController(
not_null<Window::Controller*> controller,
const FormRequest &request);
void show();
private:
struct File {
uint64 id = 0;
uint64 accessHash = 0;
int32 size = 0;
int32 dcId = 0;
QByteArray fileHash;
};
struct Value {
QString name;
QByteArray data;
QByteArray dataHash;
QByteArray dataSecret;
QString text;
QByteArray textHash;
std::vector<File> files;
QByteArray filesHash;
QByteArray filesSecret;
};
struct Field {
enum class Type {
Identity,
Address,
Phone,
Email,
};
explicit Field(Type type);
Type type;
Value data;
base::optional<Value> document;
};
struct Form {
bool requestWrite = false;
std::vector<Field> fields;
};
Value convertValue(const MTPSecureValue &value) const;
void requestForm();
void requestPassword();
void formDone(const MTPaccount_AuthorizationForm &result);
void formFail(const RPCError &error);
void parseForm(const MTPaccount_AuthorizationForm &result);
void showForm();
void passwordDone(const MTPaccount_Password &result);
void passwordFail(const RPCError &error);
void createPassword(const MTPDaccount_noPassword &settings);
void checkPassword(const MTPDaccount_password &settings);
not_null<Window::Controller*> _controller;
FormRequest _request;
UserData *_bot = nullptr;
QString _origin;
Form _form;
};
} // namespace Passport

View File

@ -31,6 +31,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
using namespace Platform;
using Platform::File::internal::EscapeShell;
namespace {
bool _psRunCommand(const QByteArray &command) {
auto result = system(command.constData());
if (result) {
DEBUG_LOG(("App Error: command failed, code: %1, command (in utf8): %2").arg(result).arg(command.constData()));
return false;
}
DEBUG_LOG(("App Info: command succeeded, command (in utf8): %1").arg(command.constData()));
return true;
}
} // namespace
namespace Platform {
QString CurrentExecutablePath(int argc, char *argv[]) {
@ -389,35 +403,7 @@ QString SystemLanguage() {
return QString();
}
namespace ThirdParty {
void start() {
Libs::start();
MainWindow::LibsLoaded();
}
void finish() {
}
} // namespace ThirdParty
} // namespace Platform
namespace {
bool _psRunCommand(const QByteArray &command) {
auto result = system(command.constData());
if (result) {
DEBUG_LOG(("App Error: command failed, code: %1, command (in utf8): %2").arg(result).arg(command.constData()));
return false;
}
DEBUG_LOG(("App Info: command succeeded, command (in utf8): %1").arg(command.constData()));
return true;
}
} // namespace
void psRegisterCustomScheme() {
void RegisterCustomScheme() {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
auto home = getHomeDir();
if (home.isEmpty() || cBetaVersion() || cExeName().isEmpty()) return; // don't update desktop file for beta version
@ -517,8 +503,22 @@ void psRegisterCustomScheme() {
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}
namespace ThirdParty {
void start() {
Libs::start();
MainWindow::LibsLoaded();
}
void finish() {
}
} // namespace ThirdParty
} // namespace Platform
void psNewVersion() {
psRegisterCustomScheme();
Platform::RegisterCustomScheme();
}
bool psShowOpenWithMenu(int x, int y, const QString &file) {

View File

@ -398,10 +398,17 @@ QString CurrentExecutablePath(int argc, char *argv[]) {
return NS2QString([[NSBundle mainBundle] bundlePath]);
}
void RegisterCustomScheme() {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
DEBUG_LOG(("App Info: set default handler for 'tg' scheme result: %1").arg(result));
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}
} // namespace Platform
void psNewVersion() {
objc_registerCustomScheme();
Platform::RegisterCustomScheme();
}
void psAutoStart(bool start, bool silent) {

View File

@ -23,8 +23,6 @@ void objc_start();
void objc_ignoreApplicationActivationRightNow();
void objc_finish();
void objc_registerCustomScheme();
void objc_activateProgram(WId winId);
bool objc_moveFile(const QString &from, const QString &to);
void objc_deleteDir(const QString &dir);

View File

@ -394,13 +394,6 @@ void objc_finish() {
}
}
void objc_registerCustomScheme() {
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
OSStatus result = LSSetDefaultHandlerForURLScheme(CFSTR("tg"), (CFStringRef)[[NSBundle mainBundle] bundleIdentifier]);
DEBUG_LOG(("App Info: set default handler for 'tg' scheme result: %1").arg(result));
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}
void objc_activateProgram(WId winId) {
[NSApp activateIgnoringOtherApps:YES];
if (winId) {

View File

@ -18,6 +18,7 @@ void StartTranslucentPaint(QPainter &p, QPaintEvent *e);
void InitOnTopPanel(QWidget *panel);
void DeInitOnTopPanel(QWidget *panel);
void ReInitOnTopPanel(QWidget *panel);
void RegisterCustomScheme();
QString SystemLanguage();
QString SystemCountry();

View File

@ -576,6 +576,8 @@ namespace {
}
}
namespace Platform {
void RegisterCustomScheme() {
if (cExeName().isEmpty()) {
return;
@ -621,8 +623,10 @@ void RegisterCustomScheme() {
#endif // !TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
}
} // namespace Platform
void psNewVersion() {
RegisterCustomScheme();
Platform::RegisterCustomScheme();
if (Local::oldSettingsVersion() < 8051) {
AppUserModelId::checkPinned();
}

View File

@ -81,9 +81,18 @@ void CloudPasswordState::onTurnOff() {
if (_curPasswordSalt.isEmpty()) {
_turnOff->hide();
auto flags = MTPDaccount_passwordInputSettings::Flag::f_email;
MTPaccount_PasswordInputSettings settings(MTP_account_passwordInputSettings(MTP_flags(flags), MTP_bytes(QByteArray()), MTP_bytes(QByteArray()), MTP_string(QString()), MTP_string(QString())));
MTP::send(MTPaccount_UpdatePasswordSettings(MTP_bytes(QByteArray()), settings), rpcDone(&CloudPasswordState::offPasswordDone), rpcFail(&CloudPasswordState::offPasswordFail));
MTP::send(
MTPaccount_UpdatePasswordSettings(
MTP_bytes(QByteArray()),
MTP_account_passwordInputSettings(
MTP_flags(MTPDaccount_passwordInputSettings::Flag::f_email),
MTP_bytes(QByteArray()),
MTP_bytes(QByteArray()),
MTP_string(QString()),
MTP_string(QString()),
MTP_bytes(QByteArray()))),
rpcDone(&CloudPasswordState::offPasswordDone),
rpcFail(&CloudPasswordState::offPasswordFail));
} else {
auto box = Ui::show(Box<PasscodeBox>(_newPasswordSalt, _curPasswordSalt, _hasPasswordRecovery, _curPasswordHint, true));
connect(box, SIGNAL(reloadPassword()), this, SLOT(onReloadPassword()));

View File

@ -12,8 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_settings.h"
#include "styles/style_window.h"
#include "styles/style_boxes.h"
#include "platform/platform_specific.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/buttons.h"
#include "ui/toast/toast.h"
#include "mainwindow.h"
#include "mainwidget.h"
#include "storage/localstorage.h"
@ -114,6 +116,10 @@ void fillCodes() {
}
});
});
Codes.insert(qsl("registertg"), [] {
Platform::RegisterCustomScheme();
Ui::Toast::Show("Forced custom scheme register.");
});
auto audioFilters = qsl("Audio files (*.wav *.mp3);;") + FileDialog::AllFilesFilter();
auto audioKeys = {

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/player/media_player_round_controller.h"
#include "data/data_session.h"
#include "data/data_feed.h"
#include "passport/passport_form_controller.h"
#include "boxes/calendar_box.h"
#include "mainwidget.h"
#include "mainwindow.h"
@ -404,6 +405,11 @@ void Controller::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
Ui::show(std::move(box));
}
void Controller::showAuthForm(const Passport::FormRequest &request) {
_authForm = std::make_unique<Passport::FormController>(this, request);
_authForm->show();
}
void Controller::updateColumnLayout() {
App::main()->updateColumnLayout();
}

View File

@ -21,6 +21,11 @@ class RoundController;
} // namespace Player
} // namespace Media
namespace Passport {
struct FormRequest;
class FormController;
} // namespace Passport
namespace Window {
class LayerWidget;
@ -200,6 +205,8 @@ public:
Dialogs::Key chat,
QDate requestedDate);
void showAuthForm(const Passport::FormRequest &request);
base::Variable<bool> &dialogsListFocused() {
return _dialogsListFocused;
}
@ -246,6 +253,8 @@ private:
not_null<MainWindow*> _window;
std::unique_ptr<Passport::FormController> _authForm;
GifPauseReasons _gifPauseReasons = 0;
base::Observable<void> _gifPauseLevelChanged;
base::Observable<void> _floatPlayerAreaUpdated;

View File

@ -454,6 +454,8 @@
<(src_loc)/mtproto/type_utils.h
<(src_loc)/overview/overview_layout.cpp
<(src_loc)/overview/overview_layout.h
<(src_loc)/passport/passport_form_controller.cpp
<(src_loc)/passport/passport_form_controller.h
<(src_loc)/platform/linux/linux_desktop_environment.cpp
<(src_loc)/platform/linux/linux_desktop_environment.h
<(src_loc)/platform/linux/linux_gdk_helper.cpp