}
}
- /**
- * Adds JS-based password security checker
- * @param $passwordId String ID of input box containing password
- * @param $retypeId String ID of input box containing retyped password
- * @return none
- */
- 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->addModules( 'mediawiki.legacy.password' );
- }
-
public function showFatalError( $message ) {
$this->setPageTitle( wfMsg( 'internalerror' ) );
$this->setRobotPolicy( 'noindex,nofollow' );
}
function showForm() {
- global $wgOut, $wgUser, $wgRequest, $wgLivePasswordStrengthChecks;
+ global $wgOut, $wgUser, $wgRequest;
- if ( $wgLivePasswordStrengthChecks ) {
- $wgOut->addPasswordSecurity( 'wpNewPassword', 'wpRetype' );
- }
$self = $this->getTitle();
if ( !$this->mUserName ) {
$this->mUserName = $wgUser->getName();
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, '<div id="password-strength"></div>' ),
- array( 'wpRetype', 'retypenew', 'password', null, '<div id="password-retype"></div>' ),
+ array( 'wpName', 'username', 'text', $this->mUserName ),
+ array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ),
+ array( 'wpNewPassword', 'newpassword', 'password', null ),
+ array( 'wpRetype', 'retypenew', 'password', null ),
) ) . "\n" .
$rememberMe .
"<tr>\n" .
function pretty( $fields ) {
$out = '';
foreach ( $fields as $list ) {
- list( $name, $label, $type, $value, $extra ) = $list;
+ list( $name, $label, $type, $value ) = $list;
if( $type == 'text' ) {
$field = htmlspecialchars( $value );
} else {
else
$out .= wfMsgHtml( $label );
$out .= "</td>\n";
- $out .= "\t<td class='mw-input'>$field</td>\n";
- $out .= "\t<td>$extra</td>\n";
+ $out .= "\t<td class='mw-input'>";
+ $out .= $field;
+ $out .= "</td>\n";
$out .= "</tr>";
}
return $out;
}
if ( $this->mType == 'signup' ) {
- global $wgLivePasswordStrengthChecks;
- if ( $wgLivePasswordStrengthChecks ) {
- $wgOut->addPasswordSecurity( 'wpPassword2', 'wpRetype' );
- }
$template = new UsercreateTemplate();
$q = 'action=submitlogin&type=signup';
$linkq = 'type=login';
'autofocus'
) ); ?>
</td>
- <td></td>
</tr>
<tr>
<td class="mw-label"><label for='wpPassword2'><?php $this->msg('yourpassword') ?></label></td>
'size' => '20'
) + User::passwordChangeInputAttribs() ); ?>
</td>
- <td><div id="password-strength"></div></td>
</tr>
<?php if( $this->data['usedomain'] ) {
$doms = "";
<?php echo $doms ?>
</select>
</td>
- <td></td>
</tr>
<?php } ?>
<tr>
'size' => '20'
) + User::passwordChangeInputAttribs() ); ?>
</td>
- <td><div id="password-retype"></div></td>
</tr>
<tr>
<?php if( $this->data['useemail'] ) { ?>
} ?>
</div>
</td>
- <td></td>
<?php } ?>
<?php if( $this->data['userealname'] ) { ?>
</tr>
<tr>
<td class="mw-label"><label for='wpRealName'><?php $this->msg('yourrealname') ?></label></td>
- <td class="mw-input" colspan="2">
+ <td class="mw-input">
<input type='text' class='loginText' name="wpRealName" id="wpRealName"
tabindex="6"
value="<?php $this->text('realname') ?>" size='20' />
<?php $this->msgWiki('prefs-help-realname'); ?>
</div>
</td>
- <td></td>
<?php } ?>
<?php if( $this->data['usereason'] ) { ?>
</tr>
<tr>
<td class="mw-label"><label for='wpReason'><?php $this->msg('createaccountreason') ?></label></td>
- <td class="mw-input" colspan="2">
+ <td class="mw-input">
<input type='text' class='loginText' name="wpReason" id="wpReason"
tabindex="7"
value="<?php $this->text('reason') ?>" size='20' />
<?php if( $this->data['canremember'] ) { ?>
<tr>
<td></td>
- <td class="mw-input" colspan="2">
+ <td class="mw-input">
<?php
global $wgCookieExpiration, $wgLang;
echo Xml::checkLabel(
?><td><?php
}
?></td>
- <td class="mw-input" colspan="2">
+ <td class="mw-input">
<input type="<?php echo htmlspecialchars( $inputItem['type'] ) ?>" name="<?php
echo htmlspecialchars( $inputItem['name'] ); ?>"
tabindex="<?php echo $tabIndex++; ?>"
?>
<tr>
<td></td>
- <td class="mw-submit" colspan="2">
+ <td class="mw-submit">
<input type='submit' name="wpCreateaccount" id="wpCreateaccount"
tabindex="<?php echo $tabIndex++; ?>"
value="<?php $this->msg('createaccount') ?>" />
'php-mail-error' => '$1', # do not translate or duplicate this message to other languages
'php-mail-error-unknown' => "Unknown error in PHP's mail() function",
-# JavaScript password checks
-'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 do not match',
-
# Password reset dialog
'resetpass' => 'Change password',
'resetpass_announce' => 'You logged in with a temporary e-mailed code.
'php-mail-error',
'php-mail-error-unknown',
),
- 'passwordstrength' => array(
- 'password-strength',
- 'password-strength-bad',
- 'password-strength-mediocre',
- 'password-strength-acceptable',
- 'password-strength-good',
- 'password-retype',
- 'password-retype-mismatch',
- ),
'resetpass' => array(
'resetpass',
'resetpass_announce',
'dependencies' => array( 'mediawiki.legacy.wikibits', 'jquery.client' ),
'messages' => array( 'search-mwsuggest-enabled', 'search-mwsuggest-disabled' ),
),
- 'mediawiki.legacy.password' => array(
- 'scripts' => 'common/password.js',
- 'remoteBasePath' => $GLOBALS['wgStylePath'],
- 'localBasePath' => "{$GLOBALS['IP']}/skins",
- 'styles' => 'common/password.css',
- 'dependencies' => 'mediawiki.legacy.wikibits',
- ),
'mediawiki.legacy.prefs' => array(
'scripts' => 'common/prefs.js',
'remoteBasePath' => $GLOBALS['wgStylePath'],
+++ /dev/null
-span.mw-password-bad {
- background: red;
- color: yellow;
- font-weight: bold;
-}
-
-.mw-password-mediocre {
- background: yellow;
-}
-
-.mw-password-acceptable {
- background: silver;
-}
-
-.mw-password-good {
- background: green;
-}
\ No newline at end of file
+++ /dev/null
-/**
- * Password strength checker
- * @license WTFPL 2.0
- * All scores are ranged approximately 0 (total disaster) - 100 (_looks_ great)
- * @todo Check for popular passwords and keyboard sequences (QWERTY, etc)
- */
-
-// Estimates how hard it would be to pick the password using brute force
-window.bruteForceComplexity = function( pwd ) {
- var score = pwd.length * 5;
-
- var regexes = [
- /[a-z]/,
- /[A-Z]/,
- /[0-9]/,
- /[-_;:\.,'"`~!@#$%\^&\*\(\)\[\]\{\} ]/
- ];
-
- var charClasses = 0;
- for ( var i=0; i< regexes.length; i++ ) {
- if ( pwd.match( regexes[i] ) ) {
- charClasses++;
- }
- }
-
- var matches = pwd.match( /[\x80-\uFFFF]/g );
- if ( matches ) {
- charClasses++;
-
- var s = matches.join( '' );
- // poor man's isUpper() and isLower()
- if ( s != s.toLowerCase() && s != s.toUpperCase() ) {
- charClasses++;
- }
- }
- score += ( charClasses - 1 ) * 10;
-
- return score;
-};
-
-// Calculates a penalty to brute force score due to character repetition
-window.repetitionAdjustment = function( pwd ) {
- var unique = '';
- for ( var i=0; i< pwd.length; i++ ) {
- if ( unique.indexOf( pwd[i] ) < 0 ) {
- unique += pwd[i];
- }
- }
- var ratio = pwd.length / unique.length - 0.4; // allow up to 40% repetition, reward for less, penalize for more
-
- return ratio * 10;
-};
-
-// Checks how many simple sequences ("abc", "321") are there in the password
-window.sequenceScore = function( pwd ) {
- pwd = pwd.concat( '\0' );
- var score = 100, sequence = 1;
- for ( var i = 1; i < pwd.length; i++ ) {
- if ( pwd.charCodeAt( i ) == pwd.charCodeAt(i - 1) + 1 ) {
- sequence++;
- } else {
- if ( sequence > 2 ) {
- score -= sequence * 7;
- }
- sequence = 1;
- }
- }
- for ( var i = 1; i < pwd.length; i++ ) {
- if ( pwd.charCodeAt( i ) == pwd.charCodeAt(i - 1) - 1 ) {
- sequence++;
- } else {
- if ( sequence > 2 ) {
- score -= Math.sqrt( sequence ) * 15;
- }
- sequence = 1;
- }
- }
- return score;
-};
-
-(function( $ ) {
- function passwordChanged() {
- retypeChanged();
- var pwd = $( passwordSecurity.password ).val();
- if ( pwd == '' ) {
- $( '#password-strength' ).html( '' );
- return;
- }
- if ( pwd.length > 100 ) pwd = pwd.slice( 0, 100 );
- var scores = [
- bruteForceComplexity( pwd ),
- repetitionAdjustment( pwd ),
- sequenceScore( pwd )
- ];
-
- var score = Math.min( scores[0] - scores[1], scores[2] );
- var result = 'good';
- if ( score < 40 ) {
- result = 'bad';
- } else if ( score < 60 ) {
- result = 'mediocre';
- } else if ( score < 80 ) {
- result = 'acceptable';
- }
- var message = '<span class="mw-password-' + result + '">' + passwordSecurity.messages['password-strength-' + result]
- + '</span>';
- $( '#password-strength' ).html(
- passwordSecurity.messages['password-strength'].replace( '$1', message )
- //+ scores
- );
- }
-
- function retypeChanged() {
- var pwd = $( passwordSecurity.password ).val();
- var retype = $( passwordSecurity.retype ).val();
- var message;
- if ( pwd == '' || pwd == retype ) {
- message = '';
- } else if ( retype == '' ) {
- message = passwordSecurity.messages['password-retype'];
- } else {
- message = passwordSecurity.messages['password-retype-mismatch'];
- }
- $( '#password-retype' ).html( message );
- }
-
- $( document ).ready( function() {
- $( passwordSecurity.password ).bind( 'keyup change', passwordChanged );
- $( passwordSecurity.retype ).bind( 'keyup change', retypeChanged );
- })
-})(jQuery);