Index: trunk/phase3/maintenance/language/messages.inc |
— | — | @@ -466,6 +466,13 @@ |
467 | 467 | 'loginlanguagelabel', |
468 | 468 | 'loginlanguagelinks', |
469 | 469 | 'suspicious-userlogout', |
| 470 | + 'password-strength', |
| 471 | + 'password-strength-bad', |
| 472 | + 'password-strength-mediocre', |
| 473 | + 'password-strength-acceptable', |
| 474 | + 'password-strength-good', |
| 475 | + 'password-retype', |
| 476 | + 'password-retype-mismatch', |
470 | 477 | ), |
471 | 478 | 'resetpass' => array( |
472 | 479 | 'resetpass', |
Index: trunk/phase3/includes/OutputPage.php |
— | — | @@ -1955,6 +1955,22 @@ |
1956 | 1956 | } |
1957 | 1957 | } |
1958 | 1958 | |
| 1959 | + public function addPasswordSecurity( $passwordId, $retypeId ) { |
| 1960 | + $data = array( |
| 1961 | + 'password' => '#' . $passwordId, |
| 1962 | + 'retype' => '#' . $retypeId, |
| 1963 | + 'messages' => array(), |
| 1964 | + ); |
| 1965 | + foreach ( array( 'password-strength', 'password-strength-bad', 'password-strength-mediocre', |
| 1966 | + 'password-strength-acceptable', 'password-strength-good', 'password-retype', 'password-retype-mismatch' |
| 1967 | + ) as $message ) { |
| 1968 | + $data['messages'][$message] = wfMsg( $message ); |
| 1969 | + } |
| 1970 | + $this->addScript( Html::inlineScript( 'var passwordSecurity=' . FormatJSON::encode( $data ) ) ); |
| 1971 | + $this->addScriptFile( 'password.js' ); |
| 1972 | + $this->addStyle( 'common/password.css' ); |
| 1973 | + } |
| 1974 | + |
1959 | 1975 | /** @deprecated */ |
1960 | 1976 | public function errorpage( $title, $msg ) { |
1961 | 1977 | wfDeprecated( __METHOD__ ); |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -1556,7 +1556,7 @@ |
1557 | 1557 | * to ensure that client-side caches do not keep obsolete copies of global |
1558 | 1558 | * styles. |
1559 | 1559 | */ |
1560 | | -$wgStyleVersion = '299'; |
| 1560 | +$wgStyleVersion = '300'; |
1561 | 1561 | |
1562 | 1562 | /** |
1563 | 1563 | * This will cache static pages for non-logged-in users to reduce |
— | — | @@ -5115,6 +5115,11 @@ |
5116 | 5116 | $wgUploadMaintenance = false; |
5117 | 5117 | |
5118 | 5118 | /** |
| 5119 | + * Enabes or disables JavaScript-based suggestions of password strength |
| 5120 | + */ |
| 5121 | +$wgLivePasswordStrengthChecks = true; |
| 5122 | + |
| 5123 | +/** |
5119 | 5124 | * For really cool vim folding this needs to be at the end: |
5120 | 5125 | * vim: foldmarker=@{,@} foldmethod=marker |
5121 | 5126 | * @} |
Index: trunk/phase3/includes/specials/SpecialUserlogin.php |
— | — | @@ -968,6 +968,10 @@ |
969 | 969 | $titleObj = SpecialPage::getTitleFor( 'Userlogin' ); |
970 | 970 | |
971 | 971 | if ( $this->mType == 'signup' ) { |
| 972 | + global $wgLivePasswordStrengthChecks; |
| 973 | + if ( $wgLivePasswordStrengthChecks ) { |
| 974 | + $wgOut->addPasswordSecurity( 'wpPassword2', 'wpRetype' ); |
| 975 | + } |
972 | 976 | $template = new UsercreateTemplate(); |
973 | 977 | $q = 'action=submitlogin&type=signup'; |
974 | 978 | $linkq = 'type=login'; |
Index: trunk/phase3/includes/specials/SpecialResetpass.php |
— | — | @@ -106,8 +106,11 @@ |
107 | 107 | } |
108 | 108 | |
109 | 109 | function showForm() { |
110 | | - global $wgOut, $wgUser, $wgRequest; |
| 110 | + global $wgOut, $wgUser, $wgRequest, $wgLivePasswordStrengthChecks; |
111 | 111 | |
| 112 | + if ( $wgLivePasswordStrengthChecks ) { |
| 113 | + $wgOut->addPasswordSecurity( 'wpNewPassword', 'wpRetype' ); |
| 114 | + } |
112 | 115 | $self = $this->getTitle(); |
113 | 116 | if ( !$this->mUserName ) { |
114 | 117 | $this->mUserName = $wgUser->getName(); |
— | — | @@ -143,10 +146,10 @@ |
144 | 147 | wfMsgExt( 'resetpass_text', array( 'parse' ) ) . "\n" . |
145 | 148 | Xml::openElement( 'table', array( 'id' => 'mw-resetpass-table' ) ) . "\n" . |
146 | 149 | $this->pretty( array( |
147 | | - array( 'wpName', 'username', 'text', $this->mUserName ), |
148 | | - array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass ), |
149 | | - array( 'wpNewPassword', 'newpassword', 'password', null ), |
150 | | - array( 'wpRetype', 'retypenew', 'password', null ), |
| 150 | + array( 'wpName', 'username', 'text', $this->mUserName, '' ), |
| 151 | + array( 'wpPassword', $oldpassMsg, 'password', $this->mOldpass, '' ), |
| 152 | + array( 'wpNewPassword', 'newpassword', 'password', null, '<div id="password-strength"></div>' ), |
| 153 | + array( 'wpRetype', 'retypenew', 'password', null, '<div id="password-retype"></div>' ), |
151 | 154 | ) ) . "\n" . |
152 | 155 | $rememberMe . |
153 | 156 | "<tr>\n" . |
— | — | @@ -165,7 +168,7 @@ |
166 | 169 | function pretty( $fields ) { |
167 | 170 | $out = ''; |
168 | 171 | foreach ( $fields as $list ) { |
169 | | - list( $name, $label, $type, $value ) = $list; |
| 172 | + list( $name, $label, $type, $value, $extra ) = $list; |
170 | 173 | if( $type == 'text' ) { |
171 | 174 | $field = htmlspecialchars( $value ); |
172 | 175 | } else { |
— | — | @@ -186,9 +189,8 @@ |
187 | 190 | else |
188 | 191 | $out .= wfMsgHtml( $label ); |
189 | 192 | $out .= "</td>\n"; |
190 | | - $out .= "\t<td class='mw-input'>"; |
191 | | - $out .= $field; |
192 | | - $out .= "</td>\n"; |
| 193 | + $out .= "\t<td class='mw-input'>$field</td>\n"; |
| 194 | + $out .= "\t<td>$extra</td>\n"; |
193 | 195 | $out .= "</tr>"; |
194 | 196 | } |
195 | 197 | return $out; |
Index: trunk/phase3/includes/templates/Userlogin.php |
— | — | @@ -169,6 +169,7 @@ |
170 | 170 | 'autofocus' |
171 | 171 | ) ); ?> |
172 | 172 | </td> |
| 173 | + <td></td> |
173 | 174 | </tr> |
174 | 175 | <tr> |
175 | 176 | <td class="mw-label"><label for='wpPassword2'><?php $this->msg('yourpassword') ?></label></td> |
— | — | @@ -181,6 +182,7 @@ |
182 | 183 | 'size' => '20' |
183 | 184 | ) + User::passwordChangeInputAttribs() ); ?> |
184 | 185 | </td> |
| 186 | + <td><div id="password-strength"></div></td> |
185 | 187 | </tr> |
186 | 188 | <?php if( $this->data['usedomain'] ) { |
187 | 189 | $doms = ""; |
— | — | @@ -196,6 +198,7 @@ |
197 | 199 | <?php echo $doms ?> |
198 | 200 | </select> |
199 | 201 | </td> |
| 202 | + <td></td> |
200 | 203 | </tr> |
201 | 204 | <?php } ?> |
202 | 205 | <tr> |
— | — | @@ -209,6 +212,7 @@ |
210 | 213 | 'size' => '20' |
211 | 214 | ) + User::passwordChangeInputAttribs() ); ?> |
212 | 215 | </td> |
| 216 | + <td><div id="password-retype"></div></td> |
213 | 217 | </tr> |
214 | 218 | <tr> |
215 | 219 | <?php if( $this->data['useemail'] ) { ?> |
— | — | @@ -229,12 +233,13 @@ |
230 | 234 | } ?> |
231 | 235 | </div> |
232 | 236 | </td> |
| 237 | + <td></td> |
233 | 238 | <?php } ?> |
234 | 239 | <?php if( $this->data['userealname'] ) { ?> |
235 | 240 | </tr> |
236 | 241 | <tr> |
237 | 242 | <td class="mw-label"><label for='wpRealName'><?php $this->msg('yourrealname') ?></label></td> |
238 | | - <td class="mw-input"> |
| 243 | + <td class="mw-input" colspan="2"> |
239 | 244 | <input type='text' class='loginText' name="wpRealName" id="wpRealName" |
240 | 245 | tabindex="6" |
241 | 246 | value="<?php $this->text('realname') ?>" size='20' /> |
— | — | @@ -242,12 +247,13 @@ |
243 | 248 | <?php $this->msgWiki('prefs-help-realname'); ?> |
244 | 249 | </div> |
245 | 250 | </td> |
| 251 | + <td></td> |
246 | 252 | <?php } ?> |
247 | 253 | <?php if( $this->data['usereason'] ) { ?> |
248 | 254 | </tr> |
249 | 255 | <tr> |
250 | 256 | <td class="mw-label"><label for='wpReason'><?php $this->msg('createaccountreason') ?></label></td> |
251 | | - <td class="mw-input"> |
| 257 | + <td class="mw-input" colspan="2"> |
252 | 258 | <input type='text' class='loginText' name="wpReason" id="wpReason" |
253 | 259 | tabindex="7" |
254 | 260 | value="<?php $this->text('reason') ?>" size='20' /> |
— | — | @@ -257,7 +263,7 @@ |
258 | 264 | <?php if( $this->data['canremember'] ) { ?> |
259 | 265 | <tr> |
260 | 266 | <td></td> |
261 | | - <td class="mw-input"> |
| 267 | + <td class="mw-input" colspan="2"> |
262 | 268 | <?php |
263 | 269 | global $wgCookieExpiration, $wgLang; |
264 | 270 | echo Xml::checkLabel( |
— | — | @@ -285,7 +291,7 @@ |
286 | 292 | ?><td><?php |
287 | 293 | } |
288 | 294 | ?></td> |
289 | | - <td class="mw-input"> |
| 295 | + <td class="mw-input" colspan="2"> |
290 | 296 | <input type="<?php echo htmlspecialchars( $inputItem['type'] ) ?>" name="<?php |
291 | 297 | echo htmlspecialchars( $inputItem['name'] ); ?>" |
292 | 298 | tabindex="<?php echo $tabIndex++; ?>" |
— | — | @@ -320,7 +326,7 @@ |
321 | 327 | ?> |
322 | 328 | <tr> |
323 | 329 | <td></td> |
324 | | - <td class="mw-submit"> |
| 330 | + <td class="mw-submit" colspan="2"> |
325 | 331 | <input type='submit' name="wpCreateaccount" id="wpCreateaccount" |
326 | 332 | tabindex="<?php echo $tabIndex++; ?>" |
327 | 333 | value="<?php $this->msg('createaccount') ?>" /> |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1145,6 +1145,13 @@ |
1146 | 1146 | * Italiano|it |
1147 | 1147 | * Nederlands|nl', # do not translate or duplicate this message to other languages |
1148 | 1148 | 'suspicious-userlogout' => 'Your request to log out was denied because it looks like it was sent by a broken browser or caching proxy.', |
| 1149 | +'password-strength' => 'Estimated password strength: $1', |
| 1150 | +'password-strength-bad' => 'BAD', |
| 1151 | +'password-strength-mediocre' => 'mediocre', |
| 1152 | +'password-strength-acceptable' => 'acceptable', |
| 1153 | +'password-strength-good' => 'good', |
| 1154 | +'password-retype' => 'Retype password here', |
| 1155 | +'password-retype-mismatch' => 'Passwords don\'t match', |
1149 | 1156 | |
1150 | 1157 | # Password reset dialog |
1151 | 1158 | 'resetpass' => 'Change password', |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -132,7 +132,8 @@ |
133 | 133 | ** (bug 1211) Subcategories, ordinary pages, and files now page separately. |
134 | 134 | ** When several pages are given the same sort key, they sort by their names |
135 | 135 | instead of randomly. |
136 | | -* (bug 23848) Add {{ARTICLEPATH}} Magic Word |
| 136 | +* JavaScript-based password complexity checker on account creation and |
| 137 | + password change. |
137 | 138 | |
138 | 139 | === Bug fixes in 1.17 === |
139 | 140 | * (bug 17560) Half-broken deletion moved image files to deletion archive |