2fa template migration; fix menu-active-state; removed unused code from UI/HTML-class

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2022-03-18 11:41:07 +01:00
parent 12bf7db481
commit ba0d33392c
14 changed files with 177 additions and 166 deletions

17
2fa.php
View File

@@ -6,6 +6,7 @@ if (! defined('AREA')) {
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\UI\Panel\UI;
if (Settings::Get('2fa.enabled') != '1') { if (Settings::Get('2fa.enabled') != '1') {
\Froxlor\UI\Response::dynamic_error("2FA not activated"); \Froxlor\UI\Response::dynamic_error("2FA not activated");
@@ -63,11 +64,13 @@ if ($action == 'delete') {
'd2fa' => $data, 'd2fa' => $data,
'id' => $uid 'id' => $uid
)); ));
\Froxlor\UI\Response::standard_success(sprintf($lng['2fa']['2fa_added'], $filename, $s)); \Froxlor\UI\Response::standard_success(sprintf($lng['2fa']['2fa_added'], $filename));
} }
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed 2fa::overview"); $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed 2fa::overview");
$type_select_values = [];
$ga_qrcode = '';
if ($userinfo['type_2fa'] == '0') { if ($userinfo['type_2fa'] == '0') {
// available types // available types
@@ -77,14 +80,16 @@ if ($userinfo['type_2fa'] == '0') {
2 => 'Authenticator' 2 => 'Authenticator'
); );
asort($type_select_values); asort($type_select_values);
$type_select = "";
foreach ($type_select_values as $_val => $_type) {
$type_select .= \Froxlor\UI\HTML::makeoption($_type, $_val);
}
} elseif ($userinfo['type_2fa'] == '1') { } elseif ($userinfo['type_2fa'] == '1') {
// email 2fa enabled // email 2fa enabled
} elseif ($userinfo['type_2fa'] == '2') { } elseif ($userinfo['type_2fa'] == '2') {
// authenticator 2fa enabled // authenticator 2fa enabled
$ga_qrcode = $tfa->getQRCodeImageAsDataUri($userinfo['loginname'], $userinfo['data_2fa']); $ga_qrcode = $tfa->getQRCodeImageAsDataUri($userinfo['loginname'], $userinfo['data_2fa']);
} }
eval("echo \"" . \Froxlor\UI\Template::getTemplate("2fa/overview", true) . "\";");
UI::twigBuffer('user/2fa.html.twig', [
'themes' => $themes_avail,
'type_select_values' => $type_select_values,
'ga_qrcode' => $ga_qrcode
]);
UI::twigOutputBuffer();

View File

