|
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 $json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE); |
|
219 $data = $json->decode($_POST['params']); |
|
220 $level = ( isset($data['level']) ) ? intval($data['level']) : USER_LEVEL_MEMBER; |
|
221 $result = $session->login_with_crypto($data['username'], $data['crypt_data'], $data['crypt_key'], $data['challenge'], $level); |
|
222 $session->start(); |
|
223 //echo "$result\n$session->sid_super"; |
|
224 //exit; |
|
225 if ( $result == 'success' ) |
|
226 { |
|
227 $response = Array( |
|
228 'result' => 'success', |
|
229 'key' => $session->sid_super // ( ( $session->sid_super ) ? $session->sid_super : $session->sid ) |
|
230 ); |
|
231 } |
|
232 else |
|
233 { |
|
234 $response = Array( |
|
235 'result' => 'error', |
|
236 'error' => $result |
|
237 ); |
|
238 } |
|
239 $response = $json->encode($response); |
|
240 echo $response; |
|
241 $db->close(); |
|
242 exit; |
|
243 } |
|
244 if(isset($_POST['login'])) { |
|
245 if($_POST['use_crypt'] == 'yes') |
|
246 { |
|
247 $result = $session->login_with_crypto($_POST['username'], $_POST['crypt_data'], $_POST['crypt_key'], $_POST['challenge_data'], intval($_POST['auth_level'])); |
|
248 } |
|
249 else |
|
250 { |
|
251 $result = $session->login_without_crypto($_POST['username'], $_POST['pass'], false, intval($_POST['auth_level'])); |
|
252 } |
|
253 $session->start(); |
|
254 $paths->init(); |
|
255 if($result == 'success') |
|
256 { |
|
257 $template->load_theme($session->theme, $session->style); |
|
258 if(isset($_POST['return_to'])) |
|
259 { |
|
260 $name = ( isset($paths->pages[$_POST['return_to']]['name']) ) ? $paths->pages[$_POST['return_to']]['name'] : $_POST['return_to']; |
|
261 redirect( makeUrl($_POST['return_to']), 'Login successful', 'You have successfully logged into the '.getConfig('site_name').' site as "'.$session->username.'". Redirecting to ' . $name . '...' ); |
|
262 } |
|
263 else |
|
264 { |
|
265 $paths->main_page(); |
|
266 } |
|
267 } |
|
268 else |
|
269 { |
|
270 $GLOBALS['__login_status'] = $result; |
|
271 } |
|
272 } |
|
273 } |
|
274 |
|
275 function page_Special_Logout() { |
|
276 global $db, $session, $paths, $template, $plugins; // Common objects |
|
277 $l = $session->logout(); |
|
278 if($l == 'success') $paths->main_page(); |
|
279 $template->header(); |
|
280 echo '<h3>An error occurred during the logout process.</h3><p>'.$l.'</p>'; |
|
281 $template->footer(); |
|
282 } |
|
283 |
|
284 function page_Special_Register() { |
|
285 global $db, $session, $paths, $template, $plugins; // Common objects |
|
286 if(getConfig('account_activation') == 'disable' && ( ( $session->user_level >= USER_LEVEL_ADMIN && !isset($_GET['IWannaPlayToo']) ) || $session->user_level < USER_LEVEL_ADMIN || !$session->user_logged_in )) |
|
287 { |
|
288 $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>' : ''; |
|
289 die_friendly('Registration disabled', '<p>The administrator has disabled new user registration on this site.</p>' . $s); |
|
290 } |
|
291 if(isset($_POST['submit'])) { |
|
292 $captcharesult = $session->get_captcha($_POST['captchahash']); |
|
293 if($captcharesult != $_POST['captchacode']) |
|
294 $s = 'The confirmation code you entered was incorrect.'; |
|
295 else |
|
296 // CAPTCHA code was correct, create the account |
|
297 $s = $session->create_user($_POST['username'], $_POST['password'], $_POST['email'], $_POST['real_name']); |
|
298 if($s == 'success') |
|
299 { |
|
300 switch(getConfig('account_activation')) |
|
301 { |
|
302 case "none": |
|
303 default: |
|
304 $str = 'You may now <a href="'.makeUrlNS('Special', 'Login').'">log in</a> with the username and password that you created.'; |
|
305 break; |
|
306 case "user": |
|
307 $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.'; |
|
308 break; |
|
309 case "admin": |
|
310 $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.'; |
|
311 break; |
|
312 } |
|
313 die_friendly('Registration successful', '<p>Thank you for registering, your user account has been created. '.$str.'</p>'); |
|
314 } |
|
315 } |
|
316 $template->header(); |
|
317 echo 'A user account enables you to have greater control over your browsing experience.'; |
|
318 $session->kill_captcha(); |
|
319 $captchacode = $session->make_captcha(); |
|
320 ?> |
|
321 <h3>Create a user account</h3> |
|
322 <form name="regform" action="<?php echo makeUrl($paths->page); ?>" method="post"> |
|
323 <div class="tblholder"> |
|
324 <table border="0" width="100%" cellspacing="1" cellpadding="4"> |
|
325 <tr><th class="subhead" colspan="3">Please tell us a little bit about yourself.</th></tr> |
|
326 <?php if(isset($_POST['submit'])) echo '<tr><td colspan="3" class="row2" style="color: red;">'.$s.'</td></tr>'; ?> |
|
327 <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> |
|
328 <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> |
|
329 <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> |
|
330 <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> |
|
331 <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> |
|
332 <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> |
|
333 <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> |
|
334 <tr><td class="row2" colspan="3" style="text-align: center;"><input type="submit" name="submit" value="Create my account" /></td></tr> |
|
335 </table> |
|
336 </div> |
|
337 </form> |
|
338 <script type="text/javascript"> |
|
339 // <![CDATA[ |
|
340 var namegood = false; |
|
341 function validateForm() |
|
342 { |
|
343 var frm = document.forms.regform; |
|
344 failed = false; |
|
345 |
|
346 // Username |
|
347 if(!namegood) |
|
348 { |
|
349 if(frm.username.value.match(/^([A-z0-9 \!@\-\(\)]+){2,}$/ig)) |
|
350 { |
|
351 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif'; |
|
352 document.getElementById('e_username').innerHTML = ''; // '<br /><small><b>Checking availability...</b></small>'; |
|
353 } else { |
|
354 failed = true; |
|
355 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
356 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>'; |
|
357 } |
|
358 } |
|
359 document.getElementById('b_username').innerHTML = ''; |
|
360 if(hex_md5(frm.real_name.value) == 'fa8e397ae0f6cd5b0f90a3f48178cd7e') |
|
361 { |
|
362 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" />'; |
|
363 } |
|
364 |
|
365 // Password |
|
366 if(frm.password.value.match(/^(.+){6,}$/ig) && frm.password_confirm.value.match(/^(.+){6,}$/ig) && frm.password.value == frm.password_confirm.value) |
|
367 { |
|
368 document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/good.gif'; |
|
369 document.getElementById('e_password').innerHTML = '<br /><small>The password you entered is valid.</small>'; |
|
370 } else { |
|
371 failed = true; |
|
372 if(frm.password.value.length < 6) |
|
373 document.getElementById('e_password').innerHTML = '<br /><small>Your password must be at least six characters in length.</small>'; |
|
374 else if(frm.password.value != frm.password_confirm.value) |
|
375 document.getElementById('e_password').innerHTML = '<br /><small>The passwords you entered do not match.</small>'; |
|
376 else |
|
377 document.getElementById('e_password').innerHTML = ''; |
|
378 document.getElementById('s_password').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
379 } |
|
380 |
|
381 // E-mail address |
|
382 if(frm.email.value.match(/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/)) |
|
383 { |
|
384 document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/good.gif'; |
|
385 } else { |
|
386 failed = true; |
|
387 document.getElementById('s_email').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
388 } |
|
389 if(failed) |
|
390 { |
|
391 frm.submit.disabled = 'disabled'; |
|
392 } else { |
|
393 frm.submit.disabled = false; |
|
394 } |
|
395 } |
|
396 function checkUsername() |
|
397 { |
|
398 var frm = document.forms.regform; |
|
399 |
|
400 if(!namegood) |
|
401 { |
|
402 if(frm.username.value.match(/^([A-z0-9 \.:\!@\#\*]+){2,}$/ig)) |
|
403 { |
|
404 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/unknown.gif'; |
|
405 document.getElementById('e_username').innerHTML = ''; |
|
406 } else { |
|
407 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
408 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>'; |
|
409 return false; |
|
410 } |
|
411 } |
|
412 |
|
413 document.getElementById('e_username').innerHTML = '<br /><small><b>Checking availability...</b></small>'; |
|
414 ajaxGet('<?php echo scriptPath; ?>/ajax.php?title=null&_mode=checkusername&name='+escape(frm.username.value), function() { |
|
415 if(ajax.readyState == 4) |
|
416 if(ajax.responseText == 'good') |
|
417 { |
|
418 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/good.gif'; |
|
419 document.getElementById('e_username').innerHTML = '<br /><small><b>This username is available.</b></small>'; |
|
420 namegood = true; |
|
421 } else if(ajax.responseText == 'bad') { |
|
422 document.getElementById('s_username').src='<?php echo scriptPath; ?>/images/bad.gif'; |
|
423 document.getElementById('e_username').innerHTML = '<br /><small><b>Error: that username is already taken.</b></small>'; |
|
424 namegood = false; |
|
425 } else { |
|
426 document.getElementById('e_username').innerHTML = ajax.responseText; |
|
427 } |
|
428 }); |
|
429 } |
|
430 function regenCaptcha() |
|
431 { |
|
432 var frm = document.forms.regform; |
|
433 document.getElementById('captchaimg').src = '<?php echo makeUrlNS("Special", "Captcha/"); ?>'+frm.captchahash.value+'/'+Math.floor(Math.random() * 100000); |
|
434 return false; |
|
435 } |
|
436 validateForm(); |
|
437 setTimeout('checkUsername();', 1000); |
|
438 // ]]> |
|
439 </script> |
|
440 <?php |
|
441 $template->footer(); |
|
442 } |
|
443 |
|
444 /* |
|
445 If you want the old preferences page back, be my guest. |
|
446 function page_Special_Preferences() { |
|
447 global $db, $session, $paths, $template, $plugins; // Common objects |
|
448 $template->header(); |
|
449 if(isset($_POST['submit'])) { |
|
450 $data = $session->update_user($session->user_id, $_POST['username'], $_POST['current_pass'], $_POST['new_pass'], $_POST['email'], $_POST['real_name'], $_POST['sig']); |
|
451 if($data == 'success') echo '<h3>Information</h3><p>Your profile has been updated. <a href="'.scriptPath.'/">Return to the index page</a>.</p>'; |
|
452 else echo $data; |
|
453 } else { |
|
454 echo ' |
|
455 <h3>Edit your profile</h3> |
|
456 <form action="'.makeUrl($paths->nslist['Special'].'Preferences').'" method="post"> |
|
457 <table border="0" style="margin-left: 0.2in;"> |
|
458 <tr><td>Username:</td><td><input type="text" name="username" value="'.$session->username.'" /></td></tr> |
|
459 <tr><td>Current Password:</td><td><input type="password" name="current_pass" /></td></tr> |
|
460 <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> |
|
461 <tr><td>New Password:</td><td><input type="password" name="new_pass" /></td></tr> |
|
462 <tr><td>E-mail:</td><td><input type="text" name="email" value="'.$session->email.'" /></td></tr> |
|
463 <tr><td>Real Name:</td><td><input type="text" name="real_name" value="'.$session->real_name.'" /></td></tr> |
|
464 <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> |
|
465 <tr><td colspan="2"> |
|
466 <input type="submit" name="submit" value="Save Changes" /></td></tr> |
|
467 </table> |
|
468 </form> |
|
469 '; |
|
470 } |
|
471 $template->footer(); |
|
472 } |
|
473 */ |
|
474 |
|
475 function page_Special_Contributions() { |
|
476 global $db, $session, $paths, $template, $plugins; // Common objects |
|
477 $template->header(); |
|
478 $user = $paths->getParam(); |
|
479 if(!$user && isset($_GET['user'])) |
|
480 { |
|
481 $user = $_GET['user']; |
|
482 } |
|
483 elseif(!$user && !isset($_GET['user'])) |
|
484 { |
|
485 echo 'No user selected!'; |
|
486 $template->footer(); |
|
487 $db->close(); |
|
488 exit; |
|
489 } |
|
490 |
|
491 $user = $db->escape($user); |
|
492 |
|
493 $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;'; |
|
494 if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.'); |
|
495 echo 'History of edits and actions<h3>Edits:</h3>'; |
|
496 if($db->numrows() < 1) echo 'No history entries in this category.'; |
|
497 while($r = $db->fetchrow()) { |
|
498 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']; |
|
499 if($r['minor_edit']) echo '<b> - minor edit</b>'; |
|
500 echo '<br />'; |
|
501 } |
|
502 $db->free_result(); |
|
503 echo '<h3>Other changes:</h3>'; |
|
504 $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;'; |
|
505 if(!$db->sql_query($q)) $db->_die('The history data for the page "'.$paths->cpage['name'].'" could not be selected.'); |
|
506 if($db->numrows() < 1) echo 'No history entries in this category.'; |
|
507 while($r = $db->fetchrow()) { |
|
508 if($r['log_type']=='page') { |
|
509 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>: '; |
|
510 if($r['action']=='prot') echo 'Protected page; reason: '.$r['edit_summary']; |
|
511 elseif($r['action']=='unprot') echo 'Unprotected page; reason: '.$r['edit_summary']; |
|
512 elseif($r['action']=='rename') echo 'Renamed page; old title was: '.$r['edit_summary']; |
|
513 elseif($r['action']=='create') echo 'Created page'; |
|
514 elseif($r['action']=='delete') echo 'Deleted page'; |
|
515 if($r['minor_edit']) echo '<b> - minor edit</b>'; |
|
516 echo '<br />'; |
|
517 } elseif($r['log_type']=='security') { |
|
518 // Not implemented, and when it is, it won't be public |
|
519 } |
|
520 } |
|
521 $db->free_result(); |
|
522 $template->footer(); |
|
523 } |
|
524 |
|
525 function page_Special_ChangeStyle() |
|
526 { |
|
527 global $db, $session, $paths, $template, $plugins; // Common objects |
|
528 if(!$session->user_logged_in) die_friendly('Access denied', '<p>You must be logged in to change your style. Spoofer.</p>'); |
|
529 if(isset($_POST['theme']) && isset($_POST['style']) && isset($_POST['return_to'])) |
|
530 { |
|
531 $d = ENANO_ROOT . '/themes/' . $_POST['theme']; |
|
532 $f = ENANO_ROOT . '/themes/' . $_POST['theme'] . '/css/' . $_POST['style'] . '.css'; |
|
533 if(!file_exists($d) || !is_dir($d)) die('The directory "'.$d.'" does not exist.'); |
|
534 if(!file_exists($f)) die('The file "'.$f.'" does not exist.'); |
|
535 $d = $db->escape($_POST['theme']); |
|
536 $f = $db->escape($_POST['style']); |
|
537 $q = 'UPDATE '.table_prefix.'users SET theme=\''.$d.'\',style=\''.$f.'\' WHERE username=\''.$session->username.'\''; |
|
538 if(!$db->sql_query($q)) |
|
539 { |
|
540 $db->_die('Your theme/style preferences were not updated.'); |
|
541 } |
|
542 else |
|
543 { |
|
544 redirect(makeUrl($_POST['return_to']), '', '', 0); |
|
545 } |
|
546 } |
|
547 else |
|
548 { |
|
549 $template->header(); |
|
550 $ret = ( isset($_POST['return_to']) ) ? $_POST['return_to'] : $paths->getParam(0); |
|
551 if(!$ret) $ret = getConfig('main_page'); |
|
552 ?> |
|
553 <form action="<?php echo makeUrl($paths->page); ?>" method="post"> |
|
554 <?php if(!isset($_POST['themeselected'])) { ?> |
|
555 <h3>Please select a new theme:</h3> |
|
556 <p> |
|
557 <select name="theme"> |
|
558 <?php |
|
559 foreach($template->theme_list as $t) { |
|
560 if($t['enabled']) |
|
561 { |
|
562 echo '<option value="'.$t['theme_id'].'"'; |
|
563 if($t['theme_id'] == $session->theme) echo ' selected="selected"'; |
|
564 echo '>'.$t['theme_name'].'</option>'; |
|
565 } |
|
566 } |
|
567 ?> |
|
568 </select> |
|
569 </p> |
|
570 <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" /> |
|
571 <input type="submit" name="themeselected" value="Continue" /></p> |
|
572 <?php } else { |
|
573 $theme = $_POST['theme']; |
|
574 if ( !preg_match('/^([0-9A-z_-]+)$/i', $theme ) ) |
|
575 die('Hacking attempt'); |
|
576 ?> |
|
577 <h3>Please select a stylesheet:</h3> |
|
578 <p> |
|
579 <select name="style"> |
|
580 <?php |
|
581 $dir = './themes/'.$theme.'/css/'; |
|
582 $list = Array(); |
|
583 // Open a known directory, and proceed to read its contents |
|
584 if (is_dir($dir)) { |
|
585 if ($dh = opendir($dir)) { |
|
586 while (($file = readdir($dh)) !== false) { |
|
587 if(preg_match('#^(.*?)\.css$#is', $file) && $file != '_printable.css') { |
|
588 $list[] = substr($file, 0, strlen($file)-4); |
|
589 } |
|
590 } |
|
591 closedir($dh); |
|
592 } |
|
593 } else die($dir.' is not a dir'); |
|
594 foreach ( $list as $l ) |
|
595 { |
|
596 echo '<option value="'.$l.'">'.capitalize_first_letter($l).'</option>'; |
|
597 } |
|
598 ?> |
|
599 </select> |
|
600 </p> |
|
601 <p><input type="hidden" name="return_to" value="<?php echo $ret; ?>" /> |
|
602 <input type="hidden" name="theme" value="<?php echo $theme; ?>" /> |
|
603 <input type="submit" name="allclear" value="Change style" /></p> |
|
604 <?php } ?> |
|
605 </form> |
|
606 <?php |
|
607 $template->footer(); |
|
608 } |
|
609 } |
|
610 |
|
611 function page_Special_ActivateAccount() |
|
612 { |
|
613 global $db, $session, $paths, $template, $plugins; // Common objects |
|
614 $user = $paths->getParam(0); |
|
615 if(!$user) die_friendly('Account activation error', '<p>The URL was incorrect.</p>'); |
|
616 $key = $paths->getParam(1); |
|
617 if(!$key) die_friendly('Account activation error', '<p>The URL was incorrect.</p>'); |
|
618 $s = $session->activate_account(str_replace('_', ' ', $user), $key); |
|
619 if($s > 0) die_friendly('Activation successful', '<p>Your account is now active. Thank you for registering.</p>'); |
|
620 else die_friendly('Activation failed', '<p>The activation key was probably incorrect.</p>'); |
|
621 } |
|
622 |
|
623 function page_Special_Captcha() |
|
624 { |
|
625 global $db, $session, $paths, $template, $plugins; // Common objects |
|
626 if($paths->getParam(0) == 'make') |
|
627 { |
|
628 $session->kill_captcha(); |
|
629 echo $session->make_captcha(); |
|
630 return; |
|
631 } |
|
632 $hash = $paths->getParam(0); |
|
633 if(!$hash || !preg_match('#^([0-9a-f]*){32,32}$#i', $hash)) $paths->main_page(); |
|
634 $code = $session->get_captcha($hash); |
|
635 if(!$code) die('Invalid hash or IP address incorrect.'); |
|
636 require(ENANO_ROOT.'/includes/captcha.php'); |
|
637 $captcha = new captcha($code); |
|
638 //header('Content-disposition: attachment; filename=autocaptcha.png'); |
|
639 $captcha->make_image(); |
|
640 exit; |
|
641 } |
|
642 |
|
643 function page_Special_PasswordReset() |
|
644 { |
|
645 global $db, $session, $paths, $template, $plugins; // Common objects |
|
646 $template->header(); |
|
647 if($paths->getParam(0) == 'stage2') |
|
648 { |
|
649 $user_id = intval($paths->getParam(1)); |
|
650 $encpass = $paths->getParam(2); |
|
651 if ( $user_id < 2 ) |
|
652 { |
|
653 echo '<p>Hacking attempt</p>'; |
|
654 $template->footer(); |
|
655 return false; |
|
656 } |
|
657 if(!preg_match('#^([a-f0-9]+)$#i', $encpass)) |
|
658 { |
|
659 echo '<p>Hacking attempt</p>'; |
|
660 $template->footer(); |
|
661 return false; |
|
662 } |
|
663 |
|
664 $q = $db->sql_query('SELECT username,temp_password_time FROM '.table_prefix.'users WHERE user_id='.$user_id.' AND temp_password=\'' . $encpass . '\';'); |
|
665 if($db->numrows() < 1) |
|
666 { |
|
667 echo '<p>Invalid credentials</p>'; |
|
668 $template->footer(); |
|
669 return false; |
|
670 } |
|
671 $row = $db->fetchrow(); |
|
672 $db->free_result(); |
|
673 |
|
674 if ( ( intval($row['temp_password_time']) + 3600 * 24 ) < time() ) |
|
675 { |
|
676 echo '<p>Password has expired</p>'; |
|
677 $template->footer(); |
|
678 return false; |
|
679 } |
|
680 |
|
681 if ( isset($_POST['do_stage2']) ) |
|
682 { |
|
683 $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE); |
|
684 if($_POST['use_crypt'] == 'yes') |
|
685 { |
|
686 $crypt_key = $session->fetch_public_key($_POST['crypt_key']); |
|
687 if(!$crypt_key) |
|
688 { |
|
689 echo 'ERROR: Couldn\'t look up public key for decryption.'; |
|
690 $template->footer(); |
|
691 return false; |
|
692 } |
|
693 $crypt_key = hexdecode($crypt_key); |
|
694 $data = $aes->decrypt($_POST['crypt_data'], $crypt_key, ENC_HEX); |
|
695 if(strlen($data) < 6) |
|
696 { |
|
697 echo 'ERROR: Your password must be six characters or greater in length.'; |
|
698 $template->footer(); |
|
699 return false; |
|
700 } |
|
701 } |
|
702 else |
|
703 { |
|
704 $data = $_POST['pass']; |
|
705 $conf = $_POST['pass_confirm']; |
|
706 if($data != $conf) |
|
707 { |
|
708 echo 'ERROR: The passwords you entered do not match.'; |
|
709 $template->footer(); |
|
710 return false; |
|
711 } |
|
712 if(strlen($data) < 6) |
|
713 { |
|
714 echo 'ERROR: Your password must be six characters or greater in length.'; |
|
715 $template->footer(); |
|
716 return false; |
|
717 } |
|
718 } |
|
719 if(empty($data)) |
|
720 { |
|
721 echo 'ERROR: Sanity check failed!'; |
|
722 $template->footer(); |
|
723 return false; |
|
724 } |
|
725 $encpass = $aes->encrypt($data, $session->private_key, ENC_HEX); |
|
726 $q = $db->sql_query('UPDATE '.table_prefix.'users SET password=\'' . $encpass . '\',temp_password=\'\',temp_password_time=0 WHERE user_id='.$user_id.';'); |
|
727 |
|
728 if($q) |
|
729 { |
|
730 $session->login_without_crypto($row['username'], $data); |
|
731 echo '<p>Your password has been reset. Return to the <a href="' . makeUrl(getConfig('main_page')) . '">main page</a>.</p>'; |
|
732 } |
|
733 else |
|
734 { |
|
735 echo $db->get_error(); |
|
736 } |
|
737 |
|
738 $template->footer(); |
|
739 return false; |
|
740 } |
|
741 |
|
742 // Password reset form |
|
743 $pubkey = $session->rijndael_genkey(); |
|
744 |
|
745 ?> |
|
746 <form action="<?php echo makeUrl($paths->fullpage); ?>" method="post" name="resetform" onsubmit="return runEncryption();"> |
|
747 <br /> |
|
748 <div class="tblholder"> |
|
749 <table border="0" style="width: 100%;" cellspacing="1" cellpadding="4"> |
|
750 <tr><th colspan="2">Reset password</th></tr> |
|
751 <tr><td class="row1">Password:</td><td class="row1"><input name="pass" type="password" /></td></tr> |
|
752 <tr><td class="row2">Confirm: </td><td class="row2"><input name="pass_confirm" type="password" /></td></tr> |
|
753 <tr> |
|
754 <td colspan="2" class="row1" style="text-align: center;"> |
|
755 <input type="hidden" name="use_crypt" value="no" /> |
|
756 <input type="hidden" name="crypt_key" value="<?php echo $pubkey; ?>" /> |
|
757 <input type="hidden" name="crypt_data" value="" /> |
|
758 <input type="submit" name="do_stage2" value="Reset password" /> |
|
759 </td> |
|
760 </tr> |
|
761 </table> |
|
762 </div> |
|
763 </form> |
|
764 <script type="text/javascript"> |
|
765 disableJSONExts(); |
|
766 str = ''; |
|
767 for(i=0;i<keySizeInBits/4;i++) str+='0'; |
|
768 var key = hexToByteArray(str); |
|
769 var pt = hexToByteArray(str); |
|
770 var ct = rijndaelEncrypt(pt, key, "ECB"); |
|
771 var ct = byteArrayToHex(ct); |
|
772 switch(keySizeInBits) |
|
773 { |
|
774 case 128: |
|
775 v = '66e94bd4ef8a2c3b884cfa59ca342b2e'; |
|
776 break; |
|
777 case 192: |
|
778 v = 'aae06992acbf52a3e8f4a96ec9300bd7aae06992acbf52a3e8f4a96ec9300bd7'; |
|
779 break; |
|
780 case 256: |
|
781 v = 'dc95c078a2408989ad48a21492842087dc95c078a2408989ad48a21492842087'; |
|
782 break; |
|
783 } |
|
784 var testpassed = ( ct == v && md5_vm_test() ); |
|
785 var frm = document.forms.resetform; |
|
786 if(testpassed) |
|
787 { |
|
788 frm.use_crypt.value = 'yes'; |
|
789 var cryptkey = frm.crypt_key.value; |
|
790 frm.crypt_key.value = hex_md5(cryptkey); |
|
791 cryptkey = hexToByteArray(cryptkey); |
|
792 if(!cryptkey || ( ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ) && cryptkey.length != keySizeInBits / 8 ) |
|
793 { |
|
794 frm._login.disabled = true; |
|
795 len = ( typeof cryptkey == 'string' || typeof cryptkey == 'object' ) ? '\nLen: '+cryptkey.length : ''; |
|
796 alert('The key is messed up\nType: '+typeof(cryptkey)+len); |
|
797 } |
|
798 } |
|
799 function runEncryption() |
|
800 { |
|
801 pass1 = frm.pass.value; |
|
802 pass2 = frm.pass_confirm.value; |
|
803 if ( pass1 != pass2 ) |
|
804 { |
|
805 alert('The passwords you entered do not match.'); |
|
806 return false; |
|
807 } |
|
808 if ( pass1.length < 6 ) |
|
809 { |
|
810 alert('The new password must be 6 characters or greater in length.'); |
|
811 return false; |
|
812 } |
|
813 if(testpassed) |
|
814 { |
|
815 pass = frm.pass.value; |
|
816 pass = stringToByteArray(pass); |
|
817 cryptstring = rijndaelEncrypt(pass, cryptkey, 'ECB'); |
|
818 if(!cryptstring) |
|
819 { |
|
820 return false; |
|
821 } |
|
822 cryptstring = byteArrayToHex(cryptstring); |
|
823 frm.crypt_data.value = cryptstring; |
|
824 frm.pass.value = ""; |
|
825 frm.pass_confirm.value = ""; |
|
826 } |
|
827 return true; |
|
828 } |
|
829 </script> |
|
830 <?php |
|
831 $template->footer(); |
|
832 return true; |
|
833 } |
|
834 if(isset($_POST['do_reset'])) |
|
835 { |
|
836 if($session->mail_password_reset($_POST['username'])) |
|
837 { |
|
838 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>'; |
|
839 } |
|
840 else |
|
841 { |
|
842 echo '<p>Error occured, your new password was not sent.</p>'; |
|
843 } |
|
844 $template->footer(); |
|
845 return true; |
|
846 } |
|
847 echo '<p>Don\'t worry, it happens to the best of us.</p> |
|
848 <p>To reset your password, just enter your username below, and a new password will be e-mailed to you.</p> |
|
849 <form action="'.makeUrl($paths->page).'" method="post" onsubmit="if(!submitAuthorized) return false;"> |
|
850 <p>Username: '.$template->username_field('username').'</p> |
|
851 <p><input type="submit" name="do_reset" value="Mail new password" /></p> |
|
852 </form>'; |
|
853 $template->footer(); |
|
854 } |
|
855 |
|
856 ?> |