|
1 <?php |
|
2 /* |
|
3 Plugin Name: Special user/login-related pages |
|
4 Plugin URI: http://enano.homelinux.org/ |
|
5 Description: Provides the pages Special:Login, Special:Logout, Special:Register, and Special:Preferences. |
|
6 Author: Dan Fuhry |
|
7 Version: 1.0 |
|
8 Author URI: http://enano.homelinux.org/ |
|
9 */ |
|
10 |
|
11 /* |
|
12 * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between |
|
13 * Version 1.0 release candidate 2 |
|
14 * Copyright (C) 2006-2007 Dan Fuhry |
|
15 * |
|
16 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License |
|
17 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
|
18 * |
|
19 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|
20 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
|
21 */ |
|
22 |
|
23 global $db, $session, $paths, $template, $plugins; // Common objects |
|
24 |
|
25 $plugins->attachHook('base_classes_initted', ' |
|
26 global $paths; |
|
27 $paths->add_page(Array( |
|
28 \'name\'=>\'Log in\', |
|
29 \'urlname\'=>\'Login\', |
|
30 \'namespace\'=>\'Special\', |
|
31 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
32 )); |
|
33 $paths->add_page(Array( |
|
34 \'name\'=>\'Log out\', |
|
35 \'urlname\'=>\'Logout\', |
|
36 \'namespace\'=>\'Special\', |
|
37 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
38 )); |
|
39 $paths->add_page(Array( |
|
40 \'name\'=>\'Register\', |
|
41 \'urlname\'=>\'Register\', |
|
42 \'namespace\'=>\'Special\', |
|
43 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
44 )); |
|
45 $paths->add_page(Array( |
|
46 \'name\'=>\'Edit Profile\', |
|
47 \'urlname\'=>\'Preferences\', |
|
48 \'namespace\'=>\'Special\', |
|
49 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
50 )); |
|
51 |
|
52 $paths->add_page(Array( |
|
53 \'name\'=>\'Contributions\', |
|
54 \'urlname\'=>\'Contributions\', |
|
55 \'namespace\'=>\'Special\', |
|
56 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
57 )); |
|
58 |
|
59 $paths->add_page(Array( |
|
60 \'name\'=>\'Change style\', |
|
61 \'urlname\'=>\'ChangeStyle\', |
|
62 \'namespace\'=>\'Special\', |
|
63 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
64 )); |
|
65 |
|
66 $paths->add_page(Array( |
|
67 \'name\'=>\'Activate user account\', |
|
68 \'urlname\'=>\'ActivateAccount\', |
|
69 \'namespace\'=>\'Special\', |
|
70 \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
71 )); |
|
72 |
|
73 $paths->add_page(Array( |
|
74 \'name\'=>\'Captcha\', |
|
75 \'urlname\'=>\'Captcha\', |
|
76 \'namespace\'=>\'Special\', |
|
77 \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
78 )); |
|
79 |
|
80 $paths->add_page(Array( |
|
81 \'name\'=>\'Forgot password\', |
|
82 \'urlname\'=>\'PasswordReset\', |
|
83 \'namespace\'=>\'Special\', |
|
84 \'special\'=>0,\'visible\'=>1,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
|
85 )); |
|
86 '); |
|
87 |
|
88 // function names are IMPORTANT!!! The name pattern is: page_<namespace ID>_<page URLname, without namespace> |
|
89 |
|
90 $__login_status = ''; |
|
91 |
|
92 function page_Special_Login() |
|
93 { |
|
94 global $db, $session, $paths, $template, $plugins; // Common objects |
|
95 global $__login_status; |
|
96 |
|
97 $pubkey = $session->rijndael_genkey(); |
|
98 $challenge = $session->dss_rand(); |
|
99 |
|
100 if ( isset($_GET['act']) && $_GET['act'] == 'getkey' ) |
|
101 { |
|
102 $response = Array( |
|
103 'key' => $pubkey, |
|
104 'challenge' => $challenge |
|
105 ); |
|
106 $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); |
|
107 $response = $json->encode($response); |
|
108 echo $response; |
|
109 return null; |
|
110 } |
|
111 |
|
112 $level = ( isset($_GET['level']) && in_array($_GET['level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) ) ? intval($_GET['level']) : USER_LEVEL_MEMBER; |
|
113 if ( isset($_POST['login']) ) |
|
114 { |
|
115 if ( in_array($_POST['auth_level'], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9') ) ) |
|
116 { |
|
117 $level = intval($_POST['auth_level']); |
|
118 } |
|
119 } |
|
120 |
|
121 if ( $level > USER_LEVEL_MEMBER && !$session->user_logged_in ) |
|
122 { |
|
123 $level = USER_LEVEL_MEMBER; |
|
124 } |
|
125 $template->header(); |
|
126 echo '<form action="'.makeUrl($paths->nslist['Special'].'Login').'" method="post" name="loginform" onsubmit="runEncryption();">'; |
|
127 $header = ( $level > USER_LEVEL_MEMBER ) ? 'Please re-enter your login details' : 'Please enter your username and password to log in.'; |
|
128 if ( isset($_POST['login']) ) |
|
129 { |
|
130 echo '<p>'.$__login_status.'</p>'; |
|
131 } |
|
132 if ( $p = $paths->getAllParams() ) |
|
133 { |
|
134 echo '<input type="hidden" name="return_to" value="'.$p.'" />'; |
|
135 } |
|
136 else if ( isset($_POST['login']) && isset($_POST['return_to']) ) |
|
137 { |
|
138 echo '<input type="hidden" name="return_to" value="'.htmlspecialchars($_POST['return_to']).'" />'; |
|
139 } |
|
140 ?> |
|
141 <div class="tblholder"> |
|
142 <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4"> |
|
143 <tr> |
|
144 <th colspan="3"><?php echo $header; ?></th> |
|
145 </tr> |
|
146 <tr> |
|
147 <td colspan="3" class="row1"> |
|
148 <?php |
|
149 if ( $level <= USER_LEVEL_MEMBER ) |
|
150 { |
|
151 echo '<p>Logging in enables you to use your preferences and access member information. If you don\'t have a username and password here, you can <a href="'.makeUrl($paths->nslist['Special'].'Register').'">create an account</a>.</p>'; |
|
152 } |
|
153 else |
|
154 { |
|
155 echo '<p>You are requesting that a sensitive operation be performed. To continue, please re-enter your password to confirm your identity.</p>'; |
|
156 } |
|
157 ?> |
|
158 </td> |
|
159 </tr> |
|
160 <tr> |
|
161 <td class="row2"> |
|
162 Username: |
|
163 </td> |
|
164 <td class="row1"> |
|
165 <input name="username" size="25" type="text" <?php |
|
166 if ( $level <= USER_LEVEL_MEMBER ) |
|
167 { |
|
168 echo 'tabindex="1" '; |
|
169 } |
|
170 if ( $session->user_logged_in ) |
|
171 { |
|
172 echo 'value="' . $session->username . '"'; |
|
173 } |
|
174 ?> /> |
|
175 </td> |
|
176 <?php if ( $level <= USER_LEVEL_MEMBER ) { ?> |
|
177 <td rowspan="2" class="row3"> |
|
178 <small>Forgot your password? <a href="<?php echo makeUrlNS('Special', 'PasswordReset'); ?>">No problem.</a><br /> |
|
179 Maybe you need to <a href="<?php echo makeUrlNS('Special', 'Register'); ?>">create an account</a>.</small> |
|
180 </td> |
|
181 <?php } ?> |
|
182 </tr> |
|
183 <tr> |
|
184 <td class="row2">Password:<br /></td><td class="row1"><input name="pass" size="25" type="password" tabindex="<?php echo ( $level <= USER_LEVEL_MEMBER ) ? '2' : '1'; ?>" /></td> |
|
185 </tr> |
|
186 <?php if ( $level <= USER_LEVEL_MEMBER ) { ?> |
|
187 <tr> |
|
188 <td class="row3" colspan="3"> |
|
189 <p><b>Important note regarding cryptography:</b> Some countries do not allow the import or use of cryptographic technology. If you live in one of the countries listed below, you should <a href="<?php if($p=$paths->getParam(0))$u='/'.$p;else $u='';echo makeUrl($paths->page.$u, 'level='.$level.'&use_crypt=0', true); ?>">log in without using encryption</a>.</p> |
|
190 <p>This restriction applies to the following countries: Belarus, China, India, Israel, Kazakhstan, Mongolia, Pakistan, Russia, Saudi Arabia, Singapore, Tunisia, Venezuela, and Vietnam.</p> |
|
191 </td> |
|
192 </tr> |
|
193 <?php } ?> |
|
194 <tr> |
|
195 <th colspan="3" style="text-align: center" class="subhead"><input type="submit" name="login" value="Log in" tabindex="3" /></th> |
|
196 </tr> |
|
197 </table> |
|
198 </div> |
|
199 <input type="hidden" name="challenge_data" value="<?php echo $challenge; ?>" /> |
|
200 <input type="hidden" name="use_crypt" value="no" /> |
|
201 <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" /> |
|
202 <input type="hidden" name="crypt_data" value="" /> |
|
203 <input type="hidden" name="auth_level" value="<?php echo (string)$level; ?>" /> |
|
204 </form> |
|
205 <?php |
|
206 echo $session->aes_javascript('loginform', 'pass', 'use_crypt', 'crypt_key', 'crypt_data', 'challenge_data'); |
|
207 ?> |
|
208 <?php |
|
209 $template->footer(); |
|
210 } |
|
211 |
|
212 function page_Special_Login_preloader() // adding _preloader to the end of the function name calls the function before $session and $paths setup routines are called |
|
213 { |
|
214 global $db, $session, $paths, $template, $plugins; // Common objects |
|
215 global $__login_status; |
|
216 if ( isset($_GET['act']) && $_GET['act'] == 'ajaxlogin' ) |
|
217 { |
|
218 $plugins->attachHook('login_password_reset', 'SpecialLogin_SendResponse_PasswordReset($row[\'user_id\'], $row[\'temp_password\']);'); |
|
219 $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); |
|
220 $data = $json->decode($_POST['params']); |
|
221 $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER; |
|
222 $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level); |
|
223 $session->start(); |
|
224 //echo "$result\n$session->sid_super"; |
|
225 //exit; |
|
226 if ( $result == 'success' ) |
|
227 { |
|
228 $response = Array( |
|
229 'result' => 'success', |
|
230 'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid ) |
|
231 ); |
|
232 } |
|
233 else |
|
234 { |
|
235 $response = Array( |
|
236 'result' => 'error', |
|
237 'error' => $result |
|
238 ); |
|
239 } |
|
240 $response = $json->encode($response); |
|
241 echo $response; |
|
242 $db->close(); |
|
243 exit; |
|
244 } |
|
245 if(isset($_POST['login'])) { |
|
246 if($_POST['use_crypt'] == 'yes') |
|
247 { |
|
248 $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level'])); |
|
249 } |
|
250 else |
|
251 { |
|
252 $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level'])); |
|
253 } |
|
254 $session->start(); |
|
255 $paths->init(); |
|
256 if($result == 'success') |
|
257 { |
|
258 $template->load_theme($session->theme, $session->style); |
|
259 if(isset($_POST['return_to'])) |
|
260 { |
|
261 $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to']; |
|
262 redirect( makeUrl($_POST['return_to']), 'Login successful', 'You have successfully logged into the '.getConfig('site_name').' site as "'.$session->username.'". Redirecting to ' . $name . '...' ); |
|
263 } |
|
264 else |
|
265 { |
|
266 $paths->main_page(); |
|
267 } |
|
268 } |
|
269 else |
|
270 { |
|
271 $GLOBALS['__login_status'] = $result; |
|
272 } |
|
273 } |
|
274 } |
|
275 |
|
276 function SpecialLogin_SendResponse_PasswordReset($user_id, $passkey) |
|
277 { |
|
278 $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); |
|
279 |
|
280 $response = Array( |
|
281 'result' => 'success_reset', |
|
282 'user_id' => $user_id, |
|
283 'temppass' => $passkey |
|
284 ); |
|
285 |
|
286 $response = $json->encode($response); |
|
287 echo $response; |
|
288 |
|
289 $db->close(); |
|
290 |
|
291 exit; |
|
292 } |
|
293 |
|
294 function page_Special_Logout() { |
|
295 global $db, $session, $paths, $template, $plugins; // Common objects |
|
296 $l = $session->logout(); |
|
297 if($l == 'success') $paths->main_page(); |
|
298 $template->header(); |
|
299 echo '<h3>An error occurred during the logout process.</h3><p>'.$l.'</p>'; |
|
300 $template->footer(); |
|
301 } |
|
302 |
|
303 function page_Special_Register() { |
|
304 global $db, $session, $paths, $template, $plugins; // Common objects |
|
305 if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in )) |
|
306 { |
|
307 $s = ($session->user_level >= USER_LEVEL_ADMIN) ? '<p>Oops...it seems that you <em>are</em> the administrator...hehe...you can also <a href="'.makeUrl($paths->page, 'IWannaPlayToo', true).'">force account registration to work</a>.</p>' : ''; |
|
308 die_friendly('Registration disabled', '<p>The administrator has disabled new user registration on this site.</p>' . $s); |
|
309 } |
|
310 if(isset($_POST['submit'])) { |
|
311 $captcharesult = $session->get_captcha($_POST['captchahash']); |
|
312 if($captcharesult != $_POST['captchacode']) |
|
313 $s = 'The confirmation code you entered was incorrect.'; |
|
314 else |
|
315 // CAPTCHA code was correct, create the account |
|
316 $s = $session->create_user($_POST['username'], $_POST['password'], $_POST['email'], $_POST['real_name']); |
|
317 if($s == 'success') |
|
318 { |
|
319 switch(getConfig('account_activation')) |
|
320 { |
|
321 case "none": |
|
322 default: |
|
323 $str = 'You may now <a href="'.makeUrlNS('Special', 'Login').'">log in</a> with the username and password that you created.'; |
|
324 break; |
|
325 case "user": |
|
326 $str = 'Because this site requires account activation, you have been sent an e-mail with further instructions. Please follow the instructions in that e-mail to continue your registration.'; |
|
327 break; |
|
328 case "admin": |
|
329 $str = 'Because this site requires administrative account activation, you cannot use your account at the moment. A notice has been sent to the site administration team that will alert them that your account has been created.'; |
|
330 break; |
|
331 } |
|
332 die_friendly('Registration successful', '<p>Thank you for registering, your user account has been created. '.$str.'</p>'); |
|
333 } |
|
334 } |
|
335 $template->header(); |
|
336 echo 'A user account enables you to have greater control over your browsing experience.'; |
|
337 $session->kill_captcha(); |
|
338 $captchacode = $session->make_captcha(); |
|
339 ?> |
|
340 <h3>Create a user account</h3> |
|
341 <form name="regform" action="<?php echo makeUrl($paths->page); ?>" method="post"> |
|
342 <div class="tblholder"> |
|
343 <table border="0" width="100%" cellspacing="1" cellpadding="4"> |
|
344 <tr><th class="subhead" colspan="3">Please tell us a little bit about yourself.</th></tr> |
|
345 <?php if(isset($_POST['submit'])) echo '<tr><td colspan="3" class="row2" style="color: red;">'.$s.'</td></tr>'; ?> |
|
346 <tr><td class="row1" style="width: 50%;">Preferred username:<span id="e_username"></span></td><td class="row1" style="width: 50%;"><input type="text" name="username" size="30" onkeyup="namegood = false; validateForm();" onblur="checkUsername();" /></td><td class="row1" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_username" /></td></tr> |
|
347 <tr><td class="row3" style="width: 50%;" rowspan="2">Password:<span id="e_password"></span></td><td class="row3" style="width: 50%;"><input type="password" name="password" size="30" onkeyup="validateForm();" /></td><td rowspan="2" class="row3" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_password" /></td></tr> |
|
348 <tr><td class="row3" style="width: 50%;"><input type="password" name="password_confirm" size="30" onkeyup="validateForm();" /> <small>Enter your password again to confirm.</small></td></tr> |
|
349 <tr><td class="row1" style="width: 50%;">E-mail address:<?php if(getConfig('account_activation')=='user') echo '<br /><small>An e-mail with an account activation key will be sent to this address, so please ensure that it is correct.</small></td>'; ?><td class="row1" style="width: 50%;"><input type="text" name="email" size="30" onkeyup="validateForm();" /></td><td class="row1" style="max-width: 24px;"><img alt="Good/bad icon" src="<?php echo scriptPath; ?>/images/bad.gif" id="s_email" /></td></tr> |
|
350 <tr><td class="row3" style="width: 50%;">Real name:<br /><small>Giving your real name is totally optional. If you choose to provide your real name, it will be used to provide attribution for any edits or contributions you may make to this site.</small><td class="row3" style="width: 50%;"><input type="text" name="real_name" size="30" /></td><td class="row3" style="max-width: 24px;"></td></tr> |
|
351 <tr><td class="row1" style="width: 50%;" rowspan="2">Visual confirmation<br /><small>Please enter the code shown in the image to the right into the text box. This process helps to ensure that this registration is not being performed by an automated bot. If the image to the right is illegible, you can <a href="#" onclick="regenCaptcha(); return false;">generate a new image</a>.<br /><br />If you are visually impaired or otherwise cannot read the text shown to the right, please contact the site management and they will create an account for you.</small></td><td colspan="2" class="row1"><img id="captchaimg" alt="CAPTCHA image" src="<?php echo makeUrlNS('Special', 'Captcha/'.$captchacode); ?>" /><span id="b_username"></span></td></tr> |
|
352 <tr><td class="row1" colspan="2">Code: <input name="captchacode" type="text" size="10" /><input type="hidden" name="captchahash" value="<?php echo $captchacode; ?>" /></td></tr> |
|
353 <tr><td class="row2" colspan="3" style="text-align: center;"><input type="submit" name="submit" value="Create my account" /></td></tr> |
|
354 </table> |
|
355 </div> |
|
356 </form> |
|
357 <script type="text/javascript"> |
|
358 // <![CDATA[ |
|
359 var namegood = false; |
|
360 function validateForm() |
|
361 { |
|
362 var frm = document.forms.regform; |
|
363 failed = false; |
|
364 |
|
365 // Username |
|
366 if(!namegood) |
|
367 { |
|
368 if(frm.username.value.match(/^([A-z0-9 \!@\-\(\)]+){2,}$/ig)) |
|
369 { |
|
370 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif'; |
|
371 document.getElementById('e_username').innerHTML = ''; // '<br /><small><b>Checking availability...</b></small>'; |
|
372 } else { |
|
373 failed = true; |
|
374 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
375 document.getElementById('e_username').innerHTML = '<br /><small>Your username must be at least two characters in length and may contain only alphanumeric characters (A-Z and 0-9), spaces, and the following characters: :, !, @, #, *.</small>'; |
|
376 } |
|
377 } |
|
378 document.getElementById('b_username').innerHTML = ''; |
|
379 if(hex_md5(frm.real_name.value) == 'fa8e397ae0f6cd5b0f90a3f48178cd7e') |
|
380 { |
|
381 document.getElementById('b_username').innerHTML = '<br /><br />Hey...I know you!<br /><img alt="" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Bill_Gates_2004_cr.jpg/220px-Bill_Gates_2004_cr.jpg" />'; |
|
382 } |
|
383 |
|
384 // Password |
|
385 if(frm.password.value.match(/^(.+){6,}$/ig) && frm.password_confirm.value.match(/^(.+){6,}$/ig) && frm.password.value == frm.password_confirm.value) |
|
386 { |
|
387 document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/good.gif'; |
|
388 document.getElementById('e_password').innerHTML = '<br /><small>The password you entered is valid.</small>'; |
|
389 } else { |
|
390 failed = true; |
|
391 if(frm.password.value.length < 6) |
|
392 document.getElementById('e_password').innerHTML = '<br /><small>Your password must be at least six characters in length.</small>'; |
|
393 else if(frm.password.value != frm.password_confirm.value) |
|
394 document.getElementById('e_password').innerHTML = '<br /><small>The passwords you entered do not match.</small>'; |
|
395 else |
|
396 document.getElementById('e_password').innerHTML = ''; |
|
397 document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
398 } |
|
399 |
|
400 // E-mail address |
|
401 if(frm.email.value.match(/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/)) |
|
402 { |
|
403 document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/good.gif'; |
|
404 } else { |
|
405 failed = true; |
|
406 document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
407 } |
|
408 if(failed) |
|
409 { |
|
410 frm.submit.disabled = 'disabled'; |
|
411 } else { |
|
412 frm.submit.disabled = false; |
|
413 } |
|
414 } |
|
415 function checkUsername() |
|
416 { |
|
417 var frm = document.forms.regform; |
|
418 |
|
419 if(!namegood) |
|
420 { |
|
421 if(frm.username.value.match(/^([A-z0-9 \.:\!@\#\*]+){2,}$/ig)) |
|
422 { |
|
423 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif'; |
|
424 document.getElementById('e_username').innerHTML = ''; |
|
425 } else { |
|
426 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
427 document.getElementById('e_username').innerHTML = '<br /><small>Your username must be at least two characters in length and may contain only alphanumeric characters (A-Z and 0-9), spaces, and the following characters: :, !, @, #, *.</small>'; |
|
428 return false; |
|
429 } |
|
430 } |
|
431 |
|
432 document.getElementById('e_username').innerHTML = '<br /><small><b>Checking availability...</b></small>'; |
|
433 ajaxGet('<?php echo scriptPath; ?>/ajax.php?title=null&_mode=checkusername&name='+escape(frm.username.value), function() { |
|
434 if(ajax.readyState == 4) |
|
435 if(ajax.responseText == 'good') |
|
436 { |
|
437 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/good.gif'; |
|
438 document.getElementById('e_username').innerHTML = '<br /><small><b>This username is available.</b></small>'; |
|
439 namegood = true; |
|
440 } else if(ajax.responseText == 'bad') { |
|
441 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
442 document.getElementById('e_username').innerHTML = '<br /><small><b>Error: that username is already taken.</b></small>'; |
|
443 namegood = false; |
|
444 } else { |
|
445 document.getElementById('e_username').innerHTML = ajax.responseText; |
|
446 } |
|
447 }); |
|
448 } |
|
449 function regenCaptcha() |
|
450 { |
|
451 var frm = document.forms.regform; |
|
452 document.getElementById('captchaimg').src = '<?php echo makeUrlNS("Special", "Captcha/"); ?>'+frm.captchahash.value+'/'+Math.floor(Math.random() * 100000); |
|
453 return false; |
|
454 } |
|
455 validateForm(); |
|
456 setTimeout('checkUsername();', 1000); |
|
457 // ]]> |
|
458 </script> |
|
459 <?php |
|
460 $template->footer(); |
|
461 } |
|
462 |
|
463 /* |
|
464 If you want the old preferences page back, be my guest. |
|
465 function page_Special_Preferences() { |
|
466 global $db, $session, $paths, $template, $plugins; // Common objects |
|
467 $template->header(); |
|
468 if(isset($_POST['submit'])) { |
|
469 $data = $session->update_user($session->user_id, $_POST['username'], $_POST['current_pass'], $_POST['new_pass'], $_POST['email'], $_POST['real_name'], $_POST['sig']); |
|
470 if($data == 'success') echo '<h3>Information</h3><p>Your profile has been updated. <a href="'.scriptPath.'/">Return to the index page</a>.</p>'; |
|
471 else echo $data; |
|
472 } else { |
|
473 echo ' |
|
474 <h3>Edit your profile</h3> |
|
475 <form action="'.makeUrl($paths->nslist['Special'].'Preferences').'" method="post"> |
|
476 <table border="0" style="margin-left: 0.2in;"> |
|
477 <tr><td>Username:</td><td><input type="text" name="username" value="'.$session->username.'" /></td></tr> |
|
478 <tr><td>Current Password:</td><td><input type="password" name="current_pass" /></td></tr> |
|
479 <tr><td colspan="2"><small>You only need to enter your current password if you are changing your e-mail address or changing your password.</small></td></tr> |
|
480 <tr><td>New Password:</td><td><input type="password" name="new_pass" /></td></tr> |
|
481 <tr><td>E-mail:</td><td><input type="text" name="email" value="'.$session->email.'" /></td></tr> |
|
482 <tr><td>Real Name:</td><td><input type="text" name="real_name" value="'.$session->real_name.'" /></td></tr> |
|
483 <tr><td>Signature:<br /><small>Your signature appears<br />below your comment posts.</small></td><td><textarea rows="10" cols="40" name="sig">'.$session->signature.'</textarea></td></tr> |
|
484 <tr><td colspan="2"> |
|
485 <input type="submit" name="submit" value="Save Changes" /></td></tr> |
|
486 </table> |
|
487 </form> |
|
488 '; |
|
489 } |
|
490 $template->footer(); |
|
491 } |
|
492 */ |
|
493 |
|
494 function page_Special_Contributions() { |
|
495 global $db, $session, $paths, $template, $plugins; // Common objects |
|
496 $template->header(); |
|
497 $user = $paths->getParam(); |
|
498 if(!$user && isset($_GET['user'])) |
|
499 { |
|
500 $user = $_GET['user']; |
|
501 } |
|
502 elseif(!$user && !isset($_GET['user'])) |
|
503 { |
|
504 echo 'No user selected!'; |
|
505 $template->footer(); |
|
506 $db->close(); |
|
507 exit; |
|
508 } |
|
509 |
|
510 $user = $db->escape($user); |
|
511 |
|
512 $q = 'SELECT time_id,date_string,page_id,namespace,author,edit_summary,minor_edit,page_id,namespace FROM '.table_prefix.'logs WHERE author=\''.$user.'\' AND action=\'edit\' ORDER BY time_id DESC;'; |
|
513 if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.'); |
|
514 echo 'History of edits and actions<h3>Edits:</h3>'; |
|
515 if($db->numrows() < 1) echo 'No history entries in this category.'; |
|
516 while($r = $db->fetchrow()) { |
|
517 echo '<a href="#" onclick="ajaxHistView(\''.$r['time_id'].'\', \''.$paths->nslist[$r['namespace']].$r['page_id'].'\'); return false;"><i>'.$r['date_string'].'</i></a> (<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">revert</a>) <a href="'.makeUrl($paths->nslist[$r['namespace']].$r['page_id']).'">'.$paths->nslist[$r['namespace']].$r['page_id'].'</a>: '.$r['edit_summary']; |
|
518 if($r['minor_edit']) echo '<b> - minor edit</b>'; |
|
519 echo '<br />'; |
|
520 } |
|
521 $db->free_result(); |
|
522 echo '<h3>Other changes:</h3>'; |
|
523 $q = 'SELECT log_type,time_id,action,date_string,page_id,namespace,author,edit_summary,minor_edit,page_id,namespace FROM '.table_prefix.'logs WHERE author=\''.$user.'\' AND action!=\'edit\' ORDER BY time_id DESC;'; |
|
524 if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.'); |
|
525 if($db->numrows() < 1) echo 'No history entries in this category.'; |
|
526 while($r = $db->fetchrow()) { |
|
527 if($r['log_type']=='page') { |
|
528 echo '(<a href="#" onclick="ajaxRollback(\''.$r['time_id'].'\'); return false;">rollback</a>) <i>'.$r['date_string'].'</i> <a href="'.makeUrl($paths->nslist[$r['namespace']].$r['page_id']).'">'.$paths->nslist[$r['namespace']].$r['page_id'].'</a>: '; |
|
529 if($r['action']=='prot') echo 'Protected page; reason: '.$r['edit_summary']; |
|
530 elseif($r['action']=='unprot') echo 'Unprotected page; reason: '.$r['edit_summary']; |
|
531 elseif($r['action']=='rename') echo 'Renamed page; old title was: '.$r['edit_summary']; |
|
532 elseif($r['action']=='create') echo 'Created page'; |
|
533 elseif($r['action']=='delete') echo 'Deleted page'; |
|
534 if($r['minor_edit']) echo '<b> - minor edit</b>'; |
|
535 echo '<br />'; |
|
536 } elseif($r['log_type']=='security') { |
|
537 // Not implemented, and when it is, it won't be public |
|
538 } |
|
539 } |
|
540 $db->free_result(); |
|
541 $template->footer(); |
|
542 } |
|
543 |
|
544 function page_Special_ChangeStyle() |
|
545 { |
|
546 global $db, $session, $paths, $template, $plugins; // Common objects |
|
547 if(!$session->user_logged_in) die_friendly('Access denied', '<p>You must be logged in to change your style. Spoofer.</p>'); |
|
548 if(isset($_POST['theme']) && isset($_POST['style']) && isset($_POST['return_to'])) |
|
549 { |
|
550 $d = ENANO_ROOT . '/themes/' . $_POST['theme']; |
|
551 $f = ENANO_ROOT . '/themes/' . $_POST['theme'] . '/css/' . $_POST['style'] . '.css'; |
|
552 if(!file_exists($d) || !is_dir($d)) die('The directory "'.$d.'" does not exist.'); |
|
553 if(!file_exists($f)) die('The file "'.$f.'" does not exist.'); |
|
554 $d = $db->escape($_POST['theme']); |
|
555 $f = $db->escape($_POST['style']); |
|
556 $q = 'UPDATE '.table_prefix.'users SET theme=\''.$d.'\',style=\''.$f.'\' WHERE username=\''.$session->username.'\''; |
|
557 if(!$db->sql_query($q)) |
|
558 { |
|
559 $db->_die('Your theme/style preferences were not updated.'); |
|
560 } |
|
561 else |
|
562 { |
|
563 redirect(makeUrl($_POST['return_to']), '', '', 0); |
|
564 } |
|
565 } |
|
566 else |
|
567 { |
|
568 $template->header(); |
|
569 $ret = ( isset($_POST['return_to']) ) ? $_POST['return_to'] : $paths->getParam(0); |
|
570 if(!$ret) $ret = getConfig('main_page'); |
|
571 ?> |
|
572 <form action="<?php echo makeUrl($paths->page); ?>" method="post"> |
|
573 <?php if(!isset($_POST['themeselected'])) { ?> |
|
574 <h3>Please select a new theme:</h3> |
|
575 <p> |
|
576 <select name="theme"> |
|
577 <?php |
|
578 foreach($template->theme_list as $t) { |
|
579 if($t['enabled']) |
|
580 { |
|
581 echo '<option value="'.$t['theme_id'].'"'; |
|
582 if($t['theme_id'] == $session->theme) echo ' selected="selected"'; |
|
583 echo '>'.$t['theme_name'].'</option>'; |
|
584 } |
|
585 } |
|
586 ?> |
|
587 </select> |
|
588 </p> |
|
589 <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" /> |
|
590 <input type="submit" name="themeselected" value="Continue" /></p> |
|
591 <?php } else { |
|
592 $theme = $_POST['theme']; |
|
593 if ( !preg_match('/^([0-9A-z_-]+)$/i', $theme ) ) |
|
594 die('Hacking attempt'); |
|
595 ?> |
|
596 <h3>Please select a stylesheet:</h3> |
|
597 <p> |
|
598 <select name="style"> |
|
599 <?php |
|
600 $dir = './themes/'.$theme.'/css/'; |
|
601 $list = Array(); |
|
602 // Open a known directory, and proceed to read its contents |
|
603 if (is_dir($dir)) { |
|
604 if ($dh = opendir($dir)) { |
|
605 while (($file = readdir($dh)) !== false) { |
|
606 if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') { |
|
607 $list[] = substr($file, 0, strlen($file)-4); |
|
608 } |
|
609 } |
|
610 closedir($dh); |
|
611 } |
|
612 } else die($dir.' is not a dir'); |
|
613 foreach ( $list as $l ) |
|
614 { |
|
615 echo '<option value="'.$l.'">'.capitalize_first_letter($l).'</option>'; |
|
616 } |
|
617 ?> |
|
618 </select> |
|
619 </p> |
|
620 <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" /> |
|
621 <input type="hidden" name="theme" value="<?php echo $theme; ?>" /> |
|
622 <input type="submit" name="allclear" value="Change style" /></p> |
|
623 <?php } ?> |
|
624 </form> |
|
625 <?php |
|
626 $template->footer(); |
|
627 } |
|
628 } |
|
629 |
|
630 function page_Special_ActivateAccount() |
|
631 { |
|
632 global $db, $session, $paths, $template, $plugins; // Common objects |
|
633 $user = $paths->getParam(0); |
|
634 if(!$user) die_friendly('Account activation error', '<p>The URL was incorrect.</p>'); |
|
635 $key = $paths->getParam(1); |
|
636 if(!$key) die_friendly('Account activation error', '<p>The URL was incorrect.</p>'); |
|
637 $s = $session->activate_account(str_replace('_', ' ', $user), $key); |
|
638 if($s > 0) die_friendly('Activation successful', '<p>Your account is now active. Thank you for registering.</p>'); |
|
639 else die_friendly('Activation failed', '<p>The activation key was probably incorrect.</p>'); |
|
640 } |
|
641 |
|
642 function page_Special_Captcha() |
|
643 { |
|
644 global $db, $session, $paths, $template, $plugins; // Common objects |
|
645 if($paths->getParam(0) == 'make') |
|
646 { |
|
647 $session->kill_captcha(); |
|
648 echo $session->make_captcha(); |
|
649 return; |
|
650 } |
|
651 $hash = $paths->getParam(0); |
|
652 if(!$hash || !preg_match('#^([0-9a-f]*){32,32}$#i', $hash)) $paths->main_page(); |
|
653 $code = $session->get_captcha($hash); |
|
654 if(!$code) die('Invalid hash or IP address incorrect.'); |
|
655 require(ENANO_ROOT.'/includes/captcha.php'); |
|
656 $captcha = new captcha($code); |
|
657 //header('Content-disposition: attachment; filename=autocaptcha.png'); |
|
658 $captcha->make_image(); |
|
659 exit; |
|
660 } |
|
661 |
|
662 function page_Special_PasswordReset() |
|
663 { |
|
664 global $db, $session, $paths, $template, $plugins; // Common objects |
|
665 $template->header(); |
|
666 if($paths->getParam(0) == 'stage2') |
|
667 { |
|
668 $user_id = intval($paths->getParam(1)); |
|
669 $encpass = $paths->getParam(2); |
|
670 if ( $user_id < 2 ) |
|
671 { |
|
672 echo '<p>Hacking attempt</p>'; |
|
673 $template->footer(); |
|
674 return false; |
|
675 } |
|
676 if(!preg_match('#^([a-f0-9]+)$#i', $encpass)) |
|
677 { |
|
678 echo '<p>Hacking attempt</p>'; |
|
679 $template->footer(); |
|
680 return false; |
|
681 } |
|
682 |
|
683 $q = $db->sql_query('SELECT username,temp_password_time FROM '.table_prefix.'users WHERE user_id='.$user_id.' AND temp_password=\'' . $encpass . '\';'); |
|
684 if($db->numrows() < 1) |
|
685 { |
|
686 echo '<p>Invalid credentials</p>'; |
|
687 $template->footer(); |
|
688 return false; |
|
689 } |
|
690 $row = $db->fetchrow(); |
|
691 $db->free_result(); |
|
692 |
|
693 if ( ( intval($row['temp_password_time']) + 3600 * 24 ) < time() ) |
|
694 { |
|
695 echo '<p>Password has expired</p>'; |
|
696 $template->footer(); |
|
697 return false; |
|
698 } |
|
699 |
|
700 if ( isset($_POST['do_stage2']) ) |
|
701 { |
|
702 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
703 if($_POST['use_crypt'] == 'yes') |
|
704 { |
|
705 $crypt_key = $session->fetch_public_key($_POST['crypt_key']); |
|
706 if(!$crypt_key) |
|
707 { |
|
708 echo 'ERROR: Couldn\'t look up public key for decryption.'; |
|
709 $template->footer(); |
|
710 return false; |
|
711 } |
|
712 $crypt_key = hexdecode($crypt_key); |
|
713 $data = $aes->decrypt($_POST['crypt_data'], $crypt_key, ENC_HEX); |
|
714 if(strlen($data) < 6) |
|
715 { |
|
716 echo 'ERROR: Your password must be six characters or greater in length.'; |
|
717 $template->footer(); |
|
718 return false; |
|
719 } |
|
720 } |
|
721 else |
|
722 { |
|
723 $data = $_POST['pass']; |
|
724 $conf = $_POST['pass_confirm']; |
|
725 if($data != $conf) |
|
726 { |
|
727 echo 'ERROR: The passwords you entered do not match.'; |
|
728 $template->footer(); |
|
729 return false; |
|
730 } |
|
731 if(strlen($data) < 6) |
|
732 { |
|
733 echo 'ERROR: Your password must be six characters or greater in length.'; |
|
734 $template->footer(); |
|
735 return false; |
|
736 } |
|
737 } |
|
738 if(empty($data)) |
|
739 { |
|
740 echo 'ERROR: Sanity check failed!'; |
|
741 $template->footer(); |
|
742 return false; |
|
743 } |
|
744 $encpass = $aes->encrypt($data, $session->private_key, ENC_HEX); |
|
745 $q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $encpass . '\',temp_password=\'\',temp_password_time=0 WHERE user_id='.$user_id.';'); |
|
746 |
|
747 if($q) |
|
748 { |
|
749 $session->login_without_crypto($row['username'], $data); |
|
750 echo '<p>Your password has been reset. Return to the <a href="' . makeUrl(getConfig('main_page')) . '">main page</a>.</p>'; |
|
751 } |
|
752 else |
|
753 { |
|
754 echo $db->get_error(); |
|
755 } |
|
756 |
|
757 $template->footer(); |
|
758 return false; |
|
759 } |
|
760 |
|
761 // Password reset form |
|
762 $pubkey = $session->rijndael_genkey(); |
|
763 |
|
764 ?> |
|
765 <form action="<?php echo makeUrl($paths->fullpage); ?>" method="post" name="resetform" onsubmit="return runEncryption();"> |
|
766 <br /> |
|
767 <div class="tblholder"> |
|
768 <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4"> |
|
769 <tr><th colspan="2">Reset password</th></tr> |
|
770 <tr><td class="row1">Password:</td><td class="row1"><input name="pass" type="password" /></td></tr> |
|
771 <tr><td class="row2">Confirm: </td><td class="row2"><input name="pass_confirm" type="password" /></td></tr> |
|
772 <tr> |
|
773 <td colspan="2" class="row1" style="text-align: center;"> |
|
774 <input type="hidden" name="use_crypt" value="no" /> |
|
775 <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" /> |
|
776 <input type="hidden" name="crypt_data" value="" /> |
|
777 <input type="submit" name="do_stage2" value="Reset password" /> |
|
778 </td> |
|
779 </tr> |
|
780 </table> |
|
781 </div> |
|
782 </form> |
|
783 <script type="text/javascript"> |
|
784 disableJSONExts(); |
|
785 str = ''; |
|
786 for(i=0;i<keySizeInBits/4;i++) str+='0'; |
|
787 var key = hexToByteArray(str); |
|
788 var pt = hexToByteArray(str); |
|
789 var ct = rijndaelEncrypt(pt, key, "ECB"); |
|
790 var ct = byteArrayToHex(ct); |
|
791 switch(keySizeInBits) |
|
792 { |
|
793 case 128: |
|
794 v = '66e94bd4ef8a2c3b884cfa59ca342b2e'; |
|
795 break; |
|
796 case 192: |
|
797 v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7'; |
|
798 break; |
|
799 case 256: |
|
800 v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087'; |
|
801 break; |
|
802 } |
|
803 var testpassed = ( ct == v && md5_vm_test() ); |
|
804 var frm = document.forms.resetform; |
|
805 if(testpassed) |
|
806 { |
|
807 frm.use_crypt.value = 'yes'; |
|
808 var cryptkey = frm.crypt_key.value; |
|
809 frm.crypt_key.value = hex_md5(cryptkey); |
|
810 cryptkey = hexToByteArray(cryptkey); |
|
811 if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 ) |
|
812 { |
|
813 frm._login.disabled = true; |
|
814 len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : ''; |
|
815 alert('The key is messed up\nType: '+typeof(cryptkey)+len); |
|
816 } |
|
817 } |
|
818 function runEncryption() |
|
819 { |
|
820 pass1 = frm.pass.value; |
|
821 pass2 = frm.pass_confirm.value; |
|
822 if ( pass1 != pass2 ) |
|
823 { |
|
824 alert('The passwords you entered do not match.'); |
|
825 return false; |
|
826 } |
|
827 if ( pass1.length < 6 ) |
|
828 { |
|
829 alert('The new password must be 6 characters or greater in length.'); |
|
830 return false; |
|
831 } |
|
832 if(testpassed) |
|
833 { |
|
834 pass = frm.pass.value; |
|
835 pass = stringToByteArray(pass); |
|
836 cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB'); |
|
837 if(!cryptstring) |
|
838 { |
|
839 return false; |
|
840 } |
|
841 cryptstring = byteArrayToHex(cryptstring); |
|
842 frm.crypt_data.value = cryptstring; |
|
843 frm.pass.value = ""; |
|
844 frm.pass_confirm.value = ""; |
|
845 } |
|
846 return true; |
|
847 } |
|
848 </script> |
|
849 <?php |
|
850 $template->footer(); |
|
851 return true; |
|
852 } |
|
853 if(isset($_POST['do_reset'])) |
|
854 { |
|
855 if($session->mail_password_reset($_POST['username'])) |
|
856 { |
|
857 echo '<p>An e-mail has been sent to the e-mail address on file for your username with a new password in it. Please check your e-mail for further instructions.</p>'; |
|
858 } |
|
859 else |
|
860 { |
|
861 echo '<p>Error occured, your new password was not sent.</p>'; |
|
862 } |
|
863 $template->footer(); |
|
864 return true; |
|
865 } |
|
866 echo '<p>Don\'t worry, it happens to the best of us.</p> |
|
867 <p>To reset your password, just enter your username below, and a new password will be e-mailed to you.</p> |
|
868 <form action="'.makeUrl($paths->page).'" method="post" onsubmit="if(!submitAuthorized) return false;"> |
|
869 <p>Username: '.$template->username_field('username').'</p> |
|
870 <p><input type="submit" name="do_reset" value="Mail new password" /></p> |
|
871 </form>'; |
|
872 $template->footer(); |
|
873 } |
|
874 |
|
875 ?> |