From bdbd284bb999146e61ef0704956dd814a892de8c Mon Sep 17 00:00:00 2001 From: Max Semenik Date: Thu, 5 Aug 2010 19:16:31 +0000 Subject: [PATCH] JavaScript-based password complexity checker on account creation and password change. Needs attention from CSS gurus to look decently. Note that OutputPage::addPasswordSecurity() doesn't check the enabling setting to make this code reusable by extensions who don't always want to follow core settings. --- RELEASE-NOTES | 3 ++- includes/DefaultSettings.php | 7 ++++++- includes/OutputPage.php | 16 ++++++++++++++++ includes/specials/SpecialResetpass.php | 20 +++++++++++--------- includes/specials/SpecialUserlogin.php | 4 ++++ includes/templates/Userlogin.php | 16 +++++++++++----- languages/messages/MessagesEn.php | 7 +++++++ maintenance/language/messages.inc | 7 +++++++ 8 files changed, 64 insertions(+), 16 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 7fc3fdc50f..56515d35cd 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -132,7 +132,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN ** (bug 1211) Subcategories, ordinary pages, and files now page separately. ** When several pages are given the same sort key, they sort by their names instead of randomly. -* (bug 23848) Add {{ARTICLEPATH}} Magic Word +* JavaScript-based password complexity checker on account creation and + password change. === Bug fixes in 1.17 === * (bug 17560) Half-broken deletion moved image files to deletion archive diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 9ba549efec..db553ffb21 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -1556,7 +1556,7 @@ $wgCacheEpoch = '20030516000000'; * to ensure that client-side caches do not keep obsolete copies of global * styles. */ -$wgStyleVersion = '299'; +$wgStyleVersion = '300'; /** * This will cache static pages for non-logged-in users to reduce @@ -5114,6 +5114,11 @@ $wgPoolCounterConf = null; */ $wgUploadMaintenance = false; +/** + * Enabes or disables JavaScript-based suggestions of password strength + */ +$wgLivePasswordStrengthChecks = true; + /** * For really cool vim folding this needs to be at the end: * vim: foldmarker=@{,@} foldmethod=marker diff --git a/includes/OutputPage.php b/includes/OutputPage.php index be9c459586..f9825ffa76 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -1955,6 +1955,22 @@ class OutputPage { } } + public function addPasswordSecurity( $passwordId, $retypeId ) { + $data = array( + 'password' => '#' . $passwordId, + 'retype' => '#' . $retypeId, + 'messages' => array(), + ); + foreach ( array( 'password-strength', 'password-strength-bad', 'password-strength-mediocre', + 'password-strength-acceptable', 'password-strength-good', 'password-retype', 'password-retype-mismatch' + ) as $message ) { + $data['messages'][$message] = wfMsg( $message ); + } + $this->addScript( Html::inlineScript( 'var passwordSecurity=' . FormatJSON::encode( $data ) ) ); + $this->addScriptFile( 'password.js' ); + $this->addStyle( 'common/password.css' ); + } + /** @deprecated */ public function errorpage( $title, $msg ) { wfDeprecated( __METHOD__ ); diff --git a/includes/specials/SpecialResetpass.php b/includes/specials/SpecialResetpass.php index 972341e27d..de832d2efb 100644 --- a/includes/specials/SpecialResetpass.php +++ b/includes/specials/SpecialResetpass.php @@ -106,8 +106,11 @@ class SpecialResetpass extends SpecialPage { } function showForm() { - global $wgOut, $wgUser, $wgRequest; + global $wgOut, $wgUser, $wgRequest, $wgLivePasswordStrengthChecks; + if ( $wgLivePasswordStrengthChecks ) { + $wgOut->addPasswordSecurity( 'wpNewPassword', 'wpRetype' ); + } $self = $this->getTitle(); if ( !$this->mUserName ) { $this->mUserName = $wgUser->getName(); @@ -143,10 +146,10 @@ class SpecialResetpass extends SpecialPage { wfMsgExt( 'resetpass_text', array( 'parse' ) ) . "\n" . Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" . $this->pretty( array( - array( 'wpName', 'username', 'text', $this->mUserName ), - array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ), - array( 'wpNewPassword', 'newpassword', 'password', null ), - array( 'wpRetype', 'retypenew', 'password', null ), + array( 'wpName', 'username', 'text', $this->mUserName, '' ), + array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass, '' ), + array( 'wpNewPassword', 'newpassword', 'password', null, '
' ), + array( 'wpRetype', 'retypenew', 'password', null, '
' ), ) ) . "\n" . $rememberMe . "\n" . @@ -165,7 +168,7 @@ class SpecialResetpass extends SpecialPage { function pretty( $fields ) { $out = ''; foreach ( $fields as $list ) { - list( $name, $label, $type, $value ) = $list; + list( $name, $label, $type, $value, $extra ) = $list; if( $type == 'text' ) { $field = htmlspecialchars( $value ); } else { @@ -186,9 +189,8 @@ class SpecialResetpass extends SpecialPage { else $out .= wfMsgHtml( $label ); $out .= "\n"; - $out .= "\t"; - $out .= $field; - $out .= "\n"; + $out .= "\t$field\n"; + $out .= "\t$extra\n"; $out .= ""; } return $out; diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php index f051110a92..d8d35dd92c 100644 --- a/includes/specials/SpecialUserlogin.php +++ b/includes/specials/SpecialUserlogin.php @@ -968,6 +968,10 @@ class LoginForm { $titleObj = SpecialPage::getTitleFor( 'Userlogin' ); if ( $this->mType == 'signup' ) { + global $wgLivePasswordStrengthChecks; + if ( $wgLivePasswordStrengthChecks ) { + $wgOut->addPasswordSecurity( 'wpPassword2', 'wpRetype' ); + } $template = new UsercreateTemplate(); $q = 'action=submitlogin&type=signup'; $linkq = 'type=login'; diff --git a/includes/templates/Userlogin.php b/includes/templates/Userlogin.php index a36fa2c533..7693223fee 100644 --- a/includes/templates/Userlogin.php +++ b/includes/templates/Userlogin.php @@ -169,6 +169,7 @@ class UsercreateTemplate extends QuickTemplate { 'autofocus' ) ); ?> + @@ -181,6 +182,7 @@ class UsercreateTemplate extends QuickTemplate { 'size' => '20' ) + User::passwordChangeInputAttribs() ); ?> +
data['usedomain'] ) { $doms = ""; @@ -196,6 +198,7 @@ class UsercreateTemplate extends QuickTemplate { + @@ -209,6 +212,7 @@ class UsercreateTemplate extends QuickTemplate { 'size' => '20' ) + User::passwordChangeInputAttribs() ); ?> +
data['useemail'] ) { ?> @@ -229,12 +233,13 @@ class UsercreateTemplate extends QuickTemplate { } ?> + data['userealname'] ) { ?> - + @@ -242,12 +247,13 @@ class UsercreateTemplate extends QuickTemplate { msgWiki('prefs-help-realname'); ?> + data['usereason'] ) { ?> - + @@ -257,7 +263,7 @@ class UsercreateTemplate extends QuickTemplate { data['canremember'] ) { ?> - + - + - + diff --git a/languages/messages/MessagesEn.php b/languages/messages/MessagesEn.php index 35cabc3482..e2f845f036 100644 --- a/languages/messages/MessagesEn.php +++ b/languages/messages/MessagesEn.php @@ -1145,6 +1145,13 @@ Please wait before trying again.', * Italiano|it * Nederlands|nl', # do not translate or duplicate this message to other languages 'suspicious-userlogout' => 'Your request to log out was denied because it looks like it was sent by a broken browser or caching proxy.', +'password-strength' => 'Estimated password strength: $1', +'password-strength-bad' => 'BAD', +'password-strength-mediocre' => 'mediocre', +'password-strength-acceptable' => 'acceptable', +'password-strength-good' => 'good', +'password-retype' => 'Retype password here', +'password-retype-mismatch' => 'Passwords don\'t match', # Password reset dialog 'resetpass' => 'Change password', diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index 9754f698a6..eca9d5c6c7 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -466,6 +466,13 @@ $wgMessageStructure = array( 'loginlanguagelabel', 'loginlanguagelinks', 'suspicious-userlogout', + 'password-strength', + 'password-strength-bad', + 'password-strength-mediocre', + 'password-strength-acceptable', + 'password-strength-good', + 'password-retype', + 'password-retype-mismatch', ), 'resetpass' => array( 'resetpass', -- 2.20.1