From 0904fa4e296e545b1971812f7248b67fbb0d3aff Mon Sep 17 00:00:00 2001
From: Herman van Rink <rink@initfour.nl>
Date: Sun, 15 May 2022 20:22:09 +0200
Subject: [PATCH] Limit sending extra mails to 30 seconds

---
 interface/web/login/lib/lang/ar.lng |  1 +
 interface/web/login/lib/lang/bg.lng |  1 +
 interface/web/login/lib/lang/br.lng |  1 +
 interface/web/login/lib/lang/ca.lng |  1 +
 interface/web/login/lib/lang/cz.lng |  1 +
 interface/web/login/lib/lang/de.lng |  1 +
 interface/web/login/lib/lang/dk.lng |  1 +
 interface/web/login/lib/lang/el.lng |  1 +
 interface/web/login/lib/lang/en.lng |  1 +
 interface/web/login/lib/lang/es.lng |  1 +
 interface/web/login/lib/lang/fi.lng |  1 +
 interface/web/login/lib/lang/fr.lng |  1 +
 interface/web/login/lib/lang/hr.lng |  1 +
 interface/web/login/lib/lang/hu.lng |  1 +
 interface/web/login/lib/lang/id.lng |  1 +
 interface/web/login/lib/lang/it.lng |  1 +
 interface/web/login/lib/lang/ja.lng |  1 +
 interface/web/login/lib/lang/nl.lng |  1 +
 interface/web/login/lib/lang/pl.lng |  1 +
 interface/web/login/lib/lang/pt.lng |  1 +
 interface/web/login/lib/lang/ro.lng |  1 +
 interface/web/login/lib/lang/ru.lng |  1 +
 interface/web/login/lib/lang/se.lng |  1 +
 interface/web/login/lib/lang/sk.lng |  1 +
 interface/web/login/lib/lang/tr.lng |  1 +
 interface/web/login/otp.php         | 94 ++++++++++++++++-------------
 26 files changed, 76 insertions(+), 43 deletions(-)

diff --git a/interface/web/login/lib/lang/ar.lng b/interface/web/login/lib/lang/ar.lng
index 4268f8696c..79ff8def0b 100644
--- a/interface/web/login/lib/lang/ar.lng
+++ b/interface/web/login/lib/lang/ar.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/bg.lng b/interface/web/login/lib/lang/bg.lng
index 6d6f92c873..18f46d6df8 100644
--- a/interface/web/login/lib/lang/bg.lng
+++ b/interface/web/login/lib/lang/bg.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/br.lng b/interface/web/login/lib/lang/br.lng
index e8df8f25dc..1f5b41c369 100644
--- a/interface/web/login/lib/lang/br.lng
+++ b/interface/web/login/lib/lang/br.lng
@@ -40,3 +40,4 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
diff --git a/interface/web/login/lib/lang/ca.lng b/interface/web/login/lib/lang/ca.lng
index 0895c1df49..f4aa11776a 100644
--- a/interface/web/login/lib/lang/ca.lng
+++ b/interface/web/login/lib/lang/ca.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/cz.lng b/interface/web/login/lib/lang/cz.lng
index 8089dcc5fc..a57ff3f704 100644
--- a/interface/web/login/lib/lang/cz.lng
+++ b/interface/web/login/lib/lang/cz.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/de.lng b/interface/web/login/lib/lang/de.lng
index 6c8472fe76..dcb94af716 100644
--- a/interface/web/login/lib/lang/de.lng
+++ b/interface/web/login/lib/lang/de.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/dk.lng b/interface/web/login/lib/lang/dk.lng
index b971e10bd6..37d41ddea1 100644
--- a/interface/web/login/lib/lang/dk.lng
+++ b/interface/web/login/lib/lang/dk.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/el.lng b/interface/web/login/lib/lang/el.lng
index 578b342c5e..64a03b36f6 100644
--- a/interface/web/login/lib/lang/el.lng
+++ b/interface/web/login/lib/lang/el.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/en.lng b/interface/web/login/lib/lang/en.lng
index 405e320500..8dd94c6294 100644
--- a/interface/web/login/lib/lang/en.lng
+++ b/interface/web/login/lib/lang/en.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/es.lng b/interface/web/login/lib/lang/es.lng
index a6da15296e..dd8bd12bc4 100644
--- a/interface/web/login/lib/lang/es.lng
+++ b/interface/web/login/lib/lang/es.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/fi.lng b/interface/web/login/lib/lang/fi.lng
index 496383401b..9bbcbdddab 100644
--- a/interface/web/login/lib/lang/fi.lng
+++ b/interface/web/login/lib/lang/fi.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/fr.lng b/interface/web/login/lib/lang/fr.lng
index e8104aacaa..dfc04fd184 100644
--- a/interface/web/login/lib/lang/fr.lng
+++ b/interface/web/login/lib/lang/fr.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/hr.lng b/interface/web/login/lib/lang/hr.lng
index ae20203acd..1980c4292d 100644
--- a/interface/web/login/lib/lang/hr.lng
+++ b/interface/web/login/lib/lang/hr.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/hu.lng b/interface/web/login/lib/lang/hu.lng
index f8ad853a48..99e2ca769b 100644
--- a/interface/web/login/lib/lang/hu.lng
+++ b/interface/web/login/lib/lang/hu.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/id.lng b/interface/web/login/lib/lang/id.lng
index fb0ba69e37..615357f654 100644
--- a/interface/web/login/lib/lang/id.lng
+++ b/interface/web/login/lib/lang/id.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/it.lng b/interface/web/login/lib/lang/it.lng
index 4ea0a12f4b..df498e978a 100644
--- a/interface/web/login/lib/lang/it.lng
+++ b/interface/web/login/lib/lang/it.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/ja.lng b/interface/web/login/lib/lang/ja.lng
index 8ec65a03e3..bff26e9d83 100644
--- a/interface/web/login/lib/lang/ja.lng
+++ b/interface/web/login/lib/lang/ja.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/nl.lng b/interface/web/login/lib/lang/nl.lng
index b946fd7dad..453aae6fac 100644
--- a/interface/web/login/lib/lang/nl.lng
+++ b/interface/web/login/lib/lang/nl.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authenticatie';
 $wb['otp_code_email_template_txt'] = 'Uw eenmalige login code is %s' . PHP_EOL . 'Deze code is geldig voor 10 minuten.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Aanvragen nieuwe code';
 $wb['otp_code_email_sent_failed_txt'] = 'Verzenden van email naar %s is mislukt.';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/pl.lng b/interface/web/login/lib/lang/pl.lng
