Editing MC Group Profiles — with Captcha
- Register Group with Captcha
- View Group Profile
- Edit Group Profile
- MC (Microcommunity) Search and Match
- MC (Microcommunity) Search and Match — Security
- MC (Microcommunity) Search and Match — JavaScript
- MC (Microcommunity) Search and Match — Form
- MC (Microcommunity) Search and Match — PHP
- MC Questionnaire
- Microcommunity (MC) Registration Script — Enter Questionnaire Data in Database
- MC Search and Match Profile and Account Management
- Login to MC Search and Match Profile and Account Management
- Logout of MC Search and Match Profile and Account Management
- MC Questionnaire Login
- MC Questionnaire Info
- Delete Group Account
- Forgot User Name
- Forgot Password
- Form to Send Private Message
- Send Private Message
- Private Message Outbox
- Private Message Inbox
- Delete Private Message from Inbox
- Delete Private Message from Outbox
- Private Message Logout
- Private Message Session Monitoring
- MC (Microcommunity) Search and Match Session Monitoring
- Configure File for Database Connection
- Captcha Script for Registration and Login
This script is called edit-profile.php
The first section is at the start of the script. First, we use the checkid.php script to ensure that the session id variable is set, and send the user to register-with-captcha.php if it is not. Then we put the session variable 'username' into $U—we will be checking that it is set in a second. Then we define a named constant '_NODIRECTACCESS'. We include the config.php file (in the includes folder) which uses the PHP defined() function to check on this constant. If it is not set, we are thrown out of the config.php file like yesterday's trash.
Next we check if the session variables 'groupname', 'username', and 'userid' are set. If not, we are sent to the login-to-mc.php script. We make sure $U is still equal to the session variable 'username', that it is not an empty string, and that it's at least 6 characters long or . . . you guessed it . . . the login script. We make sure the session id is set and send them away if not.
Next we get to the JavaScript section. We check whether the username and groupname defaultValue properties are still the same as they were when the script loaded, and if not, we stick a 1 in either or both of the hidden groupchange or userchange fields in the form. These will be used when the script tries to determine if the groupname and/or username fields in the db already exist or not.
We use both JavaScript and PHP validation to filter input from the user since the cardinal rule for user input is: NEVER TRUST IT. If you want to trust it, simply ensure that it will be safe for putting into your MySQL tables as well as displaying on your web pages. By far the best method here is to use the JavaScript for the users' benefit and the PHP for security. If JavaScript is turned off (in which case our scripts won't even work), the PHP validation scripts are your last line of defense to keep things safe. On the other hand, the JavaScript allows the user to get a user-friendly response to unacceptable or wrong input in fields. Rather than making the user restart the form when he goofs, good JavaScript validation scripts use the focus() method to put the cursor back on the field where the goof occured as well as alerting the user to his error. PHP-only validation forces form restart, which is maddening to users.
We use /^[A-Za-z0-9!@#$%^&*()_]{6,20}$/ types of regular expressions to force the data to conform to the needs of the data fields, with the first part showing the acceptable characters and the second part forcing the length—in this case—to be 6 to 20 characters. The email validator we wrote to allow even some of the weirder valid email configurations.
We now turn to the PHP section. First we grab all POSTed data that gets sent to the page after the submit button is clicked. There is a captcha in the form and the user must give the correct answer to get the edits to work. The correct answer will be figured in a different PHP script (more on that later) and stuck into the a__________a session variable. When the form is submitted, we check the answer the user gives against this a__________a variable and if it is incorrect, the user sees "Wrong captcha answer. Please try again." and is made to restart the editing process. The captchas are all simple: adding or substracting a 1-digit number to/from a 2-digit number.
If the user gets it right, the username and groupname they entered are checked for in the db table. If such a name already exists and the name has been changed from its default value (since the name is supposed to exist in the db already—which is what the default value would refer to), the user sees "This User Name already exists. Please try again." or "This Group Name already exists. Please try again." and is made to restart the editing process. If the user is silly enough to disable JavaScript, the PHP will still force the data to be within certain length parameters. Too long data gets trimmed off and too short data causes an alert and the user is made to restart the editing process. If the email is not valid, the PHP program will say so and the user is made to restart the editing process.
Here is something to get you to sit up and take notice: the very standard preg_match-using PHP email validator takes standard data but not unusual data, but the regular expression filtration done later allows any character that is technically allowed according to standards we looked up. Of course, this email regular expression filtration will have no effect since the earlier email validator stops unusual characters in their tracks—a regular expression pattern with only \w\- in it allows alphanumerics and "_" and "-" and nothing else. So if they used unusual characters they have to start over—they will never even reach the email regular expression filtration script.
We added this to allow you, dear reader, to decide if you want to include more legal characters or not. The other filtration scripts use preg_replace and dump unacceptable characters, using our strict standards.
We also filtered out tags someone may try to sneak in by use of the strip_tags function. And, of course, since the data will be going into a MySQL database table, we sanitized it even further with the mysql_real_escape_string() function, which escapes all iffy data—also known as special characters—like quotes, etc.
Next we create the random-alphanumeric-character-laden salt. Then we use the salt and the entered password to create the hash. Both salt and hash go into the db. The password does not, so if anyone asks for theirs like in Forgot Password, we simply create a random string and email it to them and say "here's your new password." Few companies allow storing of passwords—it's dumb. As the db is updated, we update their session variables for groupname and username since either or both may have changed.
The }}}}}}}}}}}}}} is because of all the }else{ conditionals used earlier in the script. If the $Entry variable is not 1 but still 0, they haven't submitted the form yet, so we show them the form for entry and submission. On the other hand, if they have submitted it, we send them off to MC Search and Match Profile and Account Management, which you will find at the end of the script after the final else conditional. We even send their username in a form, but we needn't have bothered since usernames are grabbed from session variables, not POSTs or GETs. Admittedly, there's a tad bit of overkill here and there in our scripts—just trying to cover all the bases.
The form itself is pretty standard stuff. It has maxlength attributes to keep lengths limited and it uses an onsubmit event to run the JavaScript validator. But the form also uses a captcha. We used the official captcha method in our Personal Status Board (PSB™) scripts, but designed a less cumbersome method for our MC editing scripts.
Take a gander at the captcha code: <IMG SRC="captcha-with-sessions.php" alt='captcha'>. A pretty strange type of image, to be sure! Browsers do NOT mind PHP scripts sitting in for PNG, BMP, GIF, or JPG images, believe it or not. Ad blockers with strong settings may knock the captcha out of the form. But Pop-up Blockers do not molest our captcha since it is NOT a pop-up. So your users were informed about the ad blocker nastiness when they registered—we doubt they will forget. The captcha is a random PNG image created using functions from the GD library, which is in all recent PHP versions. (To use the recommended bundled version of the GD library, which was first bundled in PHP 4.3.0, get your server hosts to use the configure option "--with-gd". Most already do this.)
The captcha image uses the font Holisb__.ttf, which is the Holiday Springs BTN True Type Font (get at MyFonts.com), but you may use other types if you wish. If you find arial.ttf in your C:\WINDOWS\Fonts\ directory on your computer, make sure it is in your folder with your PHP scripts on your server. Holisb__.ttf does a much cooler job, and will be harder for any automatic spambot script to read (and get the right answer for the arithmetic problem). For the captcha script, go to: Captcha Script for Registration and Login.
The script below is called: edit-profile.php
<?php
include_once"checkid.php";
$U=$_SESSION['username'];
define('_NODIRECTACCESS', TRUE);
include_once"includes/config.php";
if (!isset($_SESSION['groupname']) || !isset($_SESSION['userid']) || !isset($_SESSION['username']) || $_SESSION['username']<>$U || !isset($U) || $U=="" || strlen($U)<6 || !isset($_SESSION['sessionid'])){echo '<script language="javascript">alert("Please login."); window.location = "login-to-mc.php";</script>';}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
<TITLE>Edit MC Profile</TITLE>
<meta name="description" content="Edit MC Profile">
<meta name="keywords" content="Edit MC Profile,edit profile,profile,edit,php,javascript, dhtml, DHTML">
<style type="text/css">
BODY {margin-left:0; margin-right:0; margin-top:0;text-align:left}
p, li {font:13px Verdana; color:black;text-align:left}
h1 {font:bold 28px Verdana; color:black;text-align:center}
h2 {font:bold 24px Verdana;text-align:center}
h3 {font:bold 15px Verdana;}
.k {text-align:right}
.j {position:absolute;top:50px;left:200px;width:600px}
#myform {position:absolute;top:100px;left:50%;margin-left:-225px;width:450px;border:2px solid black;background-color:#8aa;}
#links {position:absolute;top:210px;left:82%;width:222px}
#t {width:410px;padding:9px;margin-top:-25px}
</style>
<script language="javascript">
function validatepassword(){
var groupname = document.getElementById("groupname");
if (groupname.value != groupname.defaultValue) {
document.formpw.groupchange.value='1';}
var username = document.getElementById("username");
if (username.value != username.defaultValue) {
document.formpw.userchange.value='1';}
var ck_password = /^[A-Za-z0-9!@#$%^&*()_]{6,20}$/;
if (document.formpw.password.value.search(ck_password)==-1)
{alert("Please enter 6 to 20 letters, numbers and these for password: !@#$%^&*()_");document.formpw.password.focus();return false;}
var ck_username = /^[A-Za-z0-9_]{6,20}$/;
if (document.formpw.username.value.search(ck_username)==-1)
{alert("Please only enter 6 to 20 letters, numbers and underline for user name.");document.formpw.username.focus();return false}
var ck_city = /^[A-Za-z \-]{2,33}$/;
if (document.formpw.city.value.search(ck_city)==-1)
{alert("Please only enter 2 to 33 letters, space, or hyphen for city name.");document.formpw.city.focus();return false}
var ck_state = /^[A-Za-z]{2,2}$/;
if (document.formpw.state.value.search(ck_state)==-1)
{alert("Please select a State.");document.formpw.state.focus();return false}
var ck_zip = /^[0-9]{5,5}$/;
if (document.formpw.zip.value.search(ck_zip)==-1)
{alert("Please only enter 5 number zip code.");document.formpw.zip.focus();return false}
var ck_groupname = /^[A-Za-z0-9_]{6,20}$/;
if (document.formpw.groupname.value.search(ck_groupname)==-1)
{alert("Please only enter 6 to 20 letters, numbers and underline for group name.");document.formpw.groupname.focus();return false}
var ck_email = /^[A-Za-z0-9-_]+(\.[A-Za-z0-9-_]+)*@([A-Za-z0-9-_]+\.)?([A-Za-z0-9-_]+(\.[A-Za-z]{2,6})(\.[A-Za-z]{2})?)$/;
if (document.formpw.email.value.search(ck_email)==-1)
{alert("That email address is not valid.");document.formpw.email.focus();return false}
return true;}
</script>
</head>
<body>
<?php
$Uold=$U;
$U=$_POST['username'];
$Entry=$_POST['entry'];
$gc=$_POST['groupchange'];
$uc=$_POST['userchange'];
$P=$_POST['password'];
$G=$_POST['groupname'];
$C=$_POST['city'];
$S=$_POST['state'];
$Z=$_POST['zip'];
$E=$_POST['email'];
$A=$_POST['answer'];
$N=0;
if($Entry==1 && $A<>$_SESSION['a__________a']){$N=1;unset($U);echo '<script language="javascript">alert("Wrong captcha answer. Please try again.");window.location="edit-profile.php";</script>';
}else{
if($Entry==1 && $A==$_SESSION['a__________a']){
$check_user_data = mysql_query("SELECT * FROM mc_members WHERE username = '$Uold' LIMIT 1") or die(mysql_error());
if(mysql_num_rows($check_user_data) == 0)
{$N=1;unset($U);echo '<script language="javascript">alert("This User Name does not exist. Please login again.");window.location="login-to-mc.php";</script>';
}else{
if($Entry==1 && $A==$_SESSION['a__________a']){
$check_user_data = mysql_query("SELECT * FROM mc_members WHERE username = '$U' LIMIT 1") or die(mysql_error());
if(mysql_num_rows($check_user_data) > 0 && $uc=='1')
{$N=1;unset($U);echo '<script language="javascript">alert("This User Name already exists. Please try again.");window.location="edit-profile.php";</script>';
}else{
if($Entry==1 && $A==$_SESSION['a__________a']){
$check_user_data = mysql_query("SELECT * FROM mc_members WHERE groupname = '$G' LIMIT 1") or die(mysql_error());
if(mysql_num_rows($check_user_data) > 0 && $gc=='1')
{$N=1;unset($U);echo '<script language="javascript">alert("This Group Name already exists. Please try again.");window.location="edit-profile.php";</script>';
}else{
$U=substr($U,0,20);
$P=substr($P,0,20);
$G=substr($G,0,20);
$C=substr($C,0,33);
$E=substr($E,0,65);
$S=substr($S,0,2);
$Z=substr($Z,0,5);
if (strlen($U)<6) {echo '<script language="javascript">alert("Please enter 6 to 20 characters for user name."); window.location = "edit-profile.php";</script>';
}else{
if (strlen($G)<6) {echo '<script language="javascript">alert("Please enter 6 to 20 characters for group name."); window.location = "edit-profile.php";</script>';
}else{
if (strlen($P)<6) {echo '<script language="javascript">alert("Please enter 6 to 20 characters for password."); window.location = "edit-profile.php";</script>';
}else{
if (strlen($C)<2) {echo '<script language="javascript">alert("Please enter 2 to 33 characters for city."); window.location = "edit-profile.php";</script>';
}else{
if (strlen($S)<2 || strlen($S)>2) {echo '<script language="javascript">alert("Please use dropdown list for state."); window.location = "edit-profile.php";</script>';
}else{
if (strlen($Z)<5) {echo '<script language="javascript">alert("Please enter 5 characters for zip code."); window.location = "edit-profile.php";</script>';
}else{
if (strlen($E)<6) {echo '<script language="javascript">alert("Please enter 6 to 65 characters for email address."); window.location = "edit-profile.php";</script>';
}else{
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$E)) {
echo '<script language="javascript">alert("That email address is not valid."); window.location = "edit-profile.php";</script>';
}else{
$pattern1 = '/[^a-zA-Z\\-\\s]/i';
$pattern2 = '/[^a-zA-Z0-9\\.\\,\\!\\;\\-\\_\\*\\@\\=\\+\\$\\/\\&\\[\\]\\#\\?\\047\\:\\(\\)]/i';
$pattern3 = '/[^a-zA-Z0-9\\_]/i';
$pattern4 = '/[^A-Za-z0-9\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)\\_]/i';
$pattern5 = '/[^0-9]/';
$pattern6 = '/[^A-Z]/';
$replacement = '';
$U=strip_tags($U);
$P=strip_tags($P);
$G=strip_tags($G);
$C=strip_tags($C);
$E=strip_tags($E);
$S=strip_tags($S);
$Z=strip_tags($Z);
$C=preg_replace($pattern1, $replacement, $C);
$U=preg_replace($pattern3, $replacement, $U);
$E=preg_replace($pattern2, $replacement, $E);
$Z=preg_replace($pattern5, $replacement, $Z);
$P=preg_replace($pattern4, $replacement, $P);
$G=preg_replace($pattern3, $replacement, $G);
$S=preg_replace($pattern6, $replacement, $S);
$S=mysql_real_escape_string($S);
$C=mysql_real_escape_string($C);
$Z=mysql_real_escape_string($Z);
$G=mysql_real_escape_string($G);
$E=mysql_real_escape_string($E);
$U=mysql_real_escape_string($U);
$o=make_salt();$h=z_____z();
$I = $_SERVER['REMOTE_ADDR'];
$D = date("d-m-Y");
$sql="UPDATE mc_members SET username='$U', password='$h', groupname='$G', city='$C', state='$S', zip='$Z', email='$E', ip='$I', signup_date='$D', salt='$o' WHERE username='$Uold'";
$result=mysql_query($sql);
if($result){$_SESSION['username'] = $U;$_SESSION['groupname'] = $G;
echo '<script language="javascript">alert("Entries were made successfully.");</script>';
}else{
$N=1;unset($U);
echo '<script language="javascript">alert("Entries were NOT made—something went wrong."); window.location="edit-profile.php";</script>';}
}}}}}}}}}}}}}}
if($N==1||$Entry==0){
$res = mysql_query("SELECT * FROM mc_members WHERE username='$Uold'") or die(mysql_error());
while($rows=mysql_fetch_array($res)){
$s=$rows['state'];
$op=array("AL","AK","AZ","AR","CA","CO","CT","DE","DC","FL","GA","HI","ID","IL",
"IN","IA","KS","KY","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE",
"NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD",
"TN","TX","UT","VT","VA","WA","WV","WI","WY");
for ($i=0;$i<51;$i++) {if($op[$i]==$s){$si=$i;}}
?>
<center><h1>Edit MC Profile</h1></center>
<div id='myform'><BR><center><h3>Edit MC Profile</h3></center><table id='t' border='0' cellspacing=0 cellpadding=2>
<form id='formpw' name="formpw" method="post" action="edit-profile.php" onsubmit="return validatepassword()">
<tr><td class='k'><label for="User Name"><b>User Name: </b></td><td><input type="text" id="username" name="username" size="20" maxlength="20" value="<?php echo htmlentities(stripslashes($rows['username']), ENT_QUOTES); ?>"></label></td></tr>
<tr><td class='k'><label for="Password"><b>Password: </b></td><td><input type="password" name="password" size="20" maxlength="20" value=""></label>(type new or old)</td></tr>
<tr><td class='k'><label for="Group Name"><b>Group Name: </b></td><td><input type="text" id="groupname" name="groupname" size="20" maxlength="20" value="<?php echo htmlentities(stripslashes($rows['groupname']), ENT_QUOTES); ?>"></label></td></tr>
<tr><td class='k'><label for="City"><b>City: </b></td><td><input type="text" name="city" size="20" maxlength="33" value="<?php echo htmlentities(stripslashes($rows['city']), ENT_QUOTES); ?>"></label></td></tr>
<tr><td class='k'><label for="State"><b>State: </b></td><td>
<select name="state" size='4'>
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
<option value="CO">Colorado</option>
<option value="CT">Connecticut</option>
<option value="DE">Delaware</option>
<option value="DC">District of Columbia</option>
<option value="FL">Florida</option>
<option value="GA">Georgia</option>
<option value="HI">Hawaii</option>
<option value="ID">Idaho</option>
<option value="IL">Illinois</option>
<option value="IN">Indiana</option>
<option value="IA">Iowa</option>
<option value="KS">Kansas</option>
<option value="KY">Kentucky</option>
<option value="LA">Louisiana</option>
<option value="ME">Maine</option>
<option value="MD">Maryland</option>
<option value="MA">Massachusetts</option>
<option value="MI">Michigan</option>
<option value="MN">Minnesota</option>
<option value="MS">Mississippi</option>
<option value="MO">Missouri</option>
<option value="MT">Montana</option>
<option value="NE">Nebraska</option>
<option value="NV">Nevada</option>
<option value="NH">New Hampshire</option>
<option value="NJ">New Jersey</option>
<option value="NM">New Mexico</option>
<option value="NY">New York</option>
<option value="NC">North Carolina</option>
<option value="ND">North Dakota</option>
<option value="OH">Ohio</option>
<option value="OK">Oklahoma</option>
<option value="OR">Oregon</option>
<option value="PA">Pennsylvania</option>
<option value="RI">Rhode Island</option>
<option value="SC">South Carolina</option>
<option value="SD">South Dakota</option>
<option value="TN">Tennessee</option>
<option value="TX">Texas</option>
<option value="UT">Utah</option>
<option value="VT">Vermont</option>
<option value="VA">Virginia</option>
<option value="WA">Washington</option>
<option value="WV">West Virginia</option>
<option value="WI">Wisconsin</option>
<option value="WY">Wyoming</option>
</select>
</label></td></tr>
<tr><td class='k'><label for="Zip"><b>Zip: </b></td><td><input type="text" name="zip" size="5" maxlength="5" value="<?php echo htmlentities(stripslashes($rows['zip']), ENT_QUOTES); ?>"></label></td></tr>
<tr><td class='k'><label for="Email"><b>Email: </b></td><td><input type="text" name="email" size="20" maxlength="65" value="<?php echo htmlentities(stripslashes($rows['email']), ENT_QUOTES); ?>"></label></td></tr>
<br><br>
<tr><td class='k'><input type="hidden" name="entry" value="1"><input type="hidden" name="userchange" value="0"><input type="hidden" name="groupchange" value="0">
</td><td><IMG SRC="captcha-with-sessions.php" alt='captcha'>
</td></tr>
<tr><td class='k'><label for="Captcha answer"><b>Captcha answer: </b></td><td><input type="text" name="answer" size="20" maxlength="20" value=""></label></td></tr>
<tr><td class='k'> </td><td><BR><input type="submit" value="Submit">
<input type="reset" value="Reset"></td></tr></form></table><BR>
<script language="javascript">
var si = <?php echo json_encode($si); ?>;
document.formpw.state.selectedIndex = si;
</script>
</div>
<div id='links'><BR>
<a HREF="register-for-mc.php">Account Management</a><BR>
<a HREF="login-to-mc.php">Login (I've registered)</a><BR>
<a HREF="register-with-captcha.php">Register</a><BR>
<a HREF="http://www.thebiganswer.info/">Home</a><BR>
<a href="http://www.css-resources.com/contact.html">Contact us</a><BR>
<a href='forgot-password.php'>I forgot my password</a><BR>
<a HREF='forgot-user-name.php'>I forgot my user name</a><BR>
<a HREF="http://www.thebiganswer.info/">The Big Answer</a>
</div>
<?php
mysql_close();}
}else{
?>
<form name="MyForm" method="POST" action="register-for-mc.php">
<input type="hidden" name="username" value=" ">
</form>
<script language="javascript">
var u = <?php echo json_encode($U); ?>;
document.MyForm.username.value=u;
document.MyForm.submit();
</script>
<?php
}}
?>
</body>
</html>