From 633ff4b60e61d6772aa7827d626ed2f6b1629817 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 9 Sep 2018 15:10:54 +0300 Subject: [PATCH] Implement privacy and security settings section. --- Telegram/Resources/langs/lang.strings | 9 + Telegram/SourceFiles/apiwrap.cpp | 57 +++ Telegram/SourceFiles/apiwrap.h | 13 + .../SourceFiles/core/core_cloud_password.cpp | 18 + .../SourceFiles/core/core_cloud_password.h | 14 + Telegram/SourceFiles/settings/settings.style | 21 +- .../SourceFiles/settings/settings_chat.cpp | 19 +- .../SourceFiles/settings/settings_common.cpp | 42 +- .../SourceFiles/settings/settings_common.h | 9 + .../SourceFiles/settings/settings_general.cpp | 16 +- .../SourceFiles/settings/settings_main.cpp | 3 + .../settings/settings_privacy_security.cpp | 395 +++++++++++++++++- 12 files changed, 582 insertions(+), 34 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 153ff4040b..5ff5cc7f8a 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -335,6 +335,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_connection_type" = "Connection type"; "lng_settings_downloading_update" = "Downloading update {progress}..."; "lng_settings_use_night_mode" = "Use night mode"; +"lng_settings_privacy_title" = "Privacy"; +"lng_settings_last_seen" = "Last seen"; +"lng_settings_calls" = "Calls"; +"lng_settings_groups_invite" = "Groups"; +"lng_settings_group_privacy_about" = "Change who can add you to groups and channel."; +"lng_settings_security_title" = "Security"; +"lng_settings_sessions_about" = "Control your sessions on other devices."; +"lng_settings_passcode_disable" = "Disable passcode"; +"lng_settings_password_disable" = "Disable cloud password"; "lng_backgrounds_header" = "Choose your new chat background"; "lng_theme_sure_keep" = "Keep this theme?"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 4dcb6bc795..6718e2eb5d 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -18,6 +18,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "dialogs/dialogs_key.h" #include "core/tl_help.h" +#include "core/core_cloud_password.h" +#include "base/openssl_help.h" #include "base/overload.h" #include "observer_peer.h" #include "lang/lang_keys.h" @@ -4889,6 +4891,61 @@ void ApiWrap::clearPeerPhoto(not_null photo) { } } +void ApiWrap::reloadPasswordState() { + if (_passwordRequestId) { + return; + } + _passwordRequestId = request(MTPaccount_GetPassword( + )).done([=](const MTPaccount_Password &result) { + _passwordRequestId = 0; + result.match([&](const MTPDaccount_password &data) { + openssl::AddRandomSeed(bytes::make_span(data.vsecure_random.v)); + if (_passwordState) { + *_passwordState = Core::ParseCloudPasswordState(data); + } else { + _passwordState = std::make_unique( + Core::ParseCloudPasswordState(data)); + } + _passwordStateChanges.fire_copy(*_passwordState); + }); + }).fail([=](const RPCError &error) { + _passwordRequestId = 0; + }).send(); +} + +void ApiWrap::clearUnconfirmedPassword() { + _passwordRequestId = request(MTPaccount_UpdatePasswordSettings( + MTP_inputCheckPasswordEmpty(), + MTP_account_passwordInputSettings( + MTP_flags( + MTPDaccount_passwordInputSettings::Flag::f_email), + MTP_passwordKdfAlgoUnknown(), // new_algo + MTP_bytes(QByteArray()), // new_password_hash + MTP_string(QString()), // hint + MTP_string(QString()), // email + MTPSecureSecretSettings()) + )).done([=](const MTPBool &result) { + _passwordRequestId = 0; + reloadPasswordState(); + }).fail([=](const RPCError &error) { + _passwordRequestId = 0; + reloadPasswordState(); + }).send(); +} + +rpl::producer ApiWrap::passwordState() const { + return _passwordState + ? _passwordStateChanges.events_starting_with_copy(*_passwordState) + : _passwordStateChanges.events(); +} + +auto ApiWrap::passwordStateCurrent() const +->base::optional { + return _passwordState + ? base::make_optional(*_passwordState) + : base::none; +} + void ApiWrap::readServerHistory(not_null history) { if (history->unreadCount()) { readServerHistoryForce(history); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index f00a5c7727..fbcedf0e34 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -37,6 +37,10 @@ namespace Dialogs { class Key; } // namespace Dialogs +namespace Core { +struct CloudPasswordState; +} // namespace Core + namespace Api { inline const MTPVector *getChatsFromMessagesChats(const MTPmessages_Chats &chats) { @@ -327,6 +331,11 @@ public: void uploadPeerPhoto(not_null peer, QImage &&image); void clearPeerPhoto(not_null photo); + void reloadPasswordState(); + void clearUnconfirmedPassword(); + rpl::producer passwordState() const; + base::optional passwordStateCurrent() const; + ~ApiWrap(); private: @@ -659,4 +668,8 @@ private: base::flat_map> _peerPhotoUploads; + mtpRequestId _passwordRequestId = 0; + std::unique_ptr _passwordState; + rpl::event_stream _passwordStateChanges; + }; diff --git a/Telegram/SourceFiles/core/core_cloud_password.cpp b/Telegram/SourceFiles/core/core_cloud_password.cpp index 446a5abb2d..22918ba772 100644 --- a/Telegram/SourceFiles/core/core_cloud_password.cpp +++ b/Telegram/SourceFiles/core/core_cloud_password.cpp @@ -303,4 +303,22 @@ bytes::vector ComputeSecureSecretHash( }); } +CloudPasswordState ParseCloudPasswordState( + const MTPDaccount_password &data) { + auto result = CloudPasswordState(); + result.request = ParseCloudPasswordCheckRequest(data); + result.unknownAlgorithm = data.has_current_algo() && !result.request; + result.hasRecovery = data.is_has_recovery(); + result.notEmptyPassport = data.is_has_secure_values(); + result.hint = data.has_hint() ? qs(data.vhint) : QString(); + result.newPassword = ValidateNewCloudPasswordAlgo( + ParseCloudPasswordAlgo(data.vnew_algo)); + result.newSecureSecret = ValidateNewSecureSecretAlgo( + ParseSecureSecretAlgo(data.vnew_secure_algo)); + result.unconfirmedPattern = data.has_email_unconfirmed_pattern() + ? qs(data.vemail_unconfirmed_pattern) + : QString(); + return result; +} + } // namespace Core \ No newline at end of file diff --git a/Telegram/SourceFiles/core/core_cloud_password.h b/Telegram/SourceFiles/core/core_cloud_password.h index 5f9754308d..bffafe5b7c 100644 --- a/Telegram/SourceFiles/core/core_cloud_password.h +++ b/Telegram/SourceFiles/core/core_cloud_password.h @@ -120,4 +120,18 @@ bytes::vector ComputeSecureSecretHash( const SecureSecretAlgo &algo, bytes::const_span password); +struct CloudPasswordState { + CloudPasswordCheckRequest request; + bool unknownAlgorithm = false; + bool hasRecovery = false; + bool notEmptyPassport = false; + QString hint; + CloudPasswordAlgo newPassword; + SecureSecretAlgo newSecureSecret; + QString unconfirmedPattern; +}; + +CloudPasswordState ParseCloudPasswordState( + const MTPDaccount_password &data); + } // namespace Core diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index 4a27468c38..1b653d99ca 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -13,13 +13,14 @@ using "boxes/boxes.style"; settingsSectionButton: InfoProfileButton(infoProfileButton) { font: boxTextFont; } -settingsButton: InfoProfileButton(settingsSectionButton) { - padding: margins(28px, 10px, 8px, 8px); +settingsGeneralButton: InfoProfileButton(settingsSectionButton) { + padding: margins(28px, 10px, 22px, 8px); } -settingsChatButton: InfoProfileButton(settingsSectionButton) { - padding: margins(22px, 10px, 8px, 8px); +settingsButton: InfoProfileButton(settingsSectionButton) { + padding: margins(22px, 10px, 22px, 8px); } settingsSectionSkip: infoProfileSkip; +settingsSeparatorPadding: margins(22px, infoProfileSkip, 0px, infoProfileSkip); settingsButtonRightPosition: point(28px, 10px); settingsButtonRight: FlatLabel(defaultFlatLabel) { textFg: windowActiveTextFg; @@ -39,6 +40,7 @@ settingsUpdateState: FlatLabel(defaultFlatLabel) { settingsUpdate: InfoProfileButton(infoMainButton, settingsButton) { } settingsUpdateStatePosition: point(28px, 30px); +settingsDividerLabelPadding: margins(22px, 7px, 22px, 14px); settingsSendType: defaultBoxCheckbox; settingsSendTypePadding: margins(22px, 5px, 10px, 5px); @@ -55,7 +57,7 @@ settingsDownloadPathPadding: margins(22px, 1px, 10px, 0px); settingsBackgroundThumb: 76px; settingsThumbSkip: 16px; -settingsBackgroundTitle: FlatLabel(defaultFlatLabel) { +settingsSubsectionTitle: FlatLabel(defaultFlatLabel) { style: TextStyle(semiboldTextStyle) { font: font(boxFontSize semibold); linkFont: font(boxFontSize semibold); @@ -63,7 +65,14 @@ settingsBackgroundTitle: FlatLabel(defaultFlatLabel) { } textFg: windowActiveTextFg; } -settingsBackgroundTitlePadding: margins(22px, 7px, 10px, 9px); +settingsSubsectionTitlePadding: margins(22px, 7px, 10px, 9px); settingsBackgroundPadding: margins(22px, 8px, 10px, 8px); settingsFromGalleryTop: 2px; settingsFromFileTop: 14px; + +settingsCloudPasswordLabel: FlatLabel(defaultFlatLabel) { + textFg: windowSubTextFg; + style: boxTextStyle; + maxHeight: 20px; +} +settingsCloudPasswordLabelPadding: margins(22px, 8px, 10px, 8px); diff --git a/Telegram/SourceFiles/settings/settings_chat.cpp b/Telegram/SourceFiles/settings/settings_chat.cpp index e98bf379fb..5e187b3b98 100644 --- a/Telegram/SourceFiles/settings/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/settings_chat.cpp @@ -535,7 +535,7 @@ void SetupMediaOptions(not_null container) { AddButton( container, lng_media_auto_settings, - st::settingsChatButton + st::settingsButton )->addClickHandler([] { Ui::show(Box()); }); @@ -543,7 +543,7 @@ void SetupMediaOptions(not_null container) { AddButton( container, lng_stickers_you_have, - st::settingsChatButton + st::settingsButton )->addClickHandler([] { Ui::show(Box(StickersBox::Section::Installed)); }); @@ -555,12 +555,7 @@ void SetupChatBackground(not_null container) { AddDivider(container); AddSkip(container); - container->add( - object_ptr( - container, - Lang::Viewer(lng_settings_section_background), - st::settingsBackgroundTitle), - st::settingsBackgroundTitlePadding); + AddSubsectionTitle(container, lng_settings_section_background); container->add( object_ptr(container), @@ -637,7 +632,7 @@ void SetupThemeOptions(not_null container) { AddButton( container, lng_settings_use_night_mode, - st::settingsChatButton + st::settingsButton )->toggleOn( rpl::single(Window::Theme::IsNightMode()) )->toggledValue( @@ -657,9 +652,9 @@ void SetupThemeOptions(not_null container) { AddButton( container, lng_settings_bg_edit_theme, - st::settingsChatButton + st::settingsButton )->addClickHandler(App::LambdaDelayed( - st::settingsChatButton.ripple.hideDuration, + st::settingsButton.ripple.hideDuration, container, [] { Window::Theme::Editor::Start(); })); @@ -670,7 +665,7 @@ void SetupThemeOptions(not_null container) { object_ptr