diff --git a/index.php b/index.php
index 3532d639..19b527f2 100644
--- a/index.php
+++ b/index.php
@@ -240,6 +240,12 @@ if ($action == 'login') {
case 5:
$message = $lng['error']['user_banned'];
break;
+ case 6:
+ $successmessage = $lng['pwdreminder']['changed'];
+ break;
+ case 7:
+ $message = $lng['pwdreminder']['wrongcode'];
+ break;
}
$update_in_progress = '';
@@ -265,7 +271,7 @@ if ($action == 'forgotpwd') {
Database::pexecute($result_stmt, array("loginname" => $loginname, "email" => $email));
if (Database::num_rows() == 0) {
- $result_stmt = Database::prepare("SELECT `adminid`, `name`, `email`, `loginname`, `def_language` FROM `" . TABLE_PANEL_ADMINS . "`
+ $result_stmt = Database::prepare("SELECT `adminid`, `name`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_ADMINS . "`
WHERE `loginname`= :loginname
AND `email`= :email"
);
@@ -289,35 +295,53 @@ if ($action == 'forgotpwd') {
if (($adminchecked && $settings['panel']['allow_preset_admin'] == '1') || $adminchecked == false) {
if ($user !== false) {
- if ($settings['panel']['password_min_length'] <= 6) {
- $password = substr(md5(uniqid(microtime(), 1)), 12, 6);
- } else {
- // make it two times larger than password_min_length
- $rnd = '';
- $minlength = $settings['panel']['password_min_length'];
- while (strlen($rnd) < ($minlength * 2)) {
- $rnd .= md5(uniqid(microtime(), 1));
- }
- $password = substr($rnd, (int)($minlength / 2), $minlength);
- }
-
- $passwordTable = $adminchecked ? TABLE_PANEL_ADMINS : TABLE_PANEL_CUSTOMERS;
- $stmt = Database::prepare("UPDATE `" . $passwordTable . "` SET `password`= :password
- WHERE `loginname`= :loginname
- AND `email`= :email"
+ // build a activation code
+ $timestamp = time();
+ $first = substr(md5($user['loginname'] . $timestamp), 0, 15);
+ $third = substr(md5($user['email'] . $timestamp), -15);
+ $activationcode = $first . $timestamp . $third . substr(md5($third . $timestamp), 0, 10);
+
+ // Drop all existing activation codes for this user
+ $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "`
+ WHERE `userid` = :userid
+ AND `admin` = :admin"
);
- Database::pexecute($stmt, array("password" => md5($password), "loginname" => $user['loginname'], "email" => $user['email']));
+ $params = array(
+ "userid" => $adminchecked ? $user['adminid'] : $user['customerid'],
+ "admin" => $adminchecked ? 1 : 0
+ );
+ Database::pexecute($stmt, $params);
+
+ // Add new activation code to database
+ $stmt = Database::prepare("INSERT INTO `" . TABLE_PANEL_ACTIVATION . "`
+ (userid, admin, creation, activationcode)
+ VALUES (:userid, :admin, :creation, :activationcode)"
+ );
+ $params = array(
+ "userid" => $adminchecked ? $user['adminid'] : $user['customerid'],
+ "admin" => $adminchecked ? 1 : 0,
+ "creation" => $timestamp,
+ "activationcode" => $activationcode
+ );
+ Database::pexecute($stmt, $params);
$rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset'), $settings);
- $rstlog->logAction(USR_ACTION, LOG_WARNING, "Password for user '" . $user['loginname'] . "' has been reset!");
-
+ $rstlog->logAction(USR_ACTION, LOG_WARNING, "User '" . $user['loginname'] . "' requested a link for setting a new password.");
+
+ // Set together our activation link
+ $protocol = strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
+ $host = $_SERVER['HTTP_HOST'];
+ $port = $_SERVER['SERVER_PORT'] != 80 ? ':' . $_SERVER['SERVER_PORT'] : '';
+ $script = $_SERVER['SCRIPT_NAME'];
+ $activationlink = $protocol . '://' . $host . $port . $script . '?action=resetpwd&resetcode=' . $activationcode;
+
$replace_arr = array(
'SALUTATION' => getCorrectUserSalutation($user),
'USERNAME' => $user['loginname'],
- 'PASSWORD' => $password
+ 'LINK' => $activationlink
);
- $body = strtr($lng['pwdreminder']['body'], array('%s' => $user['firstname'] . ' ' . $user['name'], '%p' => $password));
+ $body = strtr($lng['pwdreminder']['body'], array('%s' => $user['firstname'] . ' ' . $user['name'], '%a' => $activationlink));
$def_language = ($user['def_language'] != '') ? $user['def_language'] : $settings['panel']['standardlanguage'];
$result_stmt = Database::prepare('SELECT `value` FROM `' . TABLE_PANEL_TEMPLATES . '`
@@ -339,7 +363,7 @@ if ($action == 'forgotpwd') {
Database::pexecute($result_stmt, array("adminid" => $user['adminid'], "lang" => $def_language));
$result = $result_stmt->fetch(PDO::FETCH_ASSOC);
$mail_body = html_entity_decode(replace_variables((($result['value'] != '') ? $result['value'] : $body), $replace_arr));
-
+
$_mailerror = false;
try {
$mail->Subject = $mail_subject;
@@ -358,16 +382,16 @@ if ($action == 'forgotpwd') {
if ($_mailerror) {
$rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset'), $settings);
$rstlog->logAction(ADM_ACTION, LOG_ERR, "Error sending mail: " . $mailerr_msg);
- redirectTo('index.php', Array('showmessage' => '4', 'customermail' => $user['email']), true);
+ redirectTo('index.php', array('showmessage' => '4', 'customermail' => $user['email']), true);
exit;
}
$mail->ClearAddresses();
- redirectTo('index.php', Array('showmessage' => '1'), true);
+ redirectTo('index.php', array('showmessage' => '1'), true);
exit;
} else {
$rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset'), $settings);
- $rstlog->logAction(USR_ACTION, LOG_WARNING, "User '" . $loginname . "' tried to reset pwd but wasn't found in database!");
+ $rstlog->logAction(USR_ACTION, LOG_WARNING, "User '" . $loginname . "' requested to set a new password, but was not found in database!");
$message = $lng['login']['combination_not_found'];
}
@@ -391,3 +415,77 @@ if ($action == 'forgotpwd') {
eval("echo \"" . getTemplate('fpwd') . "\";");
}
+
+if ($action == 'resetpwd') {
+ $message = '';
+
+ if (isset($_GET['resetcode']) && strlen($_GET['resetcode']) == 50) {
+ // Check if activation code is valid
+ $activationcode = $_GET['resetcode'];
+ $timestamp = substr($activationcode, 15, 10);
+ $third = substr($activationcode, 25, 15);
+ $check = substr($activationcode, 40, 10);
+
+ if (substr(md5($third . $timestamp), 0, 10) == $check && $timestamp >= time() - 86400) {
+ if (isset($_POST['send']) && $_POST['send'] == 'send') {
+ $stmt = Database::prepare("SELECT `userid`, `admin` FROM `" . TABLE_PANEL_ACTIVATION . "`
+ WHERE `activationcode` = :activationcode"
+ );
+ $result = Database::pexecute_first($stmt, array("activationcode" => $activationcode));
+
+ if ($result !== false) {
+ if ($result['admin'] == 1) {
+ $new_password = validate($_POST['new_password'], 'new password');
+ $new_password_confirm = validate($_POST['new_password_confirm'], 'new password confirm');
+ } else {
+ $new_password = validatePassword($_POST['new_password'], 'new password');
+ $new_password_confirm = validatePassword($_POST['new_password_confirm'], 'new password confirm');
+ }
+
+ if ($new_password == '') {
+ $message = $new_password;
+ } elseif($new_password_confirm == '') {
+ $message = $new_password_confirm;
+ } elseif($new_password != $new_password_confirm) {
+ $message = $new_password . " != " . $new_password_confirm;
+ } else {
+ // Update user password
+ if ($result['admin'] == 1) {
+ $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_ADMINS . "`
+ SET `password` = :newpassword
+ WHERE `adminid` = :userid"
+ );
+ } else {
+ $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "`
+ SET `password` = :newpassword
+ WHERE `customerid` = :userid"
+ );
+ }
+ Database::pexecute($stmt, array("newpassword" => md5($new_password), "userid" => $result['userid']));
+
+ $rstlog = FroxlorLogger::getInstanceOf(array('loginname' => 'password_reset'), $settings);
+ $rstlog->logAction(USR_ACTION, LOG_NOTICE, "changed password using password reset.");
+
+ // Remove activation code from DB
+ $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_ACTIVATION . "`
+ WHERE `activationcode` = :activationcode
+ AND `userid` = :userid"
+ );
+ Database::pexecute($stmt, array("activationcode" => $activationcode, "userid" => $result['userid']));
+ redirectTo('index.php', array("showmessage" => '6'), true);
+ }
+ } else {
+ redirectTo('index.php', array("showmessage" => '7'), true);
+ }
+ }
+
+ eval("echo \"" . getTemplate('rpwd') . "\";");
+
+ } else {
+ redirectTo('index.php', array("showmessage" => '7'), true);
+ }
+
+ } else {
+ redirectTo('index.php');
+ }
+}
diff --git a/lib/tables.inc.php b/lib/tables.inc.php
index f5c4aa54..b72de738 100644
--- a/lib/tables.inc.php
+++ b/lib/tables.inc.php
@@ -23,6 +23,7 @@ define('TABLE_FTP_QUOTALIMITS', 'ftp_quotalimits');
define('TABLE_FTP_QUOTATALLIES', 'ftp_quotatallies');
define('TABLE_MAIL_USERS', 'mail_users');
define('TABLE_MAIL_VIRTUAL', 'mail_virtual');
+define('TABLE_PANEL_ACTIVATION', 'panel_activation');
define('TABLE_PANEL_ADMINS', 'panel_admins');
define('TABLE_PANEL_CUSTOMERS', 'panel_customers');
define('TABLE_PANEL_DATABASES', 'panel_databases');
diff --git a/lng/english.lng.php b/lng/english.lng.php
index 8bd8503f..b83f0805 100644
--- a/lng/english.lng.php
+++ b/lng/english.lng.php
@@ -107,7 +107,7 @@ $lng['index']['accountdetails'] = 'Account details';
$lng['changepassword']['old_password'] = 'Old password';
$lng['changepassword']['new_password'] = 'New password';
-$lng['changepassword']['new_password_confirm'] = 'New password (confirm)';
+$lng['changepassword']['new_password_confirm'] = 'Confirm password';
$lng['changepassword']['new_password_ifnotempty'] = 'New password (empty = no change)';
$lng['changepassword']['also_change_ftp'] = ' also change password of the main FTP account';
@@ -851,8 +851,8 @@ $lng['login']['email'] = 'E-mail address';
$lng['login']['remind'] = 'Reset my password';
$lng['login']['usernotfound'] = 'User not found!';
$lng['pwdreminder']['subject'] = 'Froxlor - Password reset';
-$lng['pwdreminder']['body'] = 'Hello %s,\n\nyour froxlor password has been reset!\nThe new password is: %p\n\nThank you,\nyour administrator';
-$lng['pwdreminder']['success'] = 'Password reset successfully.
You now should receive an email with your new password.';
+$lng['pwdreminder']['body'] = 'Hello %s,\n\nhere is your link for setting a new password. This link is valid for the next 24 hours.\n\n%a\n\nThank you,\nyour administrator';
+$lng['pwdreminder']['success'] = 'Password reset successfully requested. Please follow the instructions in the email you received.';
// ADDED IN 1.2.19-svn18
@@ -1981,4 +1981,8 @@ $lng['error']['sslredirectonlypossiblewithsslipport'] = 'Using the SSL redirect
$lng['error']['fcgidstillenableddeadlock'] = 'FCGID is currently active.
Please deactivate it before switching to another webserver than Apache2';
$lng['error']['send_report_title'] = 'Send error report';
$lng['error']['send_report_desc'] = 'Thank you for reporting this error and helping us to froxlor improve froxlor.
This is the email which will be sent to the froxlor developer team:';
-$lng['error']['send_report'] = 'Send report';
\ No newline at end of file
+$lng['error']['send_report'] = 'Send report';
+$lng['pwdreminder']['changed'] = 'Your password has been successfully changed. You can now login using this password.';
+$lng['pwdreminder']['wrongcode'] = 'Sorry, the used activationcode does not exist or is already expired.';
+$lng['admin']['templates']['LINK'] = 'Replaced with the customers password reset link.';
+$lng['pwdreminder']['choosenew'] = 'Choose new password';
\ No newline at end of file
diff --git a/lng/german.lng.php b/lng/german.lng.php
index 1639b666..3bb29b9f 100644
--- a/lng/german.lng.php
+++ b/lng/german.lng.php
@@ -107,7 +107,7 @@ $lng['index']['accountdetails'] = 'Kontodaten';
$lng['changepassword']['old_password'] = 'Altes Passwort';
$lng['changepassword']['new_password'] = 'Neues Passwort';
-$lng['changepassword']['new_password_confirm'] = 'Neues Passwort (bestätigen)';
+$lng['changepassword']['new_password_confirm'] = 'Passwortbestätigung';
$lng['changepassword']['new_password_ifnotempty'] = 'Neues Passwort (leer = nicht ändern)';
$lng['changepassword']['also_change_ftp'] = 'Auch Passwort vom Haupt-FTP-Zugang ändern';
@@ -850,8 +850,8 @@ $lng['login']['email'] = 'E-Mail Adresse';
$lng['login']['remind'] = 'Passwort zurücksetzen';
$lng['login']['usernotfound'] = 'Fehler: Unbekannter Benutzer!';
$lng['pwdreminder']['subject'] = 'Froxlor - Passwort zurückgesetzt';
-$lng['pwdreminder']['body'] = 'Hallo "%s",\n\nIhr Froxlor Passwort wurde zurückgesetzt!\nDas neue Passwort lautet: %p\n\nVielen Dank,\nIhr Administrator';
-$lng['pwdreminder']['success'] = 'Passwort erfolgreich zurückgesetzt.
Sie sollten nun eine E-Mail mit dem neuen Passwort erhalten.';
+$lng['pwdreminder']['body'] = 'Hallo "%s",\n\nHiermit erhalten Sie den Link um ein neues Passwort zu setzen. Dieser Link ist für die nächsten 24 Stunden gültig.\n\n%a\n\nVielen Dank,\nIhr Administrator';
+$lng['pwdreminder']['success'] = 'Das Zurücksetzen des Passworts wurde erfolgreich angefordert. Sie sollten nun eine E-Mail mit weiteren Anweisungen erhalten.';
// ADDED IN 1.2.19-svn18
@@ -1707,4 +1707,8 @@ $lng['error']['sslredirectonlypossiblewithsslipport'] = 'Eine SSL-Weiterleitung
$lng['error']['fcgidstillenableddeadlock'] = 'FCGID ist derzeit aktiviert.
Bitte deaktiviere es, um einen anderen Webserver als Apache2 auswählen zu können.';
$lng['error']['send_report_title'] = 'Fehler melden';
$lng['error']['send_report_desc'] = 'Danke, dass Sie uns diesen Fehler melden und damit helfen Froxlor zu verbessern.
Folgender Bericht wird per Mail an das Froxlor Entwickler Team gesendet.';
-$lng['error']['send_report'] = 'Fehlerbericht senden';
\ No newline at end of file
+$lng['error']['send_report'] = 'Fehlerbericht senden';
+$lng['pwdreminder']['changed'] = 'Ihr Passwort wurde erfolgreich geändert. Sie können sich nun damit ';
+$lng['pwdreminder']['wrongcode'] = 'Der verwendete Aktivierungscode ist entweder nicht gültig oder bereits abgelaufen.';
+$lng['admin']['templates']['LINK'] = 'Wird mit dem Link zum Zurücksetzen des Passworts ersetzt.';
+$lng['pwdreminder']['choosenew'] = 'Neues Passwort auswählen';
\ No newline at end of file
diff --git a/templates/Froxlor/admin/templates/templates_add_2.tpl b/templates/Froxlor/admin/templates/templates_add_2.tpl
index 2fa2ce77..ab4863a9 100644
--- a/templates/Froxlor/admin/templates/templates_add_2.tpl
+++ b/templates/Froxlor/admin/templates/templates_add_2.tpl
@@ -115,8 +115,8 @@ $header