From 5c1a9f35f16a8a871bcef24a45478ac92af9a9e1 Mon Sep 17 00:00:00 2001
From: Morris Jobke <morris.jobke@gmail.com>
Date: Wed, 13 Mar 2013 11:03:52 +0100
Subject: [PATCH] Indicate password strength using strengthify

 * uses zxcvbn
 * outsourced to separate jquery plugin
 * async loading
 * hide strength meter if input is empty
 * feedback if user enters weakest password
 * fade in and out
 * show tipsy with strength
 * Opera 12, IE8-10, FF 23, Chromium 29
---
 3rdparty                        |  2 +-
 core/css/fixes.css              |  6 ++++++
 core/css/styles.css             | 17 ++++++++++++++++-
 core/js/setup.js                | 22 ++++++++++++++++------
 core/setup.php                  |  2 ++
 core/templates/installation.php |  1 +
 settings/css/settings.css       | 13 +++++++++++++
 settings/js/personal.js         | 12 ++++++++++++
 settings/personal.php           |  4 ++++
 settings/templates/personal.php |  2 ++
 10 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/3rdparty b/3rdparty
index 95ab25149c..faeedfcc05 160000
--- a/3rdparty
+++ b/3rdparty
@@ -1 +1 @@
-Subproject commit 95ab25149c4903650a1113c01ccb1732fb089f14
+Subproject commit faeedfcc0573868a2f0bde81f25a67a940c100ab
diff --git a/core/css/fixes.css b/core/css/fixes.css
index bec002b96b..4ee854adde 100644
--- a/core/css/fixes.css
+++ b/core/css/fixes.css
@@ -63,3 +63,9 @@
 .ie8 #nojavascript {
 	filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#4c320000', endColorstr='#4c320000'); /* IE */
 }
+
+/* IE8 doesn't have rounded corners, so the strengthify bar should be wider */
+.lte8 #body-login .strengthify-wrapper {
+	width: 271px;
+	left: 6px;
+}
diff --git a/core/css/styles.css b/core/css/styles.css
index df01456708..29fcdd4573 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -341,7 +341,7 @@ input[type="submit"].enabled {
 	margin-bottom: 20px;
 	text-align: left;
 }
-#body-login form #adminaccount { margin-bottom:5px; }
+#body-login form #adminaccount { margin-bottom:15px; }
 #body-login form fieldset legend, #datadirContent label {
 	width: 100%;
 	font-weight: bold;
@@ -361,6 +361,21 @@ input[type="submit"].enabled {
 	margin-left: -4px;
 }
 
+/* strengthify wrapper */
+#body-login .strengthify-wrapper {
+	display: inline-block;
+	position: relative;
+	left: 15px;
+	top: -21px;
+	width: 252px;
+}
+
+/* tipsy for the strengthify wrapper looks better with following font settings */
+#body-login .tipsy-inner {
+	font-weight: bold;
+	color: #ccc;
+}
+
 /* Icons for username and password fields to better recognize them */
 #adminlogin, #adminpass, #user, #password { width:11.7em!important; padding-left:1.8em; }
 #adminlogin+label+img, #adminpass-icon, #user+label+img, #password-icon {
diff --git a/core/js/setup.js b/core/js/setup.js
index 0863be3588..279b5fbebb 100644
--- a/core/js/setup.js
+++ b/core/js/setup.js
@@ -7,9 +7,9 @@ $(document).ready(function() {
 		oracle:!!$('#hasOracle').val(),
 		mssql:!!$('#hasMSSQL').val()
 	};
-	
+
 	$('#selectDbType').buttonset();
-	
+
 	if($('#hasSQLite').val()){
 		$('#use_other_db').hide();
 		$('#use_oracle_db').hide();
@@ -63,17 +63,27 @@ $(document).ready(function() {
 		form.submit();
 		return false;
 	});
-	
+
 	// Expand latest db settings if page was reloaded on error
 	var currentDbType = $('input[type="radio"]:checked').val();
-	
+
 	if (currentDbType === undefined){
 		$('input[type="radio"]').first().click();
 	}
-	
+
 	if (currentDbType === 'sqlite' || (dbtypes.sqlite && currentDbType === undefined)){
 		$('#datadirContent').hide(250);
 		$('#databaseField').hide(250);
 	}
-	
+
+	$('#adminpass').strengthify({
+		zxcvbn: OC.linkTo('3rdparty','zxcvbn/js/zxcvbn.js'),
+		titles: [
+			t('core', 'Very weak password'),
+			t('core', 'Weak password'),
+			t('core', 'So-so password'),
+			t('core', 'Good password'),
+			t('core', 'Strong password')
+		]
+	});
 });
