From 3f77b0fc8b3f1c00902ad6a12747e8b0a10ac50d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 29 Jun 2018 13:01:22 +0200 Subject: [PATCH 1/3] Move user password form to security settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- lib/private/Settings/Manager.php | 2 +- lib/private/Settings/Personal/Security.php | 19 ++++- settings/css/settings.scss | 50 ++++++----- settings/js/security_password.js | 85 +++++++++++++++++++ settings/js/settings/personalInfo.js | 74 ---------------- .../settings/personal/personal.info.php | 32 ------- .../templates/settings/personal/security.php | 36 ++++++++ 7 files changed, 169 insertions(+), 129 deletions(-) create mode 100644 settings/js/security_password.js diff --git a/lib/private/Settings/Manager.php b/lib/private/Settings/Manager.php index 4ee594c090ff1..bbc0ac7e4dba3 100644 --- a/lib/private/Settings/Manager.php +++ b/lib/private/Settings/Manager.php @@ -308,7 +308,7 @@ private function getBuiltInPersonalSettings($section): array { } if($section === 'security') { /** @var ISettings $form */ - $form = new Personal\Security(); + $form = new Personal\Security($this->userManager); $forms[$form->getPriority()] = [$form]; } if ($section === 'additional') { diff --git a/lib/private/Settings/Personal/Security.php b/lib/private/Settings/Personal/Security.php index ecbd1199d114d..efcfd5589ceb7 100644 --- a/lib/private/Settings/Personal/Security.php +++ b/lib/private/Settings/Personal/Security.php @@ -25,16 +25,33 @@ use OCP\AppFramework\Http\TemplateResponse; +use OCP\IUserManager; use OCP\Settings\ISettings; class Security implements ISettings { + private $userManager; + + public function __construct( + IUserManager $userManager + ) { + $this->userManager = $userManager; + } + /** * @return TemplateResponse returns the instance with all parameters set, ready to be rendered * @since 9.1 */ public function getForm() { - return new TemplateResponse('settings', 'settings/personal/security'); + $user = $this->userManager->get(\OC_User::getUser()); + $passwordChangeSupported = false; + if ($user !== null) { + $passwordChangeSupported = $user->canChangePassword(); + } + + return new TemplateResponse('settings', 'settings/personal/security', [ + 'passwordChangeSupported' => $passwordChangeSupported + ]); } /** diff --git a/settings/css/settings.scss b/settings/css/settings.scss index cfca22d5bbb2b..910c1b4c0800e 100644 --- a/settings/css/settings.scss +++ b/settings/css/settings.scss @@ -124,14 +124,6 @@ select { } } -input { - &#pass1, - &#pass2, - &#passwordbutton { - width: 100%; - } -} - #personal-settings { display: grid; padding: 20px; @@ -380,9 +372,7 @@ input#identity { } } -.password-state { - display: inline-block; -} + table.nostyle { label { @@ -393,6 +383,33 @@ table.nostyle { } } +#security-password { + #passwordform { + display: flex; + flex-wrap: wrap; + #pass1, .personal-show-container, #passwordbutton { + flex-shrink: 1; + width: 200px; + min-width: 150px; + } + #pass2 { + width: 100%; + } + .password-state { + display: inline-block; + } + .strengthify-wrapper { + position: absolute; + left: 0; + width: 100%; + border-radius: 0 0 2px 2px; + margin-top: -6px; + overflow: hidden; + height: 3px; + } + } +} + #security { table { width: 100%; @@ -1243,16 +1260,7 @@ span { } } -/* PASSWORD */ -#passwordform .strengthify-wrapper { - position: absolute; - left: 0; - width: 100%; - border-radius: 0 0 2px 2px; - margin-top: -6px; - overflow: hidden; - height: 3px; -} + /* OPERA hack for strengthify*/ doesnotexist:-o-prefocus, .strengthify-wrapper { diff --git a/settings/js/security_password.js b/settings/js/security_password.js new file mode 100644 index 0000000000000..f7cb657c258e5 --- /dev/null +++ b/settings/js/security_password.js @@ -0,0 +1,85 @@ +/* global OC */ + +/** + * Copyright (c) 2011, Robin Appelman + * 2013, Morris Jobke + * 2016, Christoph Wurst + * 2017, Arthur Schiwon + * 2017, Thomas Citharel + * This file is licensed under the Affero General Public License version 3 or later. + * See the COPYING-README file. + */ + +$(document).ready(function () { + if($('#pass2').length) { + $('#pass2').showPassword().keyup(); + } + + var removeloader = function () { + setTimeout(function(){ + if ($('.password-state').length > 0) { + $('.password-state').remove(); + } + }, 5000) + }; + + $("#passwordbutton").click(function () { + if ($('#pass1').val() !== '' && $('#pass2').val() !== '') { + // Serialize the data + var post = $("#passwordform").serialize(); + $('#passwordchanged').hide(); + $('#passworderror').hide(); + $("#passwordbutton").attr('disabled', 'disabled'); + $("#passwordbutton").after(""); + $(".personal-show-label").hide(); + // Ajax foo + $.post(OC.generateUrl('/settings/personal/changepassword'), post, function (data) { + if (data.status === "success") { + $("#passwordbutton").after(""); + removeloader(); + $('#pass1').val(''); + $('#pass2').val('').change(); + } + if (typeof(data.data) !== "undefined") { + OC.msg.finishedSaving('#password-error-msg', data); + } else { + OC.msg.finishedSaving('#password-error-msg', + { + 'status' : 'error', + 'data' : { + 'message' : t('settings', 'Unable to change password') + } + } + ); + } + $(".personal-show-label").show(); + $(".password-loading").remove(); + $("#passwordbutton").removeAttr('disabled'); + }); + return false; + } else { + OC.msg.finishedSaving('#password-error-msg', + { + 'status' : 'error', + 'data' : { + 'message' : t('settings', 'Unable to change password') + } + } + ); + return false; + } + }); + + $('#pass2').strengthify({ + zxcvbn: OC.linkTo('core','vendor/zxcvbn/dist/zxcvbn.js'), + titles: [ + t('settings', 'Very weak password'), + t('settings', 'Weak password'), + t('settings', 'So-so password'), + t('settings', 'Good password'), + t('settings', 'Strong password') + ], + drawTitles: true, + $addAfter: $('input[name="newpassword-clone"]'), + }); +}); \ No newline at end of file diff --git a/settings/js/settings/personalInfo.js b/settings/js/settings/personalInfo.js index 2f7e1c386b57d..c9da3c6ebe8d8 100644 --- a/settings/js/settings/personalInfo.js +++ b/settings/js/settings/personalInfo.js @@ -145,67 +145,6 @@ $(document).ready(function () { $('#pass2').showPassword().keyup(); } - var removeloader = function () { - setTimeout(function(){ - if ($('.password-state').length > 0) { - $('.password-state').remove(); - } - }, 5000) - }; - - $("#passwordbutton").click(function () { - var isIE8or9 = $('html').hasClass('lte9'); - // FIXME - TODO - once support for IE8 and IE9 is dropped - // for IE8 and IE9 this will check additionally if the typed in password - // is different from the placeholder, because in IE8/9 the placeholder - // is simply set as the value to look like a placeholder - if ($('#pass1').val() !== '' && $('#pass2').val() !== '' - && !(isIE8or9 && $('#pass2').val() === $('#pass2').attr('placeholder'))) { - // Serialize the data - var post = $("#passwordform").serialize(); - $('#passwordchanged').hide(); - $('#passworderror').hide(); - $("#passwordbutton").attr('disabled', 'disabled'); - $("#passwordbutton").after(""); - $(".personal-show-label").hide(); - // Ajax foo - $.post(OC.generateUrl('/settings/personal/changepassword'), post, function (data) { - if (data.status === "success") { - $("#passwordbutton").after(""); - removeloader(); - $('#pass1').val(''); - $('#pass2').val('').change(); - } - if (typeof(data.data) !== "undefined") { - OC.msg.finishedSaving('#password-error-msg', data); - } else { - OC.msg.finishedSaving('#password-error-msg', - { - 'status' : 'error', - 'data' : { - 'message' : t('settings', 'Unable to change password') - } - } - ); - } - $(".personal-show-label").show(); - $(".password-loading").remove(); - $("#passwordbutton").removeAttr('disabled'); - }); - return false; - } else { - OC.msg.finishedSaving('#password-error-msg', - { - 'status' : 'error', - 'data' : { - 'message' : t('settings', 'Unable to change password') - } - } - ); - return false; - } - }); - var showVerifyDialog = function(dialog, howToVerify, verificationCode) { var dialogContent = dialog.children('.verification-dialog-content'); dialogContent.children(".explainVerification").text(howToVerify); @@ -417,19 +356,6 @@ $(document).ready(function () { sendCropData(); }); - $('#pass2').strengthify({ - zxcvbn: OC.linkTo('core','vendor/zxcvbn/dist/zxcvbn.js'), - titles: [ - t('settings', 'Very weak password'), - t('settings', 'Weak password'), - t('settings', 'So-so password'), - t('settings', 'Good password'), - t('settings', 'Strong password') - ], - drawTitles: true, - $addAfter: $('input[name="newpassword-clone"]'), - }); - // Load the big avatar var user = OC.getCurrentUser(); $('#avatarform .avatardiv').avatar(user.uid, 145, true, null, function() { diff --git a/settings/templates/settings/personal/personal.info.php b/settings/templates/settings/personal/personal.info.php index 1946e3ec66ed4..3e8f31cf07322 100644 --- a/settings/templates/settings/personal/personal.info.php +++ b/settings/templates/settings/personal/personal.info.php @@ -31,8 +31,6 @@ 'federationscopemenu', 'settings/personalInfo', ]); -vendor_script('strengthify/jquery.strengthify'); -vendor_style('strengthify/strengthify'); vendor_script('jcrop/js/jquery.Jcrop'); vendor_style('jcrop/css/jquery.Jcrop'); @@ -376,36 +374,6 @@ -
- -
-

t('Password'));?>

- - - - - -
- - - -
- - - -
- -
diff --git a/settings/templates/settings/personal/security.php b/settings/templates/settings/personal/security.php index 9b0d9b6e8d00b..e0de11de60e7f 100644 --- a/settings/templates/settings/personal/security.php +++ b/settings/templates/settings/personal/security.php @@ -22,14 +22,50 @@ */ script('settings', [ + 'security_password', 'authtoken', 'authtoken_collection', 'authtoken_view', 'settings/authtoken-init' ]); +if($_['passwordChangeSupported']) { + script('jquery-showpassword'); + vendor_script('strengthify/jquery.strengthify'); + vendor_style('strengthify/strengthify'); +} + ?> +
+

t('Password'));?>

