diff --git a/2fa.php b/2fa.php index 859d216b..9c7cfb9a 100644 --- a/2fa.php +++ b/2fa.php @@ -34,6 +34,7 @@ use Froxlor\FroxlorTwoFactorAuth; use Froxlor\Settings; use Froxlor\UI\Panel\UI; use Froxlor\UI\Response; +use Froxlor\PhpHelper; if (Settings::Get('2fa.enabled') != '1') { Response::dynamicError('2fa.2fa_not_activated'); @@ -60,22 +61,71 @@ if ($action == 'delete') { 'id' => $uid ]); Response::standardSuccess('2fa.2fa_removed'); -} elseif ($action == 'add') { +} elseif ($action == 'preadd') { $type = isset($_POST['type_2fa']) ? $_POST['type_2fa'] : '0'; - if ($type == 0 || $type == 1) { - $data = ""; - } - if ($type == 2) { + $data = ""; + if ($type > 0) { // generate secret for TOTP $data = $tfa->createSecret(); + + $userinfo['type_2fa'] = $type; + $userinfo['data_2fa'] = $data; + $userinfo['2fa_unsaved'] = true; + + // if type = email, send a code there for confirmation + if ($type == 1) { + $code = $tfa->getCode($tfa->createSecret()); + $_mailerror = false; + $mailerr_msg = ""; + $replace_arr = [ + 'CODE' => $code + ]; + $mail_body = html_entity_decode(PhpHelper::replaceVariables(lng('mails.2fa.mailbody'), $replace_arr)); + + try { + $mail->Subject = lng('mails.2fa.subject'); + $mail->AltBody = $mail_body; + $mail->MsgHTML(str_replace("\n", "
", $mail_body)); + $mail->AddAddress($userinfo['email'], User::getCorrectUserSalutation($userinfo)); + $mail->Send(); + } catch (\PHPMailer\PHPMailer\Exception $e) { + $mailerr_msg = $e->errorMessage(); + $_mailerror = true; + } catch (Exception $e) { + $mailerr_msg = $e->getMessage(); + $_mailerror = true; + } + + if ($_mailerror) { + Response::dynamicError($mailerr_msg); + } + } + UI::twig()->addGlobal('userinfo', $userinfo); + } else { + Response::dynamicError('Select one of the possible values for 2FA'); } - Database::pexecute($upd_stmt, [ - 't2fa' => $type, - 'd2fa' => $data, - 'id' => $uid - ]); - Response::standardSuccess('2fa.2fa_added', [$filename]); +} elseif ($action == 'add') { + $type = isset($_POST['type_2fa']) ? $_POST['type_2fa'] : '0'; + $data = isset($_POST['data_2fa']) ? $_POST['data_2fa'] : ''; + $code = isset($_POST['codevalidation']) ? $_POST['codevalidation'] : ''; + + // validate + $result = $tfa->verifyCode($data, $code, 3); + + if ($result) { + if ($type == 0 || $type == 1) { + // no fixed secret for email validation, the validation code will be set on the fly + $data = ""; + } + Database::pexecute($upd_stmt, [ + 't2fa' => $type, + 'd2fa' => $data, + 'id' => $uid + ]); + Response::standardSuccess('2fa.2fa_added', $filename); + } + Response::dynamicError('Invalid/wrong code'); } $log->logAction(FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed 2fa::overview"); @@ -98,7 +148,6 @@ if ($userinfo['type_2fa'] == '0') { } UI::view('user/2fa.html.twig', [ - 'themes' => $themes_avail, 'type_select_values' => $type_select_values, 'ga_qrcode' => $ga_qrcode ]); diff --git a/index.php b/index.php index 15dead6e..7a77ecb8 100644 --- a/index.php +++ b/index.php @@ -65,7 +65,7 @@ if ($action == '2fa_entercode') { } $code = isset($_POST['2fa_code']) ? $_POST['2fa_code'] : null; // verify entered code - $tfa = new FroxlorTwoFactorAuth('Froxlor'); + $tfa = new FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname')); $result = ($_SESSION['secret_2fa'] == 'email' ? true : $tfa->verifyCode($_SESSION['secret_2fa'], $code, 3)); // either the code is valid when using authenticator-app, or we will select userdata by id and entered code // which is temporarily stored for the customer when using email-2fa @@ -283,7 +283,7 @@ if ($action == '2fa_entercode') { // send mail if type_2fa = 1 (email) if ($userinfo['type_2fa'] == 1) { // generate code - $tfa = new FroxlorTwoFactorAuth('Froxlor'); + $tfa = new FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname')); $code = $tfa->getCode($tfa->createSecret()); // set code for user $stmt = Database::prepare("UPDATE $table SET `data_2fa` = :d2fa WHERE `$uid` = :uid"); diff --git a/templates/Froxlor/user/2fa.html.twig b/templates/Froxlor/user/2fa.html.twig index 89b758b6..c03998c2 100644 --- a/templates/Froxlor/user/2fa.html.twig +++ b/templates/Froxlor/user/2fa.html.twig @@ -4,6 +4,8 @@
{% if userinfo.type_2fa == 0 %} + {% set linkeraction = 'preadd' %} + {% elseif userinfo['2fa_unsaved'] is defined and userinfo['2fa_unsaved'] %} {% set linkeraction = 'add' %} {% else %} {% set linkeraction = 'delete' %} @@ -24,9 +26,17 @@ {% elseif userinfo.type_2fa == 2 %} - QRCode + QRCode
+ Code: {{ userinfo.data_2fa }} {% endif %} + {% if userinfo['2fa_unsaved'] is defined and userinfo['2fa_unsaved'] %} +
+ + + + + {% endif %}
@@ -34,6 +44,9 @@ {% if userinfo.type_2fa == 0 %} + + {% elseif userinfo['2fa_unsaved'] is defined and userinfo['2fa_unsaved'] %} {% else %}