Added Password Reset and Account Settings management.

This commit is contained in:
Robbie Antenesse 2015-12-11 18:06:47 -07:00
parent 6868aa5d2b
commit ea04571590
11 changed files with 455 additions and 129 deletions

View File

@ -4,7 +4,7 @@
<input type="email" id="forgotEmailField" name="email" /> <input type="email" id="forgotEmailField" name="email" />
</label> </label>
<div id="forgotError" style="font-weight:bold;color:red;"></div> <div id="forgotError" style="font-weight:bold;color:red;"></div>
<button type="submit" id="forgotSubmitButton" onclick="ValidateLogin(); return false;">Email Password Reset Key</button> <button type="submit" id="forgotSubmitButton" onclick="ValidateForgot(); return false;">Email Password Reset Key</button>
<div id="dictionaryWarn"></div> <div id="dictionaryWarn"></div>
<span id="forgotPassword" onclick="ShowInfo('login')">Log In/Create Account</span> <span id="forgotPassword" class="clickable" onclick="ShowInfo('loginForm')">Log In/Create Account</span>
</form></div> </form></div>

View File

@ -8,14 +8,14 @@
</label> </label>
<div id="loginError" style="font-weight:bold;color:red;"></div> <div id="loginError" style="font-weight:bold;color:red;"></div>
<button type="submit" id="loginSubmitButton" onclick="ValidateLogin(); return false;">Log In</button> <button type="submit" id="loginSubmitButton" onclick="ValidateLogin(); return false;">Log In</button>
<div id="dictionaryWarn"></div> <div id="dictionaryWarn" style="margin-bottom: 5px;"></div>
<span id="forgotPassword" onclick="ShowInfo('forgot')">Forgot Password?</span> <span id="forgotPassword" class="clickable" onclick="ShowInfo('forgotForm')" style="margin-top:20px;">Forgot Password?</span>
</form></div> </form></div>
<div class="settingsCol"><form id="createAccountForm" method="post" action="?createaccount"> <div class="settingsCol"><form id="createAccountForm" method="post" action="?createaccount">
<h2>Create a New Account</h2> <h2>Create a New Account</h2>
<p style="font-size: 12px;">Creating an account allows you to save and switch between as many dictionaries as you need and access them from any device for free!</p> <p style="font-size: 12px;">Creating an account allows you to save and switch between as many dictionaries as you need and access them from any device for free!</p>
<p style="font-size: 12px;">Plus if you allow us to send you emails, we'll make sure that you're the first to hear about any new features that get added or if any of our policies change for any reason. We'll never spam you or sell your information.</p> <p style="font-size: 12px;">Plus if you allow us to send you emails, we'll make sure that you're the first to hear about any new features that get added or if any of our policies change for any reason. We'll never spam you or sell your information.</p>
<p style="font-size: 12px;">By creating an account, you are indicating that you agree to the <span class="clickable" onclick="ShowInfo('terms')" style="font-size:11px;vertical-align:top;background:#e0c19c;padding:4px 7px;">Terms of Service</span> and that you understand Lexiconga's <span class="clickable" onclick="ShowInfo('privacy')" style="font-size:11px;vertical-align:top;background:#e0c19c;padding:4px 7px;">Privacy Policy</span>.</p> <p style="font-size: 12px;">By creating an account, you are indicating that you agree to the <span class="clickable" onclick="ShowInfo('termsText')" style="font-size:11px;vertical-align:top;background:#e0c19c;padding:4px 7px;">Terms of Service</span> and that you understand Lexiconga's <span class="clickable" onclick="ShowInfo('privacyText')" style="font-size:11px;vertical-align:top;background:#e0c19c;padding:4px 7px;">Privacy Policy</span>.</p>
<label><span>Email</span> <label><span>Email</span>
<input type="email" id="createAccountEmailField" name="email" /> <input type="email" id="createAccountEmailField" name="email" />
</label> </label>

View File