+ +
+ +
+ + + +
+ + + +
+ + + +
+ +
+ +

t('Devices & sessions'));?>

From 77f0633e59b8eb9515538bcaa7a114cac99a2878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 29 Jun 2018 13:06:24 +0200 Subject: [PATCH 2/3] Fix tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- tests/lib/Settings/ManagerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index 15608b9b611a2..30a5b7bd1039e 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -219,7 +219,7 @@ public function testGetAdminSettings() { public function testGetPersonalSettings() { $this->assertEquals([ - 10 => [new Security()], + 10 => [new Security($this->userManager)], ], $this->manager->getPersonalSettings('security')); } } From 97c13debdcb701573f8dd0bc437eeb8df692ec0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Fri, 29 Jun 2018 13:31:47 +0200 Subject: [PATCH 3/3] Remove unneeded param from personal settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- lib/private/Settings/Personal/PersonalInfo.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/private/Settings/Personal/PersonalInfo.php b/lib/private/Settings/Personal/PersonalInfo.php index f4a8548e8f19e..8c1c8cb19b810 100644 --- a/lib/private/Settings/Personal/PersonalInfo.php +++ b/lib/private/Settings/Personal/PersonalInfo.php @@ -135,7 +135,6 @@ public function getForm() { 'twitterScope' => $userData[AccountManager::PROPERTY_TWITTER]['scope'], 'twitterVerification' => $userData[AccountManager::PROPERTY_TWITTER]['verified'], 'groups' => $this->getGroups($user), - 'passwordChangeSupported' => $user->canChangePassword(), ] + $messageParameters + $languageParameters + $localeParameters;