index 2a037016f7..f693720542 100644
--- a/interface/web/login/lib/lang/pl.lng
+++ b/interface/web/login/lib/lang/pl.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/pt.lng b/interface/web/login/lib/lang/pt.lng
index b7eb8a2663..fd453844ea 100644
--- a/interface/web/login/lib/lang/pt.lng
+++ b/interface/web/login/lib/lang/pt.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/ro.lng b/interface/web/login/lib/lang/ro.lng
index 21ba4da975..94950d6c06 100644
--- a/interface/web/login/lib/lang/ro.lng
+++ b/interface/web/login/lib/lang/ro.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/ru.lng b/interface/web/login/lib/lang/ru.lng
index e79ac35f10..999723c2d6 100644
--- a/interface/web/login/lib/lang/ru.lng
+++ b/interface/web/login/lib/lang/ru.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/se.lng b/interface/web/login/lib/lang/se.lng
index 04d81344e2..db0aeba05e 100644
--- a/interface/web/login/lib/lang/se.lng
+++ b/interface/web/login/lib/lang/se.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/sk.lng b/interface/web/login/lib/lang/sk.lng
index 28033ff210..20ed8f74a7 100644
--- a/interface/web/login/lib/lang/sk.lng
+++ b/interface/web/login/lib/lang/sk.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/lib/lang/tr.lng b/interface/web/login/lib/lang/tr.lng
index 47be8107b6..f30f1fb354 100644
--- a/interface/web/login/lib/lang/tr.lng
+++ b/interface/web/login/lib/lang/tr.lng
@@ -40,4 +40,5 @@ $wb['otp_code_email_subject_txt'] = 'ISPConfig Login authentication';
 $wb['otp_code_email_template_txt'] = 'Your One time login code is %s' . PHP_EOL . 'This code is valid for 10 minutes.' . PHP_EOL;
 $wb['otp_code_resend_txt'] = 'Request new code';
 $wb['otp_code_email_sent_failed_txt'] = 'Failed sending an email to %s';
+$wb['otp_code_email_sent_wait_txt'] = 'Please wait, re-sending the code is only possible after %s seconds.';
 ?>
diff --git a/interface/web/login/otp.php b/interface/web/login/otp.php
index 8cd92b5e51..8b80691da6 100644
--- a/interface/web/login/otp.php
+++ b/interface/web/login/otp.php
@@ -127,57 +127,65 @@ if($_SESSION['otp']['type'] == 'email') {
 	}
 
 	// Send code via email.