diff --git a/core/setup.php b/core/setup.php
index 781d6e572a..958376b2cc 100644
--- a/core/setup.php
+++ b/core/setup.php
@@ -20,6 +20,8 @@ if ($dbIsSet AND $directoryIsSet AND $adminAccountIsSet) {
 	}
 }
 
+OC_Util::addScript( '3rdparty', 'strengthify/jquery.strengthify' );
+OC_Util::addStyle( '3rdparty', 'strengthify/strengthify' );
 OC_Util::addScript('setup');
 
 $hasSQLite = class_exists('SQLite3');
diff --git a/core/templates/installation.php b/core/templates/installation.php
index ec55a65ea5..182fc83a4d 100644
--- a/core/templates/installation.php
+++ b/core/templates/installation.php
@@ -59,6 +59,7 @@
 			<img class="svg" id="adminpass-icon" src="<?php print_unescaped(image_path('', 'actions/password.svg')); ?>" alt="" />
 			<input type="checkbox" id="show" name="show" />
 			<label for="show"></label>
+			<div class="strengthify-wrapper"></div>
 		</p>
 	</fieldset>
 
diff --git a/settings/css/settings.css b/settings/css/settings.css
index 2e464c3f11..a93c675d46 100644
--- a/settings/css/settings.css
+++ b/settings/css/settings.css
@@ -147,3 +147,16 @@ table.shareAPI td { padding-bottom: 0.8em; }
 /* HELP */
 .pressed {background-color:#DDD;}
 
+/* PASSWORD */
+.strengthify-wrapper {
+	position: absolute;
+	left: 189px;
+	width: 131px;
+	margin-top: -7px;
+}
+
+/* OPERA hack for strengthify*/
+doesnotexist:-o-prefocus, .strengthify-wrapper {
+	left: 185px;
+	width: 129px;
+}
diff --git a/settings/js/personal.js b/settings/js/personal.js
index 2934677f25..591eb8abe2 100644
--- a/settings/js/personal.js
+++ b/settings/js/personal.js
@@ -1,5 +1,6 @@
 /**
  * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
+ *               2013, Morris Jobke <morris.jobke@gmail.com>
  * This file is licensed under the Affero General Public License version 3 or later.
  * See the COPYING-README file.
  */
@@ -243,6 +244,17 @@ $(document).ready(function(){
 	$('#sendcropperbutton').click(function(){
 		sendCropData();
 	});
+
+	$('#pass2').strengthify({
+		zxcvbn: OC.linkTo('3rdparty','zxcvbn/js/zxcvbn.js'),
+		titles: [
+			t('core', 'Very weak password'),
+			t('core', 'Weak password'),
+			t('core', 'So-so password'),
+			t('core', 'Good password'),
+			t('core', 'Strong password')
+		]
+	});
 } );
 
 OC.Encryption = {
diff --git a/settings/personal.php b/settings/personal.php
index 44e1048941..cf1a496bdf 100644
--- a/settings/personal.php
+++ b/settings/personal.php
@@ -13,6 +13,8 @@ $defaults = new OC_Defaults(); // initialize themable default strings and urls
 // Highlight navigation entry
 OC_Util::addScript( 'settings', 'personal' );
 OC_Util::addStyle( 'settings', 'settings' );
+OC_Util::addScript( '3rdparty', 'strengthify/jquery.strengthify' );
+OC_Util::addStyle( '3rdparty', 'strengthify/strengthify' );
 OC_Util::addScript( '3rdparty', 'chosen/chosen.jquery.min' );
 OC_Util::addStyle( '3rdparty', 'chosen' );
 \OC_Util::addScript('files', 'jquery.fileupload');
@@ -20,6 +22,8 @@ if (\OC_Config::getValue('enable_avatars', true) === true) {
 	\OC_Util::addScript('3rdparty/Jcrop', 'jquery.Jcrop.min');
 	\OC_Util::addStyle('3rdparty/Jcrop', 'jquery.Jcrop.min');
 }
+
+// Highlight navigation entry
 OC_App::setActiveNavigationEntry( 'personal' );
 
 $storageInfo=OC_Helper::getStorageInfo('/');
diff --git a/settings/templates/personal.php b/settings/templates/personal.php
index 3eb864655b..1518b48b97 100644
--- a/settings/templates/personal.php
+++ b/settings/templates/personal.php
@@ -44,6 +44,8 @@ if($_['passwordChangeSupported']) {
 			placeholder="<?php echo $l->t('New password');?>" data-typetoggle="#personal-show" />
 		<input type="checkbox" id="personal-show" name="show" /><label for="personal-show"></label>
 		<input id="passwordbutton" type="submit" value="<?php echo $l->t('Change password');?>" />
+		<br/>
+		<div class="strengthify-wrapper"></div>
 	</fieldset>
 </form>
 <?php
-- 
GitLab