<?php
/**
* Support sign-in, sign-up, and password changes.
*
* Copyright (C) 2005 Wayne Davison <hide@address.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
require 'lib/main.inc';
switch ($_GET['do']) {
case 'signin':
case 'signup':
case 'newpass':
user_page($_GET['do']);
break;
case 'welcome':
case 'passchange':
welcome_page($_GET['do']);
break;
default:
user_page('signin');
break;
}
function user_page($signup_type)
{
add_sidebar_divider();
add_sidebar_image('btn-library', '.');
start_content($signup_type, 'wide');
$need_prompt = 1;
$scr_desc = ' ';
$sub = $_POST['sub'];
if ($sub != '') {
$scrname = preg_replace('/\s+/', '_', trim($_POST['scrname']));
$email = trim($_POST['pbemail']);
$pass1 = $_POST['pass1'];
$pass2 = $_POST['pass2'];
open_db();
if ($signup_type == 'signin') {
if ($scrname != '') {
$qscrname = mysql_real_escape_string($scrname);
$do = "SELECT UserID, Password FROM Users WHERE Name = '$qscrname' LIMIT 1";
if (preg_match('/^[-\w.]+@[-\w.]+$/', $scrname))
$do = preg_replace('/ Name /', ' Email ', $do, 1);
$result = mysql_query($do) or die('SELECT failed: ' . mysql_error() . " (cmd: $do)");
$obj = mysql_fetch_object($result);
if ($obj && crypt($pass1, $obj->Password) == $obj->Password) {
set_auth_cookie("{$obj->UserID}*{$obj->Password}");
redir_main();
$need_prompt = 0;
} else {
$err_msg = 'Sign-in information is incorrect';
}
}
} else {
if ($signup_type != 'newpass'
&& !preg_match('#^\w[\w.]{2,}$#i', $scrname))
$err_msg = 'Your screen name is invalid';
elseif (preg_match('/^everyone$/i', $scrname))
$err_msg = 'You may not use the screen name "Everyone"';
elseif ($signup_type != 'newpass'
&& !preg_match('/^[-\w.]+@[-\w.]+$/', $email))
$err_msg = 'Your email address is invalid';
elseif (strlen($pass1) < 5)
$err_msg = 'Your password is too short';
elseif ($pass1 != $pass2)
$err_msg = 'The passwords do not match';
if ($err_msg == '') {
$salt = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$cpass = crypt($pass1, substr($salt, rand(0,63), 1) . substr($salt, rand(0,63), 1));
if ($signup_type == 'newpass') {
// Change the password of an existing user.
$do = "SELECT UserID, Email FROM Users WHERE Name = '$scrname' LIMIT 1";
if (preg_match('/^[-\w.]+@[-\w.]+$/', $scrname))
$do = preg_replace('/ Name /', ' Email ', $do, 1);
$result = mysql_query($do) or die('SELECT failed: ' . mysql_error() . " (cmd: $do)");
$obj = mysql_fetch_object($result);
if ($obj) {
$do = "UPDATE Users SET NewPass = '$cpass' WHERE UserID = {$obj->UserID}";
mysql_query($do) or die('SELECT failed: ' . mysql_error() . " (cmd: $do)");
send_email($obj->UserID, $obj->Email, $cpass, 'passchange');
$need_prompt = 0;
} else {
$err_msg = 'We could not find your account';
}
} else { // TODO We should do this in a transaction.
// Create a new user.
$do = "INSERT INTO Users SET Name = '$scrname', Email = '$email',
Password = '**INVALID', NewPass = '$cpass'";
if (mysql_query($do)) {
$do = "SELECT UserID, NewPass FROM Users WHERE Name = '$scrname' LIMIT 1";
$result = mysql_query($do) or die('SELECT failed: ' . mysql_error() . " (cmd: $do)");
$obj = mysql_fetch_object($result);
if (!$obj || $obj->NewPass != $cpass) {
echo '** Internal error! **<p>Possible duplicate user!';
} else {
$uID = $obj->UserID;
$book_groups = array();
$do = "SELECT GroupID FROM Books";
$result = mysql_query($do) or die('SELECT failed: ' . mysql_error() . " (cmd: $do)");
while (($row = mysql_fetch_row($result)) !== FALSE)
$book_groups[] = $row[0];
add_new_group($uID, $uID, '', $scrname, 'Private', 0);
add_new_group($uID, 0, '', $scrname, 'Public', 0);
foreach ($book_groups as $gID)
add_enabled_group($uID, $gID);
send_email($uID, $email, $cpass, 'welcome');
$need_prompt = 0;
}
} else {
if (!preg_match('/Duplicate entry \'(.*)\' for key (\d+)/', mysql_error(), $out))
die('INSERT failed: ' . mysql_error() . " (cmd: $do)");
if ($out[1] == $scrname)
$err_msg = 'That screen name is already taken';
else
$err_msg = 'You may only sign-up for a single screen name';
}
}
}
}
close_db();
}
if ($need_prompt) {
$pass_prompt = 'Password';
if ($signup_type == 'signin') {
$info_text = <<<EOT
Returning users should supply their email address and the associated password
to sign-in. You will get a browser-cookie that will allow you to begin making
Annotations.
EOT;
$pass_desc = ' ';
$lower_form = <<<EOT
<td> </td><td><input type=submit name=sub value="Sign-In"></td><td> </td>
EOT;
} else {
if ($signup_type == 'signup') {
$button_text = 'Create Account';
$info_text = <<<EOT
<p>Please provide your email address below, which is also your login name, along
with the password you'd like. Confirmation
email will be set to that email address, with the information you will
need to login for the first time.
<p><font size=2>After filling in the form and clicking "Create Account" below, you
should wait for the email to arrive, and then follow the directions in it to
complete your registration.
EOT;
$email_prompt = <<<EOT
<td align=right width="20%">Email:</td>
<td width="5%"><input type=text name=pbemail value="$email"></td><td> </td>
</tr><tr>
EOT;
$scr_desc = '<small>(At least 3 characters; Only period and underscore for punctuaton.)</small>';
} else {
if ($scrname == '') {
open_db();
list($uID, $scrname) = get_auth_cookie();
close_db();
if (!$uID)
$scrname = '';
}
$pass_prompt = 'New Password';
$button_text = 'Change Password';
$scr_desc = "<small>(Use your email address if you don't remember your screen name.)</small>";
$info_text = <<<EOT
Use this page to request a new password for an existing account. An email will
be sent to the indicated email address with the details on what to do to
finalize the change. <b>The password-change will not take effect until you
(as the assumed recipient at the indicated email address) approve this action.</b>
EOT;
}
$pass_desc = '<small>(At least 5 characters.)</small>';
$lower_form = <<<EOT
<td align=right>Confirm Password:</td>
<td><input type=password name=pass2 value="$pass2"></td><td> </td>
</tr><tr>
$ab<td> </td><td colspan=2><input type=submit name=sub value="$button_text"></td>
EOT;
}
if ($err_msg != '')
$info_text = "<b style='color:red'>$err_msg.</b>";
echo <<<EOT
<form name=signform method=post>
<table><tr><td>
<h2 style='border:0'>$title</h2>
<p>$info_text
</td><td> </td></tr></table>
<p><table><tr>
<td align=right width="20%">Screen Name:</td>
<td width="5%"><input type=text name=scrname value="$scrname"></td><td>$scr_desc</td>
</tr><tr>
$email_prompt<td align=right>$pass_prompt:</td>
<td><input type=password name=pass1 value="$pass1"></td><td>$pass_desc</td>
</tr><tr>
$lower_form</tr></table>
</form>
<script>
document.signform.scrname.focus();
</script>
EOT;
if ($signup_type != 'signin') {
echo <<<EOT
<p>If you already have an account, please <a href="signin.php">sign in</a>.
EOT;
}
if ($signup_type != 'signup') {
echo <<<EOT
<p>If you don't yet have an account, please <a href="signin.php?do=signup">sign up
for one</a>.
EOT;
}
if ($signup_type == 'signin') {
echo <<<EOT
<p>If you can't remember your password, you can <a href="signin.php?do=newpass">request
a password change</a>.
EOT;
}
}
end_content();
}
function welcome_page($page_type)
{
$uID = $_GET['u'];
$cpass = $_GET['x'];
if (!preg_match(':^\d+;[a-zA-Z0-9./]+$:', join(';', array($uID, $cpass)))) {
redir_main();
return;
}
open_db();
$type = $page_type == 'welcome' ? 'sign-up' : 'password-change';
$do = "SELECT Email, Name, NewPass FROM Users WHERE UserID = $uID LIMIT 1";
$result = mysql_query($do) or die('SELECT failed: ' . mysql_error() . " (cmd: $do)");
$obj = mysql_fetch_object($result);
if (!$obj || $obj->NewPass != $cpass) {
if ($obj) {
$msg = <<<EOT
Your account does not have a pending $type request.
<p>You may wish to do one of the following: <ul>
<li><a href="signin.php?do=newpass">Request a new password</a>.
<li><a href=".">Go to the library</A>.
</ul>
<p>Check the sidebar to see if you're signed in or not.
EOT;
} else
$msg = 'Invalid request';
list($uID, $scrname) = get_auth_cookie();
} else {
$scrname = $obj->Name;
$do = "UPDATE Users SET Password = '$cpass', NewPass = NULL WHERE UserID = $uID";
mysql_query($do) or die('UPDATE failed: ' . mysql_error() . " (cmd: $do)");
set_auth_cookie("$uID*$cpass");
$msg = <<<EOT
<h2>Welcome!</h2>
<p>You've completed your $type. To get started, visit
<a href=".">the library</a>.
EOT;
}
add_sidebar_divider();
add_sidebar_image('btn-library', '.');
if ($uID)
add_sidebar_image('btn-bookmarks', 'bkmk.php');
sidebar_signin($uID, $scrname);
start_content('Welcome', 'wide');
echo $msg;
close_db();
end_content();
}
function send_email($uID, $email, $cpass, $page_type)
{
global $CGI;
$url = "$CGI?do=$page_type&x=$cpass&u=$uID";
$op = $page_type == 'welcome' ? 'Sign-Up' : 'Password Change';
$op2 = strtolower($op);
echo <<<EOT
<H2 style='border:0'>Email Sent</h2>
<p>An email is being sent to the email address you provided.
It contains instructions on how to complete your $op2.
EOT;
$subject = "Completing your ProcessedBook $op";
$headers = 'From: hide@address.com' . "\r\n"
. 'X-Mailer: PHP/' . phpversion();
$message = <<<EOT
To complete the $op2 that you initiated on our web site, please
visit this link:
$url
If you did not request this $op2, you may disregard this message.
EOT;
mail($email, $subject, $message, $headers);
}
?>