-	if(!isset($_SESSION['otp']['sent']) || $_GET['action'] == 'resend') {
-		// Generate new code
-		$new_otp_code = random_int(100000, 999999);
-		$_SESSION['otp']['code_hash'] = password_hash($new_otp_code, PASSWORD_DEFAULT);
-		//$_SESSION['otp']['code_debug'] = $new_otp_code; # for DEBUG only.
-		$_SESSION['otp']['starttime'] = time();
-
-		// Ensure that code is not sent too often
-		if(isset($_SESSION['otp']['sent']) && $_SESSION['otp']['sent'] > $max_code_resend) {
-			$app->error('Code resend limit reached', 'index.php');
-		}
-
-		$app->uses('functions');
-		$app->uses('getconf');
-		$server_config_array = $app->getconf->get_global_config();
+	if (!isset($_SESSION['otp']['sent']) || $_GET['action'] == 'resend') {
 
-		$app->uses('getconf,ispcmail');
-		$mail_config = $server_config_array['mail'];
-		if($mail_config['smtp_enabled'] == 'y') {
-			$mail_config['use_smtp'] = true;
-			$app->ispcmail->setOptions($mail_config);
-		}
-
-		$clientuser = $app->db->queryOneRecord('SELECT email FROM sys_user u LEFT JOIN client c ON (u.client_id=c.client_id) WHERE u.userid = ?', $_SESSION['s_pending']['user']['userid']);
-		if (!empty($clientuser['email'])) {
-		  $email_to = $clientuser['email'];
+		$mail_otp_code_retry_timeout = 30;
+		if (isset($_SESSION['otp']['starttime']) && $_SESSION['otp']['starttime'] > time() - $mail_otp_code_retry_timeout) {
+			$token_sent_message = sprintf($wb['otp_code_email_sent_wait_txt'], $mail_otp_code_retry_timeout);
 		}
 		else {
-		  // Admin users are not related to a client, thus use the globally configured email address.
-		  $email_to = $mail_config['admin_mail'];
-		}
 
-		$app->ispcmail->setSender($mail_config['admin_mail'], $mail_config['admin_name']);
-		$app->ispcmail->setSubject($wb['otp_code_email_subject_txt']);
-		$app->ispcmail->setMailText(sprintf($wb['otp_code_email_template_txt'], $new_otp_code));
-		$send_result = $app->ispcmail->send($email_to);
-		$app->ispcmail->finish();
+			// Generate new code
+			$new_otp_code = random_int(100000, 999999);
+			$_SESSION['otp']['code_hash'] = password_hash($new_otp_code, PASSWORD_DEFAULT);
+			//$_SESSION['otp']['code_debug'] = $new_otp_code; # for DEBUG only.
+			$_SESSION['otp']['starttime'] = time();
 
-		if ($send_result) {
+			// Ensure that code is not sent too often
+			if(isset($_SESSION['otp']['sent']) && $_SESSION['otp']['sent'] > $max_code_resend) {
+				$app->error('Code resend limit reached', 'index.php');
+			}
+
+			$app->uses('functions');
+			$app->uses('getconf');
+			$server_config_array = $app->getconf->get_global_config();
 
-			// Increase sent counter.
-			if(!isset($_SESSION['otp']['sent'])) {
-				$_SESSION['otp']['sent'] = 1;
-			} else {
-				$_SESSION['otp']['sent']++;
+			$app->uses('getconf,ispcmail');
+			$mail_config = $server_config_array['mail'];
+			if($mail_config['smtp_enabled'] == 'y') {
+				$mail_config['use_smtp'] = true;
+				$app->ispcmail->setOptions($mail_config);
 			}
 
-			$token_sent_message = $wb['otp_code_email_sent_txt'] . ' ' . $email_to;
-		}
-		else {
-			$token_sent_message = sprintf($wb['otp_code_email_sent_failed_txt'], $email_to);
+			$clientuser = $app->db->queryOneRecord('SELECT email FROM sys_user u LEFT JOIN client c ON (u.client_id=c.client_id) WHERE u.userid = ?', $_SESSION['s_pending']['user']['userid']);
+			if (!empty($clientuser['email'])) {
+				$email_to = $clientuser['email'];
+			}
+			else {
+				// Admin users are not related to a client, thus use the globally configured email address.
+				$email_to = $mail_config['admin_mail'];
+			}
+
+			$app->ispcmail->setSender($mail_config['admin_mail'], $mail_config['admin_name']);
+			$app->ispcmail->setSubject($wb['otp_code_email_subject_txt']);
+			$app->ispcmail->setMailText(sprintf($wb['otp_code_email_template_txt'], $new_otp_code));
+			$send_result = $app->ispcmail->send($email_to);
+			$app->ispcmail->finish();
+
+			if ($send_result) {
+
+				// Increase sent counter.
+				if(!isset($_SESSION['otp']['sent'])) {
+					$_SESSION['otp']['sent'] = 1;
+				} else {
+					$_SESSION['otp']['sent']++;
+				}
+
+				$token_sent_message = $wb['otp_code_email_sent_txt'] . ' ' . $email_to;
+			}
+			else {
+				$token_sent_message = sprintf($wb['otp_code_email_sent_failed_txt'], $email_to);
+			}
 		}
 	}
 
-- 
GitLab