diff --git a/cron.php b/cron.php index 8723dfc2..bca3f068 100644 --- a/cron.php +++ b/cron.php @@ -200,6 +200,9 @@ while($row = mysqli_fetch_array($sql_companies)){ // Clean-up shared items that have expired mysqli_query($mysqli, "DELETE FROM shared_items WHERE item_expire_at < NOW()"); + // Invalidate any password reset links + mysqli_query($mysqli, "UPDATE contacts SET contact_password_reset_token = NULL WHERE contact_archived_at IS NULL"); + // PAST DUE INVOICE Notifications //$invoiceAlertArray = [$config_invoice_overdue_reminders]; $invoiceAlertArray = [30,60,90,120,150,180,210,240,270,300,330,360,390,420,450,480,510,540,570,590,620]; diff --git a/database_updates.php b/database_updates.php index 94a28d37..6c69dec6 100644 --- a/database_updates.php +++ b/database_updates.php @@ -180,7 +180,7 @@ if(LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION){ mysqli_query($mysqli, "ALTER TABLE contacts ADD contact_department VARCHAR(200) NULL AFTER contact_title"); mysqli_query($mysqli, "DROP TABLE departments"); mysqli_query($mysqli, "ALTER TABLE contacts DROP contact_department_id"); - + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.0.7'"); } @@ -248,11 +248,11 @@ if(LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION){ mysqli_query($mysqli, "CREATE TABLE `asset_documents` (`asset_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`asset_id`,`document_id`))"); mysqli_query($mysqli, "CREATE TABLE `asset_logins` (`asset_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`asset_id`,`login_id`))"); mysqli_query($mysqli, "CREATE TABLE `asset_files` (`asset_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`asset_id`,`file_id`))"); - + mysqli_query($mysqli, "CREATE TABLE `contact_documents` (`contact_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`contact_id`,`document_id`))"); mysqli_query($mysqli, "CREATE TABLE `contact_logins` (`contact_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`contact_id`,`login_id`))"); mysqli_query($mysqli, "CREATE TABLE `contact_files` (`contact_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`contact_id`,`file_id`))"); - + mysqli_query($mysqli, "CREATE TABLE `software_documents` (`software_id` int(11) NOT NULL,`document_id` int(11) NOT NULL, PRIMARY KEY (`software_id`,`document_id`))"); mysqli_query($mysqli, "CREATE TABLE `software_logins` (`software_id` int(11) NOT NULL,`login_id` int(11) NOT NULL, PRIMARY KEY (`software_id`,`login_id`))"); mysqli_query($mysqli, "CREATE TABLE `software_files` (`software_id` int(11) NOT NULL,`file_id` int(11) NOT NULL, PRIMARY KEY (`software_id`,`file_id`))"); @@ -290,12 +290,12 @@ if(LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION){ } if(CURRENT_DATABASE_VERSION == '0.1.5'){ - // Insert queries here required to update to DB version 0.1.6 + // Insert queries here required to update to DB version 0.1.6 // Remove Mailing List Tables mysqli_query($mysqli, "DROP TABLE campaigns"); mysqli_query($mysqli, "DROP TABLE campaign_messages"); - // Then, update the database to the next sequential version + // Then, update the database to the next sequential version mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.6'"); } @@ -308,29 +308,38 @@ if(LATEST_DATABASE_VERSION > CURRENT_DATABASE_VERSION){ } if(CURRENT_DATABASE_VERSION == '0.1.7'){ - // Insert queries here required to update to DB version 0.1.8 + // Insert queries here required to update to DB version 0.1.8 mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_backup_enable`"); mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_backup_path`"); - // Then, update the database to the next sequential version + // Then, update the database to the next sequential version mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.8'"); } - //if(CURRENT_DATABASE_VERSION == '0.1.8'){ - // Insert queries here required to update to DB version 0.1.9 + if(CURRENT_DATABASE_VERSION == '0.1.8'){ + // Insert queries here required to update to DB version 0.1.9 mysqli_query($mysqli, "ALTER TABLE `settings` DROP `config_base_url`"); - // Then, update the database to the next sequential version + // Then, update the database to the next sequential version mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.1.9'"); - //} + } - //if(CURRENT_DATABASE_VERSION == '0.1.9'){ - // Insert queries here required to update to DB version 0.2.0 + if(CURRENT_DATABASE_VERSION == '0.1.9'){ + // Insert queries here required to update to DB version 0.2.0 + // Allow contacts to reset their portal password + mysqli_query($mysqli, "ALTER TABLE contacts ADD contact_password_reset_token VARCHAR(200) NULL DEFAULT NULL AFTER contact_password_hash"); - // Then, update the database to the next sequential version - // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.2.0'"); - //} + // Then, update the database to the next sequential version + mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.2.0'"); + } -} -else{ - // Up-to-date -} \ No newline at end of file + //if(CURRENT_DATABASE_VERSION == '0.2.0'){ + // Insert queries here required to update to DB version 0.2.1 + + // Then, update the database to the next sequential version + // mysqli_query($mysqli, "UPDATE `settings` SET `config_current_database_version` = '0.2.1'"); + //} + + } + else{ + // Up-to-date + } \ No newline at end of file diff --git a/database_version.php b/database_version.php index d0c9cc7e..c1288154 100644 --- a/database_version.php +++ b/database_version.php @@ -5,4 +5,4 @@ * It is used in conjunction with database_updates.php */ -DEFINE("LATEST_DATABASE_VERSION", "0.1.9"); \ No newline at end of file +DEFINE("LATEST_DATABASE_VERSION", "0.2.0"); \ No newline at end of file diff --git a/db.sql b/db.sql index a80cd772..2f7417b5 100644 --- a/db.sql +++ b/db.sql @@ -327,6 +327,7 @@ CREATE TABLE `contacts` ( `contact_notes` text DEFAULT NULL, `contact_auth_method` varchar(200) DEFAULT NULL, `contact_password_hash` varchar(200) DEFAULT NULL, + `contact_password_reset_token` varchar(200) DEFAULT NULL, `contact_important` tinyint(1) NOT NULL DEFAULT 0, `contact_created_at` datetime NOT NULL DEFAULT current_timestamp(), `contact_updated_at` datetime DEFAULT NULL ON UPDATE current_timestamp(), diff --git a/portal/login.php b/portal/login.php index 9c1cb350..ff10e1ce 100644 --- a/portal/login.php +++ b/portal/login.php @@ -4,8 +4,10 @@ * Landing / Home page for the client portal */ -include('../config.php'); -include('../functions.php'); +$session_company_id = 1; +require_once('../config.php'); +require_once('../functions.php'); +require_once ('../get_settings.php'); if(!isset($_SESSION)){ // HTTP Only cookies @@ -121,6 +123,11 @@ if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['login'])){ + + Forgotten password? + + SMTPDebug = false; // No debug output as client facing + $mail->isSMTP(); // Set mailer to use SMTP + $mail->Host = $config_smtp_host; // Specify main and backup SMTP servers + $mail->SMTPAuth = true; // Enable SMTP authentication + $mail->Username = $config_smtp_username; // SMTP username + $mail->Password = $config_smtp_password; // SMTP password + $mail->SMTPSecure = $config_smtp_encryption; // Enable TLS encryption, `ssl` also accepted + $mail->Port = $config_smtp_port; // TCP port to connect to + + //Recipients + $mail->setFrom($config_mail_from_email, $config_mail_from_name); + $mail->addAddress("$email", "$name"); // Add user as recipient + + // Content + $mail->isHTML(true); // Set email format to HTML + + $mail->Subject = "Password reset for $company_name ITFlow Portal"; + $mail->Body = "Hello, $name

Someone (probably you) has requested a new password for your account on $company_name's ITFlow Client Portal.

Please click here to reset your password.

Alternatively, copy and paste this URL into your browser: $url

If you didn't request this change, you can safely ignore this email.

~
$company_name
Support Department
$config_mail_from_email"; + $mail->send(); + } + catch(Exception $e){ + echo "Message could not be sent. Please contact $company_name."; + mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Contact', log_action = 'Modify', log_description = 'FAILED to send a portal password reset e-mail for $email due to PHP Mailer error.', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client, company_id = $company"); + exit(); + } + //End Mail IF Try-Catch + } else { + sleep(rand(2, 4)); // Mimic the e-mail send delay even if email is invalid to help prevent user enumeration + } + + $_SESSION['login_message'] = "If your account exists, a reset link is on it's way!"; + + /* + * Do password reset + */ + } + elseif(isset($_POST['password_reset_set_password'])){ + + if(!isset($_POST['new_password']) || !isset($_POST['email']) || !isset($_POST['token']) || !isset($_POST['client'])) { + $_SESSION['login_message'] = WORDING_ERROR; + } + + $token = strip_tags(mysqli_real_escape_string($mysqli, $_POST['token'])); + $email = strip_tags(mysqli_real_escape_string($mysqli, $_POST['email'])); + $client = intval(strip_tags(mysqli_real_escape_string($mysqli, $_POST['client']))); + + // Query user + $sql = mysqli_query($mysqli, "SELECT * FROM contacts WHERE contact_email = '$email' AND contact_password_reset_token = '$token' AND contact_client_id = $client AND contact_auth_method = 'local' LIMIT 1"); + $contact_row = mysqli_fetch_array($sql); + $contact_id = $contact_row['contact_id']; + $name = $contact_row['contact_name']; + $company = $contact_row['company_id']; + + // Ensure the token is correct + if (sha1($contact_row['contact_password_reset_token']) == sha1($token)) { + + // Set password, invalidate token, logging + $password = mysqli_real_escape_string($mysqli, password_hash($_POST['new_password'], PASSWORD_DEFAULT)); + mysqli_query($mysqli, "UPDATE contacts SET contact_password_hash = '$password', contact_password_reset_token = NULL WHERE contact_id = $contact_id LIMIT 1"); + mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Contact', log_action = 'Modify', log_description = 'Reset portal password for $email.', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client, company_id = $company"); + + // Send confirmation email + $mail = new PHPMailer(true); + + try{ + //Mail Server Settings + $mail->SMTPDebug = false; // No debug output as client facing + $mail->isSMTP(); // Set mailer to use SMTP + $mail->Host = $config_smtp_host; // Specify main and backup SMTP servers + $mail->SMTPAuth = true; // Enable SMTP authentication + $mail->Username = $config_smtp_username; // SMTP username + $mail->Password = $config_smtp_password; // SMTP password + $mail->SMTPSecure = $config_smtp_encryption; // Enable TLS encryption, `ssl` also accepted + $mail->Port = $config_smtp_port; // TCP port to connect to + + //Recipients + $mail->setFrom($config_mail_from_email, $config_mail_from_name); + $mail->addAddress("$email", "$name"); // Add user as recipient + + // Content + $mail->isHTML(true); // Set email format to HTML + + $mail->Subject = "Password reset confirmation for $company_name ITFlow Portal"; + $mail->Body = "Hello, $name

Your password for your account on $company_name's ITFlow Client Portal was successfully reset. You should be all set!

If you didn't reset your password, please get in touch ASAP.

~
$company_name
Support Department
$config_mail_from_email"; + $mail->send(); + } + catch(Exception $e){ + echo "Message could not be sent. Please contact $company_name."; + mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Contact', log_action = 'Modify', log_description = 'FAILED to send a password reset e-mail for $email due to PHP Mailer error.', log_ip = '$ip', log_user_agent = '$user_agent', log_created_at = NOW(), log_client_id = $client, company_id = $company"); + exit(); + } + //End Mail IF Try-Catch + + // Redirect to login page + $_SESSION['login_message'] = "Password reset successfully!"; + header("Location: login.php"); + exit(); + + } else { + $_SESSION['login_message'] = WORDING_ERROR; + } + + + } + + +} + +?> + + + + + + <?php echo $company_name; ?> | Password Reset + + + + + + + + + + + + + + + + +
+ +
+ + + +
+ + +
+ + + + + + + + + + + + + + + + \ No newline at end of file