plugins/SpecialUserFuncs.php
changeset 0 902822492a68
child 23 320acf077276
equal deleted inserted replaced
-1:000000000000 0:902822492a68
       
     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 ?>