@ -96,7 +96,7 @@ input, textarea, select, option, button {
border-color: #d09b84 #915237 #915237 #d09b84; border-color: #d09b84 #915237 #915237 #d09b84;
} }
#dictionaryDescription, .management, #settingsOptions, #infoPage, #loadAfterDeletePage { #dictionaryDescription, .management, #settingsOptions, #infoPage, #loadAfterDeletePage, #accountSettingsPage {
background: #f2d5b2; background: #f2d5b2;
} }
@ -117,7 +117,7 @@ input, textarea, select, option, button {
#descriptionToggle, #searchFilterToggle, #settingsButton, #descriptionToggle, #searchFilterToggle, #settingsButton,
.deleteCancelButton, .deleteConfirmButton, .deleteCancelButton, .deleteConfirmButton,
#settingsScreenCloseButton, #infoScreenCloseButton, #settingsScreenCloseButton, #infoScreenCloseButton,
.helperlink { .clickable, .helperlink {
background: #e0c19c; background: #e0c19c;
} }

View File

@ -178,6 +178,7 @@ input[type=checkbox] {
.clickable, .helperlink { .clickable, .helperlink {
display: inline; display: inline;
font-weight: bold; font-weight: bold;
font-size: 13px;
padding: 4px; padding: 4px;
background: #dddddd; background: #dddddd;
border-radius: 5px; border-radius: 5px;
@ -309,7 +310,7 @@ searchTerm {
margin: 10px; margin: 10px;
} }
#settingsBackgroundFade, #infoBackgroundFade, #loadAfterDeleteFade { #settingsBackgroundFade, #infoBackgroundFade, #loadAfterDeleteFade, #accountSettingsBackgroundFade {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@ -319,7 +320,7 @@ searchTerm {
opacity: 0.75; opacity: 0.75;
} }
#settingsOptions, #infoPage, #loadAfterDeletePage { #settingsOptions, #infoPage, #loadAfterDeletePage, #accountSettingsPage {
position: fixed; position: fixed;
top: 6%; top: 6%;
left: 6%; left: 6%;

120
index.php
View File

@ -6,86 +6,16 @@ $current_user = isset($_SESSION['user']) ? $_SESSION['user'] : 0;
$notificationMessage = ""; $notificationMessage = "";
if (!isset($_SESSION['loginfailures']) || (isset($_SESSION['loginlockouttime']) && time() - $_SESSION['loginlockouttime'] >= 3600)) { if ($current_user > 0 || !isset($_SESSION['loginfailures']) || (isset($_SESSION['loginlockouttime']) && time() - $_SESSION['loginlockouttime'] >= 3600)) {
// If never failed or more than 1 hour has passed, reset login failures. // If logged in, never failed, or more than 1 hour has passed, reset login failures.
$_SESSION['loginfailures'] = 0; $_SESSION['loginfailures'] = 0;
} else { } else {
$alertlockoutmessage = "You failed logging in 10 times. To prevent request flooding and hacking attempts, you may not log in or create an account for about an hour.\\n\\nThe last time this page was loaded, you had been locked out for " . time_elapsed(time() - $_SESSION['loginlockouttime']); $alertlockoutmessage = "You failed logging in 10 times. To prevent request flooding and hacking attempts, you may not log in or create an account for 1 hour.\\n\\nThe last time this page was loaded, you had been locked out for " . time_elapsed(time() - $_SESSION['loginlockouttime']) . "\\n\\nRefresh the page once the hour has passed.";
$hoverlockoutmessage = str_replace("\\n", "\n", $alertlockoutmessage); $hoverlockoutmessage = str_replace("\\n", "\n", $alertlockoutmessage);
} }
if (isset($_GET['logout']) && $current_user > 0) { require_once(SITE_LOCATION . '/php/notificationconditiontree.php');
session_destroy();
header('Location: ./?loggedout');
}
elseif (isset($_GET['login']) && $current_user <= 0) {
if (isset($_POST['email']) && isset($_POST['password'])) {
if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
if (EmailExists($_POST['email'])) {
if (Validate_Login($_POST['email'], $_POST['password'])) {
$_SESSION['user'] = Get_User_Id($_POST['email']);
header('Location: ./');
} else {
header('Location: ./?error=loginfailed');
}
} else {
header('Location: ./?error=emaildoesnotexist');
}
} else {
header('Location: ./?error=emailinvalid');
}
} else {
header('Location: ./?error=loginemailorpasswordblank');
}
}
elseif (isset($_GET['createaccount'])) {
if (isset($_POST['email']) && isset($_POST['password'])) {
if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) && !EmailExists($_POST['email'])) {
if (query("INSERT INTO users (email, password, public_name, allow_email) VALUES ('" . $_POST['email'] . "','" . crypt($_POST['password'], $_POST['email']) . "','" . htmlspecialchars($_POST['publicname'], ENT_QUOTES) . "'," . (($_POST['allowemails'] != "on") ? 0 : 1) . ")")) {
header('Location: ./?success');
} else {
header('Location: ./?error=couldnotcreate');
}
} else {
header('Location: ./?error=emailcreateinvalid');
}
} else {
header('Location: ./?error=createemailorpasswordblank');
}
}
elseif (isset($_GET['error']) && $current_user <= 0) {
if ($_GET['error'] == "couldnotcreate") {
$notificationMessage = "Could not create account.<br>Please try again later.";
} elseif ($_GET['error'] == "emailcreateinvalid") {
$notificationMessage = "The email address used to create your account didn't work.<br>Please try another.";
} elseif ($_GET['error'] == "createemailorpasswordblank") {
$notificationMessage = "The create account form somehow got submitted without some essential information.<br>Please try filling it out again.";
} elseif ($_GET['error'] == "loginfailed") {
$notificationMessage = "We couldn't log you in because your email or password was incorrect.<br>";
$_SESSION['loginfailures'] += 1;
if ($_SESSION['loginfailures'] < 10) {
$notificationMessage .= "This is your " . ordinal($_SESSION['loginfailures']) . " time. Please try again.";
} else {
$_SESSION['loginlockouttime'] = time();
$notificationMessage .= "Since you failed to log in successfully 10 times, you may not try again for about an hour.";
}
} elseif ($_GET['error'] == "emaildoesnotexist") {
$notificationMessage = "The email address you entered doesn't have an account.<br>Would you like to <span class='clickable' onclick='ShowInfo(\"create\")'>create an account</span>?";
} elseif ($_GET['error'] == "emailinvalid") {
$notificationMessage = "The email address you entered didn't work.<br>Please try another.";
} else {
$notificationMessage = "Something seems to have gone wrong, but I don't know what.<br>Please try again.";
}
}
elseif (isset($_GET['success']) && $current_user <= 0) {
$notificationMessage = "Your account was created successfully!<br>Please log in using the email address and password you used to create it and you can start accessing your dictionaries anywhere!";
}
elseif (isset($_GET['loggedout']) && $current_user <= 0) {
$notificationMessage = "You have been successfully logged out.<br>You will only be able to use the dictionary saved to your browser.";
} elseif ($current_user > 0) {
$notificationMessage = "Welcome back, " . Get_Public_Name($current_user) . "!";
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
@ -103,13 +33,13 @@ elseif (isset($_GET['loggedout']) && $current_user <= 0) {
<div id="headerPadder"> <div id="headerPadder">
<a href="./" id="siteLogo">Lexiconga Dictionary Builder</a> <a href="./" id="siteLogo">Lexiconga Dictionary Builder</a>
<div style="float:right;margin: 16px 8px;font-size:12px;"> <div style="float:right;margin: 16px 8px;font-size:12px;">
<span id="aboutButton" class="clickable" onclick="ShowInfo('about')">About Lexiconga</span> <span id="aboutButton" class="clickable" onclick="ShowInfo('aboutText')">About Lexiconga</span>
</div> </div>
<div id="loginoutArea" style="font-size:12px;"> <div id="loginoutArea" style="font-size:12px;">
<?php if ($current_user > 0) { //If logged in, show the log out button. ?> <?php if ($current_user > 0) { //If logged in, show the log out button. ?>
<a href="?logout" id="logoutLink" class="clickable">Log Out</a> <span id="accountSettings" class="clickable" onclick="ShowAccountSettings()">Account Settings</span> <a href="?logout" id="logoutLink" class="clickable">Log Out</a>
<?php } elseif (!isset($_SESSION['loginfailures']) || (isset($_SESSION['loginfailures']) && $_SESSION['loginfailures'] < 10)) { ?> <?php } elseif (!isset($_SESSION['loginfailures']) || (isset($_SESSION['loginfailures']) && $_SESSION['loginfailures'] < 10)) { ?>
<span id="loginLink" class="clickable" onclick="ShowInfo('login')">Log In/Create Account</span> <span id="loginLink" class="clickable" onclick="ShowInfo('loginForm')">Log In/Create Account</span>
<?php } else { ?> <?php } else { ?>
<span id="loginLink" class="clickable" title="<?php echo $hoverlockoutmessage; ?>" onclick="alert('<?php echo $alertlockoutmessage; ?>');">Can't Login</span> <span id="loginLink" class="clickable" title="<?php echo $hoverlockoutmessage; ?>" onclick="alert('<?php echo $alertlockoutmessage; ?>');">Can't Login</span>
<?php } ?> <?php } ?>
@ -282,9 +212,43 @@ elseif (isset($_GET['loggedout']) && $current_user <= 0) {
</div> </div>
</div> </div>
</div> </div>
<?php if ($current_user > 0) {
$user_email = Get_User_Email($current_user);
?>
<div id="accountSettingsScreen" style="display:none;">
<div id="accountSettingsBackgroundFade" onclick="HideAccountSettings()"></div>
<div id="accountSettingsPage">
<span id="accountSettingsScreenCloseButton" class="clickable" onclick="HideAccountSettings()">Close</span>
<div class="settingsCol"><form id="accountSettingsForm" method="post" action="?accountsettings">
<h2>Account Settings</h2>
<label><span>Email</span>
<input type="email" id="accountSettingsEmailField" name="email" value="<?php echo $user_email; ?>" onchange="WarnEmailChange()" />
<input type="hidden" id="accountSettingsPreviousEmailField" name="previousemail" value="<?php echo $user_email; ?>" />
</label>
<div id="accountSettingsEmailChangeWarning" style="display:none;font-weight:bold;color:#dd5500;font-size:11px;margin-bottom:10px;">If you change your email address, please note that you will no longer be able to log in with your old email address, <?php echo $user_email; ?>.<br>Change it back unless you are completely sure that you want to change your email address!</div>
<label><span>Public Name <span class="clickable" onclick="ExplainPublicName()" style="font-size:11px;vertical-align:top;background:#e0c19c;padding:4px 7px;">?</span></span>
<input type="text" id="accountSettingsPublicNameField" name="publicname" value="<?php echo Get_Public_Name_By_Id($current_user); ?>" />
</label>
<label><b>Allow Emails</b>
<input type="checkbox" id="accountSettingsAllowEmailsField" name="allowemails" <?php if (Get_Allow_Email_By_Id($current_user) == 1) echo 'checked="checked"'; ?> />
</label>
<div id="accountSettingsError" style="font-weight:bold;color:red;"></div>
<button type="submit" id="accountSettingsSubmitButton" onclick="ValidateAccountSettings(); return false;">Save Settings</button>
<br><br>
<h2>Reset Your Password</h2>
<p style="font-size: 12px;">Click the button below to reload the page and show the Reset Password form. Filling out this form will instantly change your password, and you will need to log in using the new password from that point forward.</p>
<span id="resetPassword" class="clickable" onclick="this.innerHTML='Loading...';LoggedInResetPassword();" style="margin-top:20px;">Reset Password</span>
</form></div>
</div>
</div>
<?php
}
?>
</contents> </contents>
<footer> <footer>
Dictionary Builder only guaranteed to work with most up-to-date HTML5 browsers. <a href="https://github.com/Alamantus/DictionaryBuilder/issues" target="_blank">Report a Problem</a> | <span class="clickable" onclick="ShowInfo('terms')" style="font-size:12px;">Terms</span> <span class="clickable" onclick="ShowInfo('privacy')" style="font-size:12px;">Privacy</span> Dictionary Builder only guaranteed to work with most up-to-date HTML5 browsers. <a href="https://github.com/Alamantus/DictionaryBuilder/issues" target="_blank">Report a Problem</a> | <span class="clickable" onclick="ShowInfo('termsText')" style="font-size:12px;">Terms</span> <span class="clickable" onclick="ShowInfo('privacyText')" style="font-size:12px;">Privacy</span>
</footer> </footer>
<!-- Markdown Parser --> <!-- Markdown Parser -->

136
js/ui.js
View File

@ -1,14 +1,15 @@
var aboutText, termsText, privacyText, loginForm, createAccountForm; var aboutText = termsText = privacyText = loginForm = forgotForm = "Loading...";
window.onload = function () { window.onload = function () {
LoadDictionary(); LoadDictionary();
ClearForm(); ClearForm();
LoadUserDictionaries(); LoadUserDictionaries();
GetTextFile("README.md"); GetTextFile("README.md", "aboutText", true);
GetTextFile("TERMS.md"); GetTextFile("TERMS.md", "termsText", true);
GetTextFile("PRIVACY.md"); GetTextFile("PRIVACY.md", "privacyText", true);
GetTextFile("LOGIN.form"); GetTextFile("LOGIN.form", "loginForm", false);
GetTextFile("FORGOT.form", "forgotForm", false);
} }
function LoadUserDictionaries() { function LoadUserDictionaries() {
@ -43,20 +44,13 @@ function ParseUserDictionariesIntoSelect(selectToPopulate, dicitonaryList) {
selectToPopulate.value = (currentDictionary.externalID > 0) ? currentDictionary.externalID : ""; selectToPopulate.value = (currentDictionary.externalID > 0) ? currentDictionary.externalID : "";
} }
function GetTextFile(filename) { function GetTextFile(filename, variableName, parseMarkdown) {
parseMarkdown = (typeof parseMarkdown !== 'undefined') ? parseMarkdown : false;
var readmeFileRequest = new XMLHttpRequest(); var readmeFileRequest = new XMLHttpRequest();
readmeFileRequest.open('GET', filename); readmeFileRequest.open('GET', filename);
readmeFileRequest.onreadystatechange = function() { readmeFileRequest.onreadystatechange = function() {
if (readmeFileRequest.readyState == 4 && readmeFileRequest.status == 200) { if (readmeFileRequest.readyState == 4 && readmeFileRequest.status == 200) {
if (filename == "TERMS.md") { window[variableName] = (parseMarkdown) ? marked(readmeFileRequest.responseText) : readmeFileRequest.responseText;
termsText = marked(readmeFileRequest.responseText);
} else if (filename == "PRIVACY.md") {
privacyText = marked(readmeFileRequest.responseText);
} else if (filename == "LOGIN.form") {
loginForm = readmeFileRequest.responseText;
} else {
aboutText = marked(readmeFileRequest.responseText);
}
} }
} }
readmeFileRequest.send(); readmeFileRequest.send();
@ -120,6 +114,97 @@ function ValidateCreateAccount() {
} }
} }
function ValidateAccountSettings() {
var errorMessage = document.getElementById("accountSettingsError");
var emailValue = document.getElementById("accountSettingsEmailField").value;
var publicNameValue = document.getElementById("accountSettingsPublicNameField").value;
if (emailValue == "") {
errorMessage.innerHTML = "Email cannot be blank!";
return false;
} else if (!(/[^\s@]+@[^\s@]+\.[^\s@]+/.test(emailValue))) {
errorMessage.innerHTML = "Your email address looks fake. Email addresses look like this: name@email.com."
return false;
} else if (publicNameValue == "") {
errorMessage.innerHTML = "Public Name cannot be blank!";
return false;
} else {
document.getElementById("createAccountForm").submit();
}
}
function WarnEmailChange() {
var emailChangeWarning = document.getElementById("accountSettingsEmailChangeWarning");
var emailValue = document.getElementById("accountSettingsEmailField").value;
var originalEmailValue = document.getElementById("accountSettingsPreviousEmailField").value;
if (emailValue != originalEmailValue) {
emailChangeWarning.style.display = "block";
} else {
emailChangeWarning.style.display = "none";
}
}
function ValidateForgotPassword() {
var errorMessage = document.getElementById("forgotError");
var emailValue = document.getElementById("forgotEmailField").value;
if (emailValue == "") {
errorMessage.innerHTML = "Email cannot be blank!";
return false;
} else if (!(/[^\s@]+@[^\s@]+\.[^\s@]+/.test(emailValue))) {
errorMessage.innerHTML = "Your email address looks fake. Email addresses look like this: name@email.com."
return false;
} else {
var emailCheck = new XMLHttpRequest();
emailCheck.open('GET', "php/ajax_passwordresetemailcheck.php?email=" + emailValue);
emailCheck.onreadystatechange = function() {
if (emailCheck.readyState == 4 && emailCheck.status == 200) {
if (emailCheck.responseText != "email exists") {
errorMessage.innerHTML = "The email address entered is not in use and therefore can't have its password reset. Try <span class='clickable' onclick='ShowInfo(\"loginForm\")'>creating an account</span> instead!";
return false;
} else {
document.getElementById("forgotForm").submit();
}
}
}
emailCheck.send();
}
}
function ValidateResetPassword() {
var errorMessage = document.getElementById("resetPasswordError");
var passwordValue = document.getElementById("newPasswordField").value;
var passwordConfirmValue = document.getElementById("newPasswordConfirmField").value;
if (passwordValue == "") {
errorMessage.innerHTML = "Password cannot be blank!";
return false;
} else if (passwordValue != passwordConfirmValue) {
errorMessage.innerHTML = "Passwords do not match!";
return false;
} else {
document.getElementById("resetPasswordForm").submit();
}
}
function LoggedInResetPassword() {
var resetPasswordRequest = new XMLHttpRequest();
resetPasswordRequest.open('GET', "php/ajax_setnewpassword.php");
resetPasswordRequest.onreadystatechange = function() {
if (resetPasswordRequest.readyState == 4 && resetPasswordRequest.status == 200) {
if (resetPasswordRequest.responseText != "done") {
console.log(resetPasswordRequest.responseText);
alert("Error resetting password.\n\nTry again later.");
return false;
} else {
window.location = "./";
}
}
}
resetPasswordRequest.send();
}
function ExplainPublicName() { function ExplainPublicName() {
alert("This is the name we greet you with. It's also the name displayed if you ever decide to share any of your dictionaries.\n\nNote: this is not a username, and as such is not guaranteed to be unique. Use something people will recognize you as to differentiate from other people who might use the same name!"); alert("This is the name we greet you with. It's also the name displayed if you ever decide to share any of your dictionaries.\n\nNote: this is not a username, and as such is not guaranteed to be unique. Use something people will recognize you as to differentiate from other people who might use the same name!");
} }
@ -168,18 +253,13 @@ function ToggleSearchFilter() {
} }
} }
function ShowInfo(text) { function ShowInfo(variableName) {
if (text == "terms") { document.getElementById("infoText").innerHTML = window[variableName];
document.getElementById("infoText").innerHTML = termsText; if (variableName == "loginForm") {
} else if (text == "privacy") { // document.getElementById("infoText").innerHTML = loginForm;
document.getElementById("infoText").innerHTML = privacyText;
} else if (text == "login") {
document.getElementById("infoText").innerHTML = loginForm;
if (currentDictionary.words.length > 0 || currentDictionary.name != "New" || currentDictionary.description != "A new dictionary.") { if (currentDictionary.words.length > 0 || currentDictionary.name != "New" || currentDictionary.description != "A new dictionary.") {
document.getElementById("dictionaryWarn").innerHTML = "If your current dictionary is not already saved to your account, be sure to <span class='exportWarnText' onclick='ExportDictionary()'>export it before logging in</span> so you don't lose anything!"; document.getElementById("dictionaryWarn").innerHTML = "If your current dictionary is not already saved to your account, be sure to <span class='exportWarnText' onclick='ExportDictionary()'>export it before logging in</span> so you don't lose anything!";
} }
} else {
document.getElementById("infoText").innerHTML = aboutText;
} }
document.getElementById("infoPage").scrollTop = 0; document.getElementById("infoPage").scrollTop = 0;
document.getElementById("infoScreen").style.display = "block"; document.getElementById("infoScreen").style.display = "block";
@ -189,6 +269,14 @@ function HideInfo() {
document.getElementById("infoScreen").style.display = "none"; document.getElementById("infoScreen").style.display = "none";
} }
function ShowAccountSettings(variableName) {
document.getElementById("accountSettingsScreen").style.display = "block";
}
function HideAccountSettings() {
document.getElementById("accountSettingsScreen").style.display = "none";
}
function ShowDictionaryDeleteMenu(dictionaryList) { function ShowDictionaryDeleteMenu(dictionaryList) {
document.getElementById('loadAfterDeleteScreen').style.display = 'block'; document.getElementById('loadAfterDeleteScreen').style.display = 'block';
//Parse response into the list that forces you to load one and reload select in settings. //Parse response into the list that forces you to load one and reload select in settings.

View File

@ -0,0 +1,13 @@
<?php
// require_once("../required.php");
require_once('config.php');
require_once(SITE_LOCATION . '/php/functions.php');
$email = htmlspecialchars($_GET['email']);
if (EmailExists($email)) {
echo "email exists";
} else {
echo "bad email";
}
?>

View File

@ -4,6 +4,6 @@
require_once(SITE_LOCATION . '/php/helpers.php'); require_once(SITE_LOCATION . '/php/helpers.php');
require_once(SITE_LOCATION . '/php/plugins/easycrypt.php'); require_once(SITE_LOCATION . '/php/plugins/easycrypt.php');
require_once(SITE_LOCATION . '/php/validation.php'); require_once(SITE_LOCATION . '/php/validation.php');
require_once(SITE_LOCATION . '/php/ajax_passwordresetvalidation.php'); require_once(SITE_LOCATION . '/php/passwordreset.php');
?> ?>

View File

@ -0,0 +1,210 @@
<?php
// Notification messages based on status.
if (isset($_SESSION['current_status']) && $_SESSION['current_status'] != "") {
switch ($_SESSION['current_status']) {
case "couldnotcreate":
$notificationMessage = "Could not create account.<br>Please try again later.";
break;
case "emailcreateinvalid":
$notificationMessage = "The email address used to create your account didn't work.<br>Please try another.";
break;
case "createemailorpasswordblank":
$notificationMessage = "The create account form somehow got submitted without some essential information.<br>Please try filling it out again.";
break;
case "couldnotsendresetemail":
$notificationMessage = "For some reason, the reset email could not be sent.<br>Please try again later.";
break;
case "couldnotsetresetlink":
$notificationMessage = "The email address specified for password reset does not have an account.";
break;
case "emailresetinvalid":
$notificationMessage = "The email address specified for password reset didn't work.<br>Please try again.";
break;
case "resetemailblank":
$notificationMessage = "The password reset form somehow got submitted without some essential information.<br>Please try filling it out again.";
break;
case "loginfailed":
$notificationMessage = "We couldn't log you in because your email or password was incorrect.<br>";
$_SESSION['loginfailures'] += 1;
if ($_SESSION['loginfailures'] < 10) {
$notificationMessage .= "This is your <strong>" . ordinal($_SESSION['loginfailures']) . "</strong> failed attempt.<br>After 10 failures, you will not be able to log in for 1 hour.<br>Please try again.";
} else {
$_SESSION['loginlockouttime'] = time();
$notificationMessage .= "Since you failed to log in successfully 10 times, you may not try again for 1 hour.";
}
break;
case "emaildoesnotexist":
$notificationMessage = "The email address you entered doesn't have an account.<br>Would you like to <span class='clickable' onclick='ShowInfo(\"loginForm\")'>create an account</span>?";
break;
case "emailinvalid":
$notificationMessage = "The email address you entered didn't work.<br>Please try another.";
break;
case "resetlinkfailed":
$notificationMessage = "The reset link used is not valid. Please make sure you have copied it correctly.";
break;
case "resetlinkinvalid":
$notificationMessage = "The reset link used is not valid. Please make sure you have copied it correctly.";
break;
case "couldnotresetpassword":
$notificationMessage = "Your password could not be reset at this time. Please try again later.<br>If you remember your old password, you may still use it to log in.";
break;
case "passwordresetinvalid":
$notificationMessage = "Something went wrong in the password reset process. Please try again.";
break;
case "newpasswordblank":
$notificationMessage = "All the necessary information did not make it through for your password reset. Please try again.";
break;
case "couldnotupdatesettings":
$notificationMessage = "Could not update your account settings. Please try again.";
break;
case "accountsettingsinvalid":
$notificationMessage = "The email address you entered was either not valid or is already in use by another user. Please choose a different email address if you want to update your account email.";
break;
case "createdaccountsuccessfully":
$notificationMessage = "Your account was created successfully!<br>Please log in using the email address and password you used to create it and you can start accessing your dictionaries anywhere!";
break;
case "resetemailsent":
$notificationMessage = "The password reset link has been sent to the email you specified.<br>If you do not see it in your inbox, please check your junk mail box just in case!<br>Be sure to use the link before the end of today or else you will need to request a new one.";
break;
case "showresetform":
$notificationMessage = '<script>document.getElementById("notificationCloseButton").style.display = "none";</script>
<form id="resetPasswordForm" method="post" action="?resetpassword" style="text-align:left;">
<h2 style="margin-top: 3px;">Reset Your Password</h2>
<label><span>New Password</span>
<input type="password" id="newPasswordField" name="password" />
</label>
<label><span>Confirm Password</span>
<input type="password" id="newPasswordConfirmField" name="confirmpassword" />
</label>
<input type="hidden" name="account" value="' . Get_User_Email($_SESSION['reset_account']) . '" />
<div id="resetPasswordError" style="font-weight:bold;color:red;"></div>
<button type="submit" id="createAccountSubmitButton" onclick="ValidateResetPassword(); return false;">Set New Password</button>
</form>';
break;
case "passwordresetsuccessfully":
$notificationMessage = "Your password has been successfully reset. You may now log in using your new password.";
break;
case "accountsettingsupdated":
$notificationMessage = "Your settings have been updated.";
break;
}
$_SESSION['current_status'] = "";
}
if (isset($_GET['logout']) && $current_user > 0) {
session_destroy();
header('Location: ./?loggedout');
}
elseif (isset($_GET['login']) && $current_user <= 0) {
if (isset($_POST['email']) && isset($_POST['password'])) {
if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
if (EmailExists($_POST['email'])) {
if (Validate_Login($_POST['email'], $_POST['password'])) {
$_SESSION['user'] = Get_User_Id($_POST['email']);
} else {
$_SESSION['current_status'] = "loginfailed";
}
} else {
$_SESSION['current_status'] = "emaildoesnotexist";
}
} else {
$_SESSION['current_status'] = "emailinvalid";
}
} else {
$_SESSION['current_status'] = "loginemailorpasswordblank";
}
header('Location: ./');
}
elseif (isset($_GET['createaccount'])) {
if (isset($_POST['email']) && isset($_POST['password'])) {
if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) && !EmailExists($_POST['email'])) {
if (query("INSERT INTO users (email, password, public_name, allow_email) VALUES ('" . $_POST['email'] . "','" . crypt($_POST['password'], $_POST['email']) . "','" . htmlspecialchars($_POST['publicname'], ENT_QUOTES) . "'," . (($_POST['allowemails'] != "on") ? 0 : 1) . ")")) {
$_SESSION['current_status'] = "createdaccountsuccessfully";
} else {
$_SESSION['current_status'] = "couldnotcreate";
}
} else {
$_SESSION['current_status'] = "emailcreateinvalid";
}
} else {
$_SESSION['current_status'] = "createemailorpasswordblank";
}
header('Location: ./');
}
elseif (isset($_GET['forgot'])) {
if (isset($_POST['email'])) {
if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) && EmailExists($_POST['email'])) {
$reset_email = Set_Password_Reset($_POST['email']);
if ($reset_email === true) {
$_SESSION['current_status'] = "resetemailsent";
} elseif ($reset_email === "could not send") {
$_SESSION['current_status'] = "couldnotsendresetemail";
} else {
$_SESSION['current_status'] = "couldnotsetresetlink";
}
} else {
$_SESSION['current_status'] = "emailresetinvalid";
}
} else {
$_SESSION['current_status'] = "resetemailblank";
}
header('Location: ./');
}
elseif (isset($_GET['passwordreset'])) {
if (isset($_GET['account']) && isset($_GET['code'])) {
$reset_email = Check_Password_Reset($_GET['account'], $_GET['code']);
if ($reset_email == true) {
$_SESSION['current_status'] = "showresetform";
$_SESSION['reset_account'] = $_GET['account'];
} else {
$_SESSION['current_status'] = "resetlinkfailed";
}
} else {
$_SESSION['current_status'] = "resetlinkinvalid";
}
header('Location: ./');
}
elseif (isset($_GET['resetpassword'])) {
if (isset($_POST['account']) && isset($_POST['password'])) {
if (filter_var($_POST['account'], FILTER_VALIDATE_EMAIL) && EmailExists($_POST['account'])) {
$reset_password_success = Reset_Password($_POST['password'], $_POST['account']);
if ($reset_password_success == true) {
$_SESSION['current_status'] = "passwordresetsuccessfully";
} else {
$_SESSION['current_status'] = "couldnotresetpassword";
}
} else {
$_SESSION['current_status'] = "passwordresetinvalid";
}
} else {
$_SESSION['current_status'] = "newpasswordblank";
}
header('Location: ./');
}
elseif (isset($_GET['accountsettings'])) {
if (filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) &&
($_POST['email'] == Get_User_Email($current_user) || !EmailExists($_POST['email'])))
{
$public_name = (isset($_POST['publicname']) && $_POST['publicname'] != "") ? $_POST['publicname'] : "Someone";
if (query("UPDATE `users` SET `email`='" . $_POST['email'] . "', `public_name`='" . htmlspecialchars($public_name, ENT_QUOTES) . "', `allow_email`=" . (($_POST['allowemails'] != "on") ? 0 : 1) . " WHERE `id`=" . $current_user . ";")) {
$_SESSION['current_status'] = "accountsettingsupdated";
} else {
$_SESSION['current_status'] = "couldnotupdatesettings";
}
} else {
$_SESSION['current_status'] = "accountsettingsinvalid";
}
header('Location: ./');
}
elseif (isset($_GET['loggedout']) && $current_user <= 0) {
$notificationMessage = "You have been successfully logged out.<br>You will only be able to use the dictionary saved to your browser.";
} elseif ($current_user > 0) {
if ($notificationMessage != "") {
$notificationMessage = "Welcome back, " . Get_Public_Name_By_Id($current_user) . "!<br>" . $notificationMessage;
} else {
$notificationMessage = "Welcome back, " . Get_Public_Name_By_Id($current_user) . "!";
}
}
?>

View File

@ -2,18 +2,20 @@
function Set_Password_Reset($email) { function Set_Password_Reset($email) {
$date = date("Y-m-d H:i:s"); $date = date("Y-m-d H:i:s");
$reset_code = random_string(20); $reset_code = random_string(20);
$query = "UPDATE `users` SET `password_reset_code`=" . $reset_code . ", `password_reset_date`='" . $date . "' WHERE `email`='" . $email . ";"; $query = "UPDATE `users` SET `password_reset_code`='" . $reset_code . "', `password_reset_date`='" . $date . "' WHERE `email`='" . $email . "';";
$reset = query($query); $reset = query($query);
if ($reset) { if ($reset) {
$to = $email; $to = $email;
$subject = "Here's your Lexiconga password reset link"; $subject = "Here's your Lexiconga password reset link";
$message = "Hello " . Get_Public_Name(Get_User_Id($email)) . "\n\nSomeone has requested a password reset link for your Lexiconga account. If it was you, you can reset your password by going to the link below and entering a new password for yourself:\n"; $message = "Hello " . Get_Public_Name_By_Email($email) . "\r\n\r\nSomeone has requested a password reset link for your Lexiconga account. If it was you, you can reset your password by going to the link below and entering a new password for yourself:\r\n";
$message .= "http://lexicon.ga/?action=passwordreset&code=" . $reset_code . "\n\n"; $message .= "http://lexicon.ga/?passwordreset&account=" . Get_User_Id($email) . "&code=" . $reset_code . "\r\n\r\n";
$message .= "If it wasn't you who requested the link, you can ignore this email since it was only sent to you, but you might want to consider changing your password when you have a chance.\n\n"; $message .= "If it wasn't you who requested the link, you can ignore this email since it was only sent to you, but you might want to consider changing your password when you have a chance.\r\n\r\n";
$message .= "The password link will only be valid for today until you use it.\n\n"; $message .= "The password link will only be valid for today until you use it.\r\n\r\n";
$message .= "Thanks!\nThe Lexiconga Admins"; $message .= "Thanks!\r\nThe Lexiconga Admins";
$header = "From: help@lexicon.ga\r\n"; $header = "From: Lexiconga Password Reset <donotreply@lexicon.ga>\r\n" .
"Reply-To: help@lexicon.ga\r\n" .
"X-Mailer: PHP/" . phpversion();
if (mail($to, $subject, $message, $header)) { if (mail($to, $subject, $message, $header)) {
return true; return true;
@ -25,10 +27,10 @@ function Set_Password_Reset($email) {
} }
} }
function Check_Password_Reset($email, $code) { function Check_Password_Reset($id, $code) {
$date = date("Y-m-d"); $date = date("Y-m-d");
$daterange = "'" . $date . " 00:00:00' AND '" . $date . " 23:59:59'"; $daterange = "'" . $date . " 00:00:00' AND '" . $date . " 23:59:59'";
$query = "SELECT * FROM `users` WHERE `email`='" . $email . "' AND `password_reset_code`='" . $code . "' AND `password_reset_date` BETWEEN " . $daterange . ";"; $query = "SELECT * FROM `users` WHERE `id`='" . $id . "' AND `password_reset_code`='" . $code . "' AND `password_reset_date` BETWEEN " . $daterange . ";";
$users = query($query); $users = query($query);
if ($users && num_rows($users) === 1) { if ($users && num_rows($users) === 1) {
@ -39,7 +41,7 @@ function Check_Password_Reset($email, $code) {
} }
function Reset_Password($password, $email) { function Reset_Password($password, $email) {
$query = "UPDATE `users` SET `password`=" . crypt($password, $email) . ", `password_reset_date`='0000-00-00 00:00:00' WHERE `email`='" . $email . ";"; $query = "UPDATE `users` SET `password`='" . crypt($password, $email) . "', `password_reset_date`='0000-00-00 00:00:00' WHERE `email`='" . $email . "';";
$reset = query($query); $reset = query($query);
if ($reset) { if ($reset) {

View File

@ -1,6 +1,6 @@
<?php <?php
function EmailExists($email) { function EmailExists($email) {
$query = "SELECT * FROM users WHERE email='" . $email . "'"; $query = "SELECT * FROM `users` WHERE `email`='" . $email . "'";
$users = query($query); $users = query($query);
if ($users && num_rows($users) > 0) { if ($users && num_rows($users) > 0) {
@ -12,7 +12,7 @@ function EmailExists($email) {
function Validate_Login($email, $password) { function Validate_Login($email, $password) {
$hashed_pw = crypt($password, $email); $hashed_pw = crypt($password, $email);
$query = "SELECT * FROM users WHERE email='" . $email . "' AND password='" . $hashed_pw . "'"; $query = "SELECT * FROM `users` WHERE `email`='" . $email . "' AND `password`='" . $hashed_pw . "'";
$users = query($query); $users = query($query);
if ($users && num_rows($users) === 1) { if ($users && num_rows($users) === 1) {
@ -23,7 +23,7 @@ function Validate_Login($email, $password) {
} }
function Get_User_Id($email) { function Get_User_Id($email) {
$query = "SELECT id FROM users WHERE email='" . $email . "'"; $query = "SELECT `id` FROM `users` WHERE `email`='" . $email . "'";
$users = query($query); $users = query($query);
if ($users && num_rows($users) > 0) { if ($users && num_rows($users) > 0) {
@ -38,8 +38,24 @@ function Get_User_Id($email) {
} }
} }
function Get_Public_Name($id) { function Get_User_Email($id) {
$query = "SELECT public_name FROM users WHERE id=" . $id; $query = "SELECT `email` FROM `users` WHERE `id`='" . $id . "'";
$users = query($query);
if ($users && num_rows($users) > 0) {
if (num_rows($users) === 1) {
$user = fetch($users);
return $user["email"];
} else {
return "More than one user id returned!";
}
} else {
return "No User";
}
}
function Get_Public_Name_By_Id($id) {
$query = "SELECT `public_name` FROM `users` WHERE `id`=" . $id . ";";
$users = query($query); $users = query($query);
if ($users && num_rows($users) > 0) { if ($users && num_rows($users) > 0) {
@ -53,4 +69,36 @@ function Get_Public_Name($id) {
return "No User"; return "No User";
} }
} }
function Get_Public_Name_By_Email($email) {
$query = "SELECT `public_name` FROM `users` WHERE `email`='" . $email . "';";
$users = query($query);
if ($users && num_rows($users) > 0) {
if (num_rows($users) === 1) {
$user = fetch($users);
return $user["public_name"];
} else {
return "More than one public name returned!";
}
} else {
return "No User";
}
}
function Get_Allow_Email_By_Id($id) {
$query = "SELECT `allow_email` FROM `users` WHERE `id`=" . $id . ";";
$users = query($query);
if ($users && num_rows($users) > 0) {
if (num_rows($users) === 1) {
$user = fetch($users);
return $user["allow_email"];
} else {
return "More than one user returned!";
}
} else {
return "No User";
}
}
?> ?>