@@ -254,8 +254,6 @@ if ($page == 'overview') {
\Froxlor\UI\Response::redirectTo($filename); \Froxlor\UI\Response::redirectTo($filename);
} else { } else {
$language_options = '';
$default_lang = Settings::Get('panel.standardlanguage'); $default_lang = Settings::Get('panel.standardlanguage');
if ($userinfo['def_language'] != '') { if ($userinfo['def_language'] != '') {
$default_lang = $userinfo['def_language']; $default_lang = $userinfo['def_language'];
@@ -284,8 +282,6 @@ if ($page == 'overview') {
\Froxlor\UI\Response::redirectTo($filename); \Froxlor\UI\Response::redirectTo($filename);
} else { } else {
$theme_options = '';
$default_theme = Settings::Get('panel.default_theme'); $default_theme = Settings::Get('panel.default_theme');
if ($userinfo['theme'] != '') { if ($userinfo['theme'] != '') {
$default_theme = $userinfo['theme']; $default_theme = $userinfo['theme'];

View File

@@ -215,12 +215,11 @@ if ($page == 'overview') {
$default_lang = $userinfo['def_language']; $default_lang = $userinfo['def_language'];
} }
$language_options = ''; UI::twigBuffer('user/change_language.html.twig', [
foreach ($languages as $language_file => $language_name) { 'languages' => $languages,
$language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $default_lang, true); 'default_lang' => $default_lang
} ]);
UI::twigOutputBuffer();
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/change_language') . "\";");
} }
} elseif ($page == 'change_theme') { } elseif ($page == 'change_theme') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
@@ -237,18 +236,19 @@ if ($page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default theme to '" . $theme . "'"); $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "changed default theme to '" . $theme . "'");
\Froxlor\UI\Response::redirectTo($filename); \Froxlor\UI\Response::redirectTo($filename);
} else { } else {
$default_theme = Settings::Get('panel.default_theme'); $default_theme = Settings::Get('panel.default_theme');
if ($userinfo['theme'] != '') { if ($userinfo['theme'] != '') {
$default_theme = $userinfo['theme']; $default_theme = $userinfo['theme'];
} }
$theme_options = '';
$themes_avail = \Froxlor\UI\Template::getThemes(); $themes_avail = \Froxlor\UI\Template::getThemes();
foreach ($themes_avail as $t => $d) {
$theme_options .= \Froxlor\UI\HTML::makeoption($d, $t, $default_theme, true);
}
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/change_theme') . "\";"); UI::twigBuffer('user/change_theme.html.twig', [
'themes' => $themes_avail,
'default_theme' => $default_theme
]);
UI::twigOutputBuffer();
} }
} elseif ($page == 'send_error_report' && Settings::Get('system.allow_error_report_customer') == '1') { } elseif ($page == 'send_error_report' && Settings::Get('system.allow_error_report_customer') == '1') {

View File

@@ -36,7 +36,10 @@ if ($action == '2fa_entercode') {
exit(); exit();
} }
// show template to enter code // show template to enter code
eval("echo \"" . \Froxlor\UI\Template::getTemplate('2fa/entercode', true) . "\";"); UI::twigBuffer('login/enter2fa.html.twig', [
'pagetitle' => $lng['login']['2fa']
]);
UI::twigOutputBuffer();
} elseif ($action == '2fa_verify') { } elseif ($action == '2fa_verify') {
// verify code from 2fa code-enter form // verify code from 2fa code-enter form
if (!isset($_SESSION) || !isset($_SESSION['secret_2fa'])) { if (!isset($_SESSION) || !isset($_SESSION['secret_2fa'])) {
@@ -660,7 +663,12 @@ if ($action == 'resetpwd') {
} }
} }
eval("echo \"" . \Froxlor\UI\Template::getTemplate('rpwd') . "\";"); UI::twigBuffer('login/rpwd.html.twig', [
'pagetitle' => $lng['pwdreminder']['choosenew'],
'formaction' => 'index.php?action=resetpwd&resetcode=' . $activationcode,
'message' => $message,
]);
UI::twigOutputBuffer();
} else { } else {
\Froxlor\UI\Response::redirectTo('index.php', array( \Froxlor\UI\Response::redirectTo('index.php', array(
"showmessage" => '7' "showmessage" => '7'
@@ -705,7 +713,7 @@ function finishLogin($userinfo)
if ($userinfo['adminsession'] == '1') { if ($userinfo['adminsession'] == '1') {
if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) { if (\Froxlor\Froxlor::hasUpdates() || \Froxlor\Froxlor::hasDbUpdates()) {
\Froxlor\UI\Response::redirectTo('admin_updates.php'); \Froxlor\UI\Response::redirectTo('admin_updates.php?page=overview');
} else { } else {
if (isset($_POST['script']) && $_POST['script'] != "") { if (isset($_POST['script']) && $_POST['script'] != "") {
if (preg_match("/customer\_/", $_POST['script']) === 1) { if (preg_match("/customer\_/", $_POST['script']) === 1) {

View File

@@ -43,32 +43,18 @@ class HTML
if ((!isset($box['show_element']) || $box['show_element'] === true) && (!isset($box['required_resources']) || $box['required_resources'] == '' || (isset($userinfo[$box['required_resources']]) && ((int) $userinfo[$box['required_resources']] > 0 || $userinfo[$box['required_resources']] == '-1')))) { if ((!isset($box['show_element']) || $box['show_element'] === true) && (!isset($box['required_resources']) || $box['required_resources'] == '' || (isset($userinfo[$box['required_resources']]) && ((int) $userinfo[$box['required_resources']] > 0 || $userinfo[$box['required_resources']] == '-1')))) {
$navigation_links = []; $navigation_links = [];
$box_active = false; $box_active = false;
foreach ($box['elements'] as $element_id => $element) { foreach ($box['elements'] as $element) {
if ((!isset($element['show_element']) || $element['show_element'] === true) && (!isset($element['required_resources']) || $element['required_resources'] == '' || (isset($userinfo[$element['required_resources']]) && ((int) $userinfo[$element['required_resources']] > 0 || $userinfo[$element['required_resources']] == '-1')))) { if ((!isset($element['show_element']) || $element['show_element'] === true) && (!isset($element['required_resources']) || $element['required_resources'] == '' || (isset($userinfo[$element['required_resources']]) && ((int) $userinfo[$element['required_resources']] > 0 || $userinfo[$element['required_resources']] == '-1')))) {
$target = ''; $target = '';
$active = false; $active = false;
$navurl = '#'; $navurl = '#';
if (isset($element['url']) && trim($element['url']) != '') { if (isset($element['url']) && trim($element['url']) != '') {
// append sid only to local
if (!preg_match('/^https?\:\/\//', $element['url']) && (isset($userinfo['hash']) && $userinfo['hash'] != '')) {
// generate sid with ? oder &
if (strpos($element['url'], '?') !== false) {
$element['url'] .= '&s=' . $userinfo['hash'];
} else {
$element['url'] .= '?s=' . $userinfo['hash'];
}
}
if (isset($element['new_window']) && $element['new_window'] == true) { if (isset($element['new_window']) && $element['new_window'] == true) {
$target = ' target="_blank"'; $target = ' target="_blank"';
} }
if (isset($_GET['page']) && substr_count($element['url'], "page=" . $_GET['page']) > 0 && substr_count($element['url'], basename($_SERVER["SCRIPT_FILENAME"])) > 0 && isset($_GET['action']) && substr_count($element['url'], "action=" . $_GET['action']) > 0) { if (isset($_GET['page']) && substr_count($element['url'], "page=" . $_GET['page']) > 0 && substr_count($element['url'], basename($_SERVER["SCRIPT_FILENAME"])) > 0) {
$active = true;
$box_active = true;
} elseif (isset($_GET['page']) && substr_count($element['url'], "page=" . $_GET['page']) > 0 && substr_count($element['url'], basename($_SERVER["SCRIPT_FILENAME"])) > 0 && substr_count($element['url'], "action=") == 0 && !isset($_GET['action'])) {
$active = true; $active = true;
$box_active = true; $box_active = true;
} }
@@ -94,17 +80,6 @@ class HTML
if (!empty($navigation_links)) { if (!empty($navigation_links)) {
$target = ''; $target = '';
if (isset($box['url']) && trim($box['url']) != '') { if (isset($box['url']) && trim($box['url']) != '') {
// append sid only to local
if (!preg_match('/^https?\:\/\//', $box['url']) && (isset($userinfo['hash']) && $userinfo['hash'] != '')) {
// generate sid with ? oder &
if (strpos($box['url'], '?') !== false) {
$box['url'] .= '&s=' . $userinfo['hash'];
} else {
$box['url'] .= '?s=' . $userinfo['hash'];
}
}
if (isset($box['new_window']) && $box['new_window'] == true) { if (isset($box['new_window']) && $box['new_window'] == true) {
$target = ' target="_blank"'; $target = ' target="_blank"';
@@ -134,55 +109,6 @@ class HTML
return $returnvalue; return $returnvalue;
} }
/**
* Return HTML Code for a checkbox
*
* @param string $name
* The fieldname
* @param string $title
* The captions
* @param string $value
* The Value which will be returned
* @param bool $break
* Add a <br /> at the end of the checkbox
* @param string $selvalue
* Values which will be selected by default
* @param bool $title_trusted
* Whether the title may contain html or not
* @param bool $value_trusted
* Whether the value may contain html or not
*
* @return string HTML Code
*
* @deprecated
*/
public static function makecheckbox($name, $title, $value, $break = false, $selvalue = null, $title_trusted = false, $value_trusted = false)
{
if ($selvalue !== null && $value == $selvalue) {
$checked = 'checked="checked"';
} elseif (isset($_SESSION['requestData'][$name])) {
$checked = 'checked="checked"';
} else {
$checked = '';
}
if (!$title_trusted) {
$title = htmlspecialchars($title);
}
if (!$value_trusted) {
$value = htmlspecialchars($value);
}
$checkbox = '<label class="nobr"><input type="checkbox" name="' . $name . '" value="' . $value . '" ' . $checked . ' />&nbsp;' . $title . '</label>';
if ($break) {
$checkbox .= '<br />';
}
return $checkbox;
}
/** /**
* Return HTML Code for an option within a <select> * Return HTML Code for an option within a <select>
* *
@@ -232,43 +158,6 @@ class HTML
return $option; return $option;
} }
/**
* Returns HTML Code for two radio buttons with two choices: yes and no
*
* @param
* string Name of HTML-Variable
* @param
* string Value which will be returned if user chooses yes
* @param
* string Value which will be returned if user chooses no
* @param
* string Value which is chosen by default
* @param
* bool Whether this element is disabled or not (default: false)
* @return string HTML Code
* @author Florian Lippert <flo@syscp.org> (2003-2009)
* @author Froxlor team <team@froxlor.org> (2010-)
*
* @deprecated
*/
public static function makeyesno($name, $yesvalue, $novalue = '', $yesselected = '', $disabled = false)
{
global $lng, $theme;
if ($disabled) {
$d = ' disabled="disabled"';
} else {
$d = '';
}
if (isset($_SESSION['requestData'])) {
$yesselected = $yesselected & $_SESSION['requestData'][$name];
}
return '<select class="dropdown_noborder" id="' . $name . '" name="' . $name . '"' . $d . '>
<option value="' . $yesvalue . '"' . ($yesselected ? ' selected="selected"' : '') . '>' . $lng['panel']['yes'] . '</option><option value="' . $novalue . '"' . ($yesselected ? '' : ' selected="selected"') . '>' . $lng['panel']['no'] . '</option></select>';
}
/** /**
* Output boolean confirm-dialog * Output boolean confirm-dialog
* *

View File

@@ -295,19 +295,6 @@ if (AREA == 'admin' || AREA == 'customer') {
*/ */
$navigation_data = array( $navigation_data = array(
'admin' => array( 'admin' => array(
'index' => array(
'url' => 'admin_index.php',
'label' => $lng['admin']['overview'],
'elements' => array(
array(
'label' => $lng['menue']['main']['username']
),
array(
'url' => 'admin_index.php?action=logout',
'label' => $lng['login']['logout']
)
)
),
'server' => array( 'server' => array(
'label' => $lng['admin']['server'], 'label' => $lng['admin']['server'],
'required_resources' => 'change_serversettings', 'required_resources' => 'change_serversettings',

View File

@@ -2048,7 +2048,7 @@ $lng['2fa']['2fa_enabled'] = 'Activate Two-factor authentication (2FA)';
$lng['login']['2fa'] = 'Two-factor authentication (2FA)'; $lng['login']['2fa'] = 'Two-factor authentication (2FA)';
$lng['login']['2facode'] = 'Please enter 2FA code'; $lng['login']['2facode'] = 'Please enter 2FA code';
$lng['2fa']['2fa_removed'] = '2FA removed successfully'; $lng['2fa']['2fa_removed'] = '2FA removed successfully';
$lng['2fa']['2fa_added'] = '2FA activated successfully<br><a href="%s?s=%s&page=2fa">View 2FA details</a>'; $lng['2fa']['2fa_added'] = '2FA activated successfully<br><a class="alert-link" href="%s?page=2fa">View 2FA details</a>';
$lng['2fa']['2fa_add'] = 'Activate 2FA'; $lng['2fa']['2fa_add'] = 'Activate 2FA';
$lng['2fa']['2fa_delete'] = 'Deactivate 2FA'; $lng['2fa']['2fa_delete'] = 'Deactivate 2FA';
$lng['2fa']['2fa_verify'] = 'Verify code'; $lng['2fa']['2fa_verify'] = 'Verify code';

View File

@@ -1694,7 +1694,7 @@ $lng['2fa']['2fa_enabled'] = 'Aktiviere Zwei-Faktor Authentifizierung (2FA)';
$lng['login']['2fa'] = 'Zwei-Faktor Authentifizierung (2FA)'; $lng['login']['2fa'] = 'Zwei-Faktor Authentifizierung (2FA)';
$lng['login']['2facode'] = 'Bitte 2FA Code angeben'; $lng['login']['2facode'] = 'Bitte 2FA Code angeben';
$lng['2fa']['2fa_removed'] = '2FA erfolgreich gelöscht'; $lng['2fa']['2fa_removed'] = '2FA erfolgreich gelöscht';
$lng['2fa']['2fa_added'] = '2FA erfolgreich aktiviert<br><a href="%s?s=%s&page=2fa">2FA Details öffnen</a>'; $lng['2fa']['2fa_added'] = '2FA erfolgreich aktiviert<br><a class="alert-link" href="%s?page=2fa">2FA Details öffnen</a>';
$lng['2fa']['2fa_add'] = '2FA aktivieren'; $lng['2fa']['2fa_add'] = '2FA aktivieren';
$lng['2fa']['2fa_delete'] = '2FA deaktivieren'; $lng['2fa']['2fa_delete'] = '2FA deaktivieren';
$lng['2fa']['2fa_verify'] = 'Code verifizieren'; $lng['2fa']['2fa_verify'] = 'Code verifizieren';

View File

@@ -0,0 +1,29 @@
{% extends "Froxlor/base.html.twig" %}
{% block content %}
<div class="container">
<div class="row justify-content-center">
<form action="index.php" class="col-12 max-w-420 d-flex flex-column" method="post" enctype="application/x-www-form-urlencoded">
<img class="align-self-center my-5" src="{{ header_logo_login }}" alt="Froxlor Server Management Panel"/>
<div class="card shadow">
<div class="card-body">
<h5 class="card-title">{{ pagetitle }}</h5>
<div class="mb-3">
<label for="2fa_code" class="col-form-label">{{ lng('login.2facode') }}</label>
<input class="form-control" type="text" name="2fa_code" id="2fa_code" value="" autofocus required/>
</div>
</div>
<div class="card-body d-grid gap-2">
<input type="hidden" name="action" value="2fa_verify"/>
<input type="hidden" name="send" value="send"/>
<button class="btn btn-primary rounded-top-0" type="submit" name="2faverify">{{ lng('2fa.2fa_verify') }}</button>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@@ -44,7 +44,9 @@
</div> </div>
<div class="card-footer"> <div class="card-footer">
<a class="card-link text-muted" href="index.php"><i class="fa-solid fa-angles-left"></i> {{ lng('login.backtologin') }}</a> <a class="card-link text-muted" href="index.php">
<i class="fa-solid fa-angles-left"></i>
{{ lng('login.backtologin') }}</a>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -0,0 +1,47 @@
{% extends "Froxlor/base.html.twig" %}
{% block body %}
<div class="container">
<div class="row justify-content-center">
<form action="{{ formaction }}" class="col-12 max-w-420 d-flex flex-column" method="post" enctype="application/x-www-form-urlencoded">
<img class="align-self-center mb-5" src="{{ header_logo_login }}" alt="Froxlor Server Management Panel"/>
<div class="card shadow">
<div class="card-body">
<h5 class="card-title">{{ pagetitle }}</h5>
<p>{{ lng('login.presend') }}</p>
{% if message is not empty %}
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading">{{ lng('error.error') }}</h4>
<p>{{ message|raw }}</p>
</div>
{% endif %}
<div class="mb-3">
<label for="new_password" class="col-form-label">{{ lng('changepassword.new_password') }}</label>
<input class="form-control" type="password" name="new_password" id="new_password" value="" required/>
</div>
<div class="mb-3">
<label for="new_password_confirm" class="col-form-label">{{ lng('changepassword.new_password_confirm') }}</label>
<input class="form-control" type="password" name="new_password_confirm" id="new_password_confirm" value="" required/>
</div>
</div>
<div class="card-body d-grid gap-2">
<input type="hidden" name="action" value="resetpwd"/>
<input type="hidden" name="send" value="send"/>
<button class="btn btn-primary rounded-top-0" type="submit" name="doremind">{{ lng('login.remind') }}</button>
</div>
<div class="card-footer">
<a class="card-link text-muted" href="index.php">
<i class="fa-solid fa-angles-left"></i>
{{ lng('login.backtologin') }}</a>
</div>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@@ -2,7 +2,7 @@
<ul class="nav d-flex flex-fill flex-column py-3"> <ul class="nav d-flex flex-fill flex-column py-3">
{% for idx,mitems in nav_entries %} {% for idx,mitems in nav_entries %}
{% if mitems.items is not empty %} {% if mitems.items is not empty %}
<li class="nav-item"> <li class="nav-item {% if mitems.active == 1 %}active{% endif %}" {% if mitems.active == 1 %}aria-current="page"{% endif %}>
<a class="nav-link text-light {% if mitems.active == 0 %}collapsed{% endif %}" href="#sub{{ idx }}" data-bs-toggle="collapse" data-bs-target="#sub{{ idx }}"> <a class="nav-link text-light {% if mitems.active == 0 %}collapsed{% endif %}" href="#sub{{ idx }}" data-bs-toggle="collapse" data-bs-target="#sub{{ idx }}">
{% if mitems.icon is not empty %} {% if mitems.icon is not empty %}
<i class="{{ mitems.icon }}"></i> <i class="{{ mitems.icon }}"></i>
@@ -12,15 +12,15 @@
<div class="collapse {% if mitems.active == 1 %}show{% endif %}" id="sub{{ idx }}" aria-expanded="{% if mitems.active == 1 %}true{% else %}false{% endif %}"> <div class="collapse {% if mitems.active == 1 %}show{% endif %}" id="sub{{ idx }}" aria-expanded="{% if mitems.active == 1 %}true{% else %}false{% endif %}">
<ul class="flex-column ps-3 nav"> <ul class="flex-column ps-3 nav">
{% for item in mitems.items %} {% for item in mitems.items %}
<li class="nav-item"> <li class="nav-item {% if item.active == 1 %}active{% endif %}" {% if item.active == 1 %}aria-current="page"{% endif %}>
<a class="nav-link text-light {% if item.active == 1 %}font-weight-bold{% endif %}" href="{{ item.url|raw }}">{{ item.label|raw }}</a> <a class="nav-link text-light {% if item.active == 1 %}fw-bold{% endif %}" href="{{ item.url|raw }}">{{ item.label|raw }}</a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
</li> </li>
{% else %} {% else %}
<li class="nav-item"> <li class="nav-item {% if mitems.active == 1 %}active{% endif %}" {% if mitems.active == 1 %}aria-current="page"{% endif %}>
<a class="nav-link text-light {% if mitems.active == 1 %}active{% endif %}" href="{% if mitems.url is not empty %}{{ mitems.url|raw }}{% else %}#{% endif %}" {% if mitems.target is not empty %} target="{{ mitems.target }}" {% endif %}> <a class="nav-link text-light {% if mitems.active == 1 %}active{% endif %}" href="{% if mitems.url is not empty %}{{ mitems.url|raw }}{% else %}#{% endif %}" {% if mitems.target is not empty %} target="{{ mitems.target }}" {% endif %}>
{% if mitems.icon is not empty %} {% if mitems.icon is not empty %}
<i class="{{ mitems.icon }}"></i> <i class="{{ mitems.icon }}"></i>

View File

@@ -0,0 +1,48 @@
{% extends "Froxlor/userarea.html.twig" %}
{% block content %}
<div class="container">
<div class="row justify-content-center">
{% if userinfo.type_2fa == 0 %}
{% set linkeraction = 'add' %}
{% else %}
{% set linkeraction = 'delete' %}
{% endif %}
<form action="{{ linker({'section':'index','action':linkeraction}) }}" class="col-12 max-w-420 d-flex flex-column" method="post" enctype="application/x-www-form-urlencoded">
<div class="card shadow">
<div class="card-body">
<h5 class="card-title">{{ lng('login.2fa') }}</h5>
<div>
{% if userinfo.type_2fa == 0 %}
<label for="type_2fa" class="col-form-label">{{ lng('2fa.2fa_overview_desc')|raw }}</label>
<select class="form-select" name="type_2fa" id="type_2fa" required>
{% for val,opt in type_select_values %}
<option value="{{ val }}">{{ opt }}</option>
{% endfor %}
</select>
{% elseif userinfo.type_2fa == 2 %}
<label for="qrcode" class="col-form-label">{{ lng('2fa.2fa_ga_desc')|raw }}</label>
<img src="{{ ga_qrcode }}" class="img-fluid" alt="QRCode" id="qrcode"/>
{% endif %}
</div>
</div>
<div class="card-body d-grid gap-2">
<input type="hidden" name="page" value="{{ page }}"/>
<input type="hidden" name="send" value="send"/>
{% if userinfo.type_2fa == 0 %}
<button class="btn btn-primary rounded-top-0" type="submit" name="add">
{{ lng('2fa.2fa_add') }}</button>
{% else %}
<button class="btn btn-warning rounded-top-0" type="submit" name="delete">
{{ lng('2fa.2fa_delete') }}</button>
{% endif %}
</div>
</div>
</form>
</div>
</div>
{% endblock %}