fix twig templates
This commit is contained in:
bovenliggende
5d4f29988e
commit
b2ba738b05
@ -33,12 +33,12 @@ use Psr\Log\LoggerInterface;
|
||||
|
||||
class d3totpadminlogin extends AdminController
|
||||
{
|
||||
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/wave/d3totpadminlogin';
|
||||
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/d3totplogin';
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function _authorize(): bool
|
||||
protected function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use OxidEsales\Eshop\Core\Utils;
|
||||
|
||||
class d3totplogin extends FrontendController
|
||||
{
|
||||
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/d3totplogin';
|
||||
protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/apex/d3totplogin';
|
||||
|
||||
public function render()
|
||||
{
|
||||
|
@ -25,8 +25,6 @@ return [
|
||||
'D3_TOTP_ACCOUNT' => '2-Faktor-Authentisierung',
|
||||
'D3_TOTP_ACCOUNT_DESC' => 'Sichern Sie Ihre Kontoanmeldung mit einem zweiten Faktor.',
|
||||
|
||||
'D3_TOTP_ACCOUNT_USE' => '2-Faktor-Authentisierung verwenden',
|
||||
|
||||
'D3_TOTP_REGISTERNEW' => 'neue Registrierung erstellen',
|
||||
'D3_TOTP_QRCODE' => 'QR-Code',
|
||||
'D3_TOTP_QRCODE_HELP' => 'Scannen Sie diesen QR-Code mit Ihrer Authentisierungs-App, um dieses Benutzerkonto dort zu hinterlegen.',
|
||||
@ -35,6 +33,9 @@ return [
|
||||
'D3_TOTP_CURROTP' => 'Bestätigung mit Einmalpasswort',
|
||||
'D3_TOTP_CURROTP_HELP' => 'Haben Sie dieses Kundenkonto in Ihrer Authentisierungs-App registriert, generieren Sie damit ein Einmalpasswort, tragen Sie es hier ein und senden das Formular direkt darauf hin ab.',
|
||||
|
||||
'D3_TOTP_STATUS' => 'Status',
|
||||
'D3_TOTP_ACCOUNT_USE' => '2-Faktor-Authentisierung verwenden',
|
||||
|
||||
'D3_TOTP_REGISTEREXIST' => 'vorhandene Registrierung',
|
||||
'D3_TOTP_REGISTERDELETE_DESC' => 'Um die Registrierung zu ändern, löschen Sie diese bitte vorerst. Sie können sofort im Anschluss eine neue Registrierung anlegen.<br>Wenn Sie die Registrierung löschen, ist das Konto nicht mehr durch die Zwei-Faktor-Authentisierung geschützt.',
|
||||
'D3_TOTP_REGISTERDELETE_CONFIRM' => 'Soll die bestehende 2-Faktor-Authentisierung gelöscht werden?',
|
||||
@ -44,6 +45,13 @@ return [
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcode(s) verfügbar',
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
|
||||
|
||||
'D3_TOTP_INPUT_FIRST' => 'erste TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_SECOND' => 'zweite TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_THIRD' => 'dritte TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_FOURTH' => 'vierte TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_FIFTH' => 'fünfte TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_SIXTH' => 'sechste TOTP-Ziffer',
|
||||
|
||||
'D3_TOTP_ACCOUNT_SAVE' => 'Einstellungen übernehmen',
|
||||
|
||||
];
|
||||
|
@ -25,8 +25,6 @@ return [
|
||||
'D3_TOTP_ACCOUNT' => '2-factor authentication',
|
||||
'D3_TOTP_ACCOUNT_DESC' => 'Secure your account login with a second factor.',
|
||||
|
||||
'D3_TOTP_ACCOUNT_USE' => 'Use 2-factor authentication',
|
||||
|
||||
'D3_TOTP_REGISTERNEW' => 'create a new registration',
|
||||
'D3_TOTP_QRCODE' => 'QR code',
|
||||
'D3_TOTP_QRCODE_HELP' => 'Scan this QR code with your authentication app to store this user account there.',
|
||||
@ -35,15 +33,25 @@ return [
|
||||
'D3_TOTP_CURROTP' => 'Confirmation with one-time password',
|
||||
'D3_TOTP_CURROTP_HELP' => 'If you have registered this customer account in your authentication app, use it to generate a one-time password, enter it here and send the form directly afterwards.',
|
||||
|
||||
'D3_TOTP_REGISTEREXIST' => 'existing registration',
|
||||
'D3_TOTP_STATUS' => 'Status',
|
||||
'D3_TOTP_ACCOUNT_USE' => 'use 2-factor authentication',
|
||||
|
||||
'D3_TOTP_REGISTEREXIST' => 'Existing registration',
|
||||
'D3_TOTP_REGISTERDELETE_DESC' => 'To change the registration, please delete it first. You can then create a new registration immediately. <br>If you delete the registration, the account is no longer protected by two-factor authentication.',
|
||||
'D3_TOTP_REGISTERDELETE_CONFIRM' => 'Should the existing 2-factor authentication be deleted?',
|
||||
|
||||
'D3_TOTP_BACKUPCODES' => 'backup codes',
|
||||
'D3_TOTP_BACKUPCODES' => 'Backup codes',
|
||||
'D3_TOTP_BACKUPCODES_DESC' => 'You can use these backup codes to log on if it is not possible to generate the one-time password (e.g. device lost or newly installed). You can then change the settings to use 2-factor authentication or create a new account. Please save these codes securely at this moment. After leaving this page, these codes cannot be displayed again.',
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'still %1$s backup code(s) available',
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.',
|
||||
|
||||
'D3_TOTP_INPUT_FIRST' => 'first TOTP digit',
|
||||
'D3_TOTP_INPUT_SECOND' => 'second TOTP digit',
|
||||
'D3_TOTP_INPUT_THIRD' => 'third TOTP digit',
|
||||
'D3_TOTP_INPUT_FOURTH' => 'fourth TOTP digit',
|
||||
'D3_TOTP_INPUT_FIFTH' => 'fifth TOTP digit',
|
||||
'D3_TOTP_INPUT_SIXTH' => 'sixth TOTP digit',
|
||||
|
||||
'D3_TOTP_ACCOUNT_SAVE' => 'Confirm settings',
|
||||
|
||||
];
|
||||
|
@ -47,6 +47,13 @@ return [
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT' => 'noch %1$s Backupcode(s) verfügbar',
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'Um neue Backupcodes zu erstellen, löschen Sie die bestehende Registrierung und legen diese bitte neu an.',
|
||||
|
||||
'D3_TOTP_INPUT_FIRST' => 'erste TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_SECOND' => 'zweite TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_THIRD' => 'dritte TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_FOURTH' => 'vierte TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_FIFTH' => 'fünfte TOTP-Ziffer',
|
||||
'D3_TOTP_INPUT_SIXTH' => 'sechste TOTP-Ziffer',
|
||||
|
||||
'D3_TOTP_SAVE' => 'Speichern',
|
||||
|
||||
'D3_TOTP_ERROR_UNVALID' => 'Das Einmalpasswort ist ungültig.',
|
||||
|
@ -47,6 +47,13 @@ return [
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT' => '%1$s backup code(s) still available',
|
||||
'D3_TOTP_AVAILBACKUPCODECOUNT_DESC' => 'To create new backup codes, delete the existing registry and create a new one.',
|
||||
|
||||
'D3_TOTP_INPUT_FIRST' => 'first TOTP digit',
|
||||
'D3_TOTP_INPUT_SECOND' => 'second TOTP digit',
|
||||
'D3_TOTP_INPUT_THIRD' => 'third TOTP digit',
|
||||
'D3_TOTP_INPUT_FOURTH' => 'fourth TOTP digit',
|
||||
'D3_TOTP_INPUT_FIFTH' => 'fifth TOTP digit',
|
||||
'D3_TOTP_INPUT_SIXTH' => 'sixth TOTP digit',
|
||||
|
||||
'D3_TOTP_SAVE' => 'Save',
|
||||
|
||||
'D3_TOTP_ERROR_UNVALID' => 'The one-time password is invalid.',
|
||||
|
@ -15,11 +15,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace D3\Totp\Modules\Application\Component;
|
||||
|
||||
use Assert\Assert;
|
||||
use D3\Totp\Application\Model\d3totp;
|
||||
use D3\Totp\Application\Model\d3totp_conf;
|
||||
use D3\Totp\Application\Model\Exceptions\d3totp_wrongOtpException;
|
||||
use D3\Totp\Modules\Application\Model\d3_totp_user;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\Exception;
|
||||
use Doctrine\DBAL\Exception as DBALException;
|
||||
use InvalidArgumentException;
|
||||
use OxidEsales\Eshop\Application\Model\User;
|
||||
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
||||
@ -27,6 +29,8 @@ use OxidEsales\Eshop\Core\Registry;
|
||||
use OxidEsales\Eshop\Core\Session;
|
||||
use OxidEsales\Eshop\Core\Utils;
|
||||
use OxidEsales\Eshop\Core\UtilsView;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
{
|
||||
@ -36,13 +40,12 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
* @return string
|
||||
* @throws DatabaseConnectionException
|
||||
*/
|
||||
protected function _afterLogin($oUser)
|
||||
protected function afterLogin($oUser)
|
||||
{
|
||||
if (!$oUser instanceof User) {
|
||||
throw oxNew(InvalidArgumentException::class, 'user argument must an instance of User class');
|
||||
}
|
||||
Assert::that($oUser)->isInstanceOf(User::class, 'user argument must an instance of User class');
|
||||
|
||||
if ($oUser->getId()) {
|
||||
try {
|
||||
Assert::that($oUser->getId())->notBlank('user must logged in');
|
||||
$totp = $this->d3GetTotpObject();
|
||||
$totp->loadByUserId($oUser->getId());
|
||||
|
||||
@ -65,9 +68,9 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
$sUrl = Registry::getConfig()->getShopHomeUrl() . 'cl=d3totplogin';
|
||||
$this->d3TotpGetUtils()->redirect($sUrl, false);
|
||||
}
|
||||
}
|
||||
} catch (InvalidArgumentException) {}
|
||||
|
||||
return parent::_afterLogin($oUser);
|
||||
return parent::afterLogin($oUser);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,10 +82,14 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws DBALException
|
||||
* @return false|string
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws Exception
|
||||
* @throws DBALException
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
public function d3TotpCheckTotpLogin()
|
||||
public function d3TotpCheckTotpLogin(): false|string
|
||||
{
|
||||
$sTotp = implode('', Registry::getRequest()->getRequestEscapedParameter('d3totp') ?: []);
|
||||
|
||||
@ -101,7 +108,7 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
$this->d3TotpGetSession()->setVariable(d3totp_conf::OXID_FRONTEND_AUTH, $oUser->getId());
|
||||
$this->setUser($oUser);
|
||||
$this->setLoginStatus(USER_LOGIN_SUCCESS);
|
||||
$this->_afterLogin($oUser);
|
||||
$this->afterLogin($oUser);
|
||||
|
||||
$this->d3TotpClearSessionVariables();
|
||||
|
||||
@ -117,7 +124,7 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
/**
|
||||
* @return UtilsView
|
||||
*/
|
||||
public function d3TotpGetUtilsView()
|
||||
public function d3TotpGetUtilsView(): UtilsView
|
||||
{
|
||||
return Registry::getUtilsView();
|
||||
}
|
||||
@ -125,12 +132,12 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
/**
|
||||
* @return Utils
|
||||
*/
|
||||
public function d3TotpGetUtils()
|
||||
public function d3TotpGetUtils(): Utils
|
||||
{
|
||||
return Registry::getUtils();
|
||||
}
|
||||
|
||||
public function d3TotpCancelTotpLogin()
|
||||
public function d3TotpCancelTotpLogin(): bool
|
||||
{
|
||||
$this->d3TotpClearSessionVariables();
|
||||
|
||||
@ -141,7 +148,7 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
* @param d3totp $totp
|
||||
* @return bool
|
||||
*/
|
||||
public function d3TotpIsNoTotpOrNoLogin($totp)
|
||||
public function d3TotpIsNoTotpOrNoLogin($totp): bool
|
||||
{
|
||||
return false == Registry::getSession()->getVariable(d3totp_conf::SESSION_CURRENTUSER)
|
||||
|| false == $totp->isActive();
|
||||
@ -154,13 +161,13 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
* @throws DatabaseConnectionException
|
||||
* @throws d3totp_wrongOtpException
|
||||
*/
|
||||
public function d3TotpHasValidTotp($sTotp, $totp)
|
||||
public function d3TotpHasValidTotp($sTotp, $totp): bool
|
||||
{
|
||||
return Registry::getSession()->getVariable(d3totp_conf::SESSION_AUTH) ||
|
||||
$totp->verify($sTotp);
|
||||
}
|
||||
|
||||
public function d3TotpClearSessionVariables()
|
||||
public function d3TotpClearSessionVariables(): void
|
||||
{
|
||||
$this->d3TotpGetSession()->deleteVariable(d3totp_conf::SESSION_CURRENTCLASS);
|
||||
$this->d3TotpGetSession()->deleteVariable(d3totp_conf::SESSION_CURRENTUSER);
|
||||
@ -170,7 +177,7 @@ class d3_totp_UserComponent extends d3_totp_UserComponent_parent
|
||||
/**
|
||||
* @return Session
|
||||
*/
|
||||
public function d3TotpGetSession()
|
||||
public function d3TotpGetSession(): Session
|
||||
{
|
||||
return Registry::getSession();
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class d3_totp_LoginController extends d3_totp_LoginController_parent
|
||||
return $this->d3CallMockableFunction([d3_totp_LoginController_parent::class, 'checklogin']);
|
||||
}
|
||||
|
||||
public function d3totpAfterLogin()
|
||||
public function d3totpAfterLogin(): void
|
||||
{
|
||||
$myUtilsServer = $this->d3TotpGetUtilsServer();
|
||||
$sProfile = $this->d3TotpGetSession()->getVariable(d3totp_conf::SESSION_ADMIN_PROFILE);
|
||||
|
@ -50,6 +50,7 @@ class totpSystemEventHandler extends totpSystemEventHandler_parent
|
||||
|
||||
$this->getUtilsObject()->redirect(
|
||||
'index.php?cl=d3totpadminlogin&'.
|
||||
'stoken='.Registry::getRequest()->getRequestEscapedParameter('stoken').'&'.
|
||||
'profile='.$this->d3TotpGetSession()->getVariable(d3totp_conf::SESSION_ADMIN_PROFILE).'&'.
|
||||
'chlanguage='.$this->d3TotpGetSession()->getVariable(d3totp_conf::SESSION_ADMIN_CHLANGUAGE),
|
||||
false
|
||||
|
@ -33,17 +33,17 @@
|
||||
[{$oView->getBackupCodeCountMessage()}]
|
||||
|
||||
<div class="container">
|
||||
<label for="1st">erste TOTP-Ziffer</label>
|
||||
<label for="1st">[{oxmultilang ident="D3_TOTP_INPUT_FIRST"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">zweite TOTP-Ziffer</label>
|
||||
<label for="2nd">[{oxmultilang ident="D3_TOTP_INPUT_SECOND"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">dritte TOTP-Ziffer</label>
|
||||
<label for="3rd">[{oxmultilang ident="D3_TOTP_INPUT_THIRD"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">vierte TOTP-Ziffer</label>
|
||||
<label for="4th">[{oxmultilang ident="D3_TOTP_INPUT_FOURTH"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">fünfte TOTP-Ziffer</label>
|
||||
<label for="5th">[{oxmultilang ident="D3_TOTP_INPUT_FIFTH"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">sechste TOTP-Ziffer</label>
|
||||
<label for="6th">[{oxmultilang ident="D3_TOTP_INPUT_SIXTH"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
|
||||
|
@ -24,17 +24,17 @@
|
||||
[{$oView->getBackupCodeCountMessage()}]
|
||||
|
||||
<div class="container">
|
||||
<label for="1st">erste TOTP-Ziffer</label>
|
||||
<label for="1st">[{oxmultilang ident="D3_TOTP_INPUT_FIRST"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">zweite TOTP-Ziffer</label>
|
||||
<label for="2nd">[{oxmultilang ident="D3_TOTP_INPUT_SECOND"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">dritte TOTP-Ziffer</label>
|
||||
<label for="3rd">[{oxmultilang ident="D3_TOTP_INPUT_THIRD"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">vierte TOTP-Ziffer</label>
|
||||
<label for="4th">[{oxmultilang ident="D3_TOTP_INPUT_FOURTH"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">fünfte TOTP-Ziffer</label>
|
||||
<label for="5th">[{oxmultilang ident="D3_TOTP_INPUT_FIFTH"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">sechste TOTP-Ziffer</label>
|
||||
<label for="6th">[{oxmultilang ident="D3_TOTP_INPUT_SIXTH"}]</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
|
||||
|
@ -33,21 +33,21 @@
|
||||
{{ oView.getBackupCodeCountMessage()|raw }}
|
||||
|
||||
<div class="container">
|
||||
<label for="1st">erste TOTP-Ziffer</label>
|
||||
<label for="1st">{{ translate({ ident: "D3_TOTP_INPUT_FIRST" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">zweite TOTP-Ziffer</label>
|
||||
<label for="2nd">{{ translate({ ident: "D3_TOTP_INPUT_SECOND" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">dritte TOTP-Ziffer</label>
|
||||
<label for="3rd">{{ translate({ ident: "D3_TOTP_INPUT_THIRD" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">vierte TOTP-Ziffer</label>
|
||||
<label for="4th">{{ translate({ ident: "D3_TOTP_INPUT_FOURTH" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">fünfte TOTP-Ziffer</label>
|
||||
<label for="5th">{{ translate({ ident: "D3_TOTP_INPUT_FIFTH" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">sechste TOTP-Ziffer</label>
|
||||
<label for="6th">{{ translate({ ident: "D3_TOTP_INPUT_SIXTH" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
|
||||
{% set name = "d3js" %}
|
||||
{% set d3js %}
|
||||
function clickEvent(previous, next){
|
||||
const digitKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
const deleteKeys = ['Backspace', 'Delete'];
|
||||
@ -58,8 +58,7 @@
|
||||
}
|
||||
}
|
||||
document.addEventListener("paste", function(e) {
|
||||
if (e.target.type is same as("text") {
|
||||
)
|
||||
if (e.target.type === "text") {
|
||||
var data = e.clipboardData.getData('Text');
|
||||
data = data.split('');
|
||||
[].forEach.call(document.querySelectorAll("#login input[type=text]"), (node, index) => {
|
||||
@ -68,7 +67,7 @@
|
||||
}
|
||||
});
|
||||
{% endset %}
|
||||
{{ script({ add: d3js, dynamic: __oxid_include_dynamic }) }}
|
||||
{{ script({ add: d3js.__toString(), dynamic: __oxid_include_dynamic }) }}
|
||||
|
||||
<div>{{ translate({ ident: "TOTP_INPUT_HELP" }) }}</div>
|
||||
|
||||
@ -78,7 +77,7 @@
|
||||
onclick="document.getElementById('login').fnc.value='d3CancelLogin'; document.getElementById('login').submit();"
|
||||
>
|
||||
|
||||
{{ style({ include: oViewConf.getModuleUrl('d3totp', 'out/admin/src/css/d3totplogin.css'): 'out/admin/src/css/d3totplogin.css') }) }}
|
||||
{{ style({ include: oViewConf.getModuleUrl('d3totp', 'out/admin/src/css/d3totplogin.css') }) }}
|
||||
|
||||
{{ style() }}
|
||||
|
||||
|
@ -1,126 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>[{oxmultilang ident="LOGIN_TITLE"}]</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=[{$charset}]">
|
||||
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW">
|
||||
<link rel="shortcut icon" href="[{$oViewConf->getImageUrl()}]favicon.ico">
|
||||
<link rel="stylesheet" href="[{$oViewConf->getResourceUrl()}]login.css">
|
||||
<link rel="stylesheet" href="[{$oViewConf->getResourceUrl()}]colors_[{$oViewConf->getEdition()|lower}].css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="admin-login-box">
|
||||
|
||||
<div id="shopLogo"><img src="[{$oViewConf->getImageUrl('logo_dark.svg')}]" alt="" /></div>
|
||||
|
||||
<form action="[{$oViewConf->getSelfLink()}]" method="post" id="login">
|
||||
|
||||
[{block name="admin_login_form"}]
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
|
||||
<input type="hidden" name="fnc" value="checklogin">
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
<input type="hidden" name="profile" value="[{$selectedProfile}]">
|
||||
<input type="hidden" name="chlanguage" value="[{$selectedChLanguage}]">
|
||||
|
||||
<h3>[{oxmultilang ident="TOTP_INPUT"}]</h3>
|
||||
|
||||
[{if !empty($Errors.default)}]
|
||||
[{include file="inc_error.tpl" Errorlist=$Errors.default}]
|
||||
[{/if}]
|
||||
|
||||
[{$oView->getBackupCodeCountMessage()}]
|
||||
|
||||
<div class="container">
|
||||
<label for="1st">erste TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">zweite TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">dritte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">vierte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">fünfte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">sechste TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
|
||||
[{capture name="d3js"}]
|
||||
function clickEvent(previous, next){
|
||||
const digitKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
const deleteKeys = ['Backspace', 'Delete'];
|
||||
if(next && digitKeys.includes(event.key)){
|
||||
document.getElementById(next).focus();
|
||||
} else if(previous && deleteKeys.includes(event.key)){
|
||||
document.getElementById(previous).focus();
|
||||
}
|
||||
}
|
||||
document.addEventListener("paste", function(e) {
|
||||
if (e.target.type === "text") {
|
||||
var data = e.clipboardData.getData('Text');
|
||||
data = data.split('');
|
||||
[].forEach.call(document.querySelectorAll("#login input[type=text]"), (node, index) => {
|
||||
node.value = data[index];
|
||||
});
|
||||
}
|
||||
});
|
||||
[{/capture}]
|
||||
[{oxscript add=$smarty.capture.d3js}]
|
||||
|
||||
<div>[{oxmultilang ident="TOTP_INPUT_HELP"}]</div>
|
||||
|
||||
<input type="submit" value="[{oxmultilang ident="LOGIN_START"}]" class="btn"><br>
|
||||
|
||||
<input class="btn btn_cancel" value="[{oxmultilang ident="TOTP_CANCEL_LOGIN"}]" type="submit"
|
||||
onclick="document.getElementById('login').fnc.value='d3CancelLogin'; document.getElementById('login').submit();"
|
||||
>
|
||||
|
||||
[{oxstyle include=$oViewConf->getModuleUrl('d3totp', 'out/admin/src/css/d3totplogin.css')}]
|
||||
[{oxstyle}]
|
||||
|
||||
|
||||
|
||||
[{**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
|
||||
<input type="hidden" name="fnc" value="">
|
||||
<input type="hidden" name="cl" value="login">
|
||||
|
||||
[{if !empty($Errors.default)}]
|
||||
[{include file="inc_error.tpl" Errorlist=$Errors.default}]
|
||||
[{/if}]
|
||||
|
||||
<div class="d3webauthn_icon">
|
||||
<div class="svg-container">
|
||||
[{include file=$oViewConf->getModulePath('d3webauthn', 'out/img/fingerprint.svg')}]
|
||||
</div>
|
||||
<div class="message">[{oxmultilang ident="WEBAUTHN_INPUT_HELP"}]</div>
|
||||
</div>
|
||||
**}]
|
||||
[{* prevent cancel button (1st button) action when form is sent via Enter key *}]
|
||||
[{**
|
||||
<input type="submit" style="display:none !important;">
|
||||
|
||||
<input class="btn btn_cancel" value="[{oxmultilang ident="WEBAUTHN_CANCEL_LOGIN"}]" type="submit"
|
||||
onclick="document.getElementById('login').fnc.value='d3WebauthnCancelLogin'; document.getElementById('login').submit();"
|
||||
>
|
||||
|
||||
[{oxstyle include=$oViewConf->getModuleUrl('d3webauthn', 'out/admin/src/css/d3webauthnlogin.css')}]
|
||||
[{oxstyle}]
|
||||
**}]
|
||||
[{/block}]
|
||||
</form>
|
||||
</div>
|
||||
|
||||
[{oxscript}]
|
||||
<script type="text/javascript">if (window !== window.top) top.location.href = document.location.href;</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,194 +0,0 @@
|
||||
[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}]
|
||||
|
||||
[{oxstyle include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"}]
|
||||
[{oxscript include="https://code.jquery.com/jquery-3.2.1.slim.min.js"}]
|
||||
[{oxscript include="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"}]
|
||||
[{oxscript include="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"}]
|
||||
[{oxstyle include="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/solid.min.css"}]
|
||||
[{oxstyle}]
|
||||
|
||||
[{assign var="totp" value=$edit->d3GetTotp()}]
|
||||
[{assign var="userid" value=$edit->getId()}]
|
||||
[{$totp->loadByUserId($userid)}]
|
||||
|
||||
[{if $readonly}]
|
||||
[{assign var="readonly" value="readonly disabled"}]
|
||||
[{else}]
|
||||
[{assign var="readonly" value=""}]
|
||||
[{/if}]
|
||||
|
||||
<style>
|
||||
td.edittext {
|
||||
white-space: normal;
|
||||
}
|
||||
.hero {
|
||||
display: inline-block;
|
||||
}
|
||||
.hero > h1 {
|
||||
padding: 0.3em 0;
|
||||
}
|
||||
.hero > div {
|
||||
text-align: right;
|
||||
color: #6c7c98;
|
||||
}
|
||||
.container-fluid {
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
|
||||
[{if $force2FA}]
|
||||
<div class="hero">
|
||||
<h1>[{oxmultilang ident="D3_TOTP_FORCE2FATITLE"}]</h1>
|
||||
<div>[{oxmultilang ident="D3_TOTP_FORCE2FASUB"}]</div>
|
||||
</div>
|
||||
[{/if}]
|
||||
|
||||
<form name="transfer" id="transfer" action="[{$oViewConf->getSelfLink()}]" method="post">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="oxid" value="[{$oxid}]">
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
</form>
|
||||
|
||||
<form name="myedit" id="myedit" action="[{$oViewConf->getSelfLink()}]" method="post" style="padding: 0;margin: 0;height:0;">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
<input type="hidden" name="fnc" value="">
|
||||
<input type="hidden" name="oxid" value="[{$oxid}]">
|
||||
<input type="hidden" name="editval[d3totp__oxid]" value="[{$totp->getId()}]">
|
||||
<input type="hidden" name="editval[d3totp__oxuserid]" value="[{$oxid}]">
|
||||
|
||||
[{if $sSaveError}]
|
||||
<table style="padding:0; border:0; width:98%;">
|
||||
<tr>
|
||||
<td></td>
|
||||
<td class="errorbox">[{oxmultilang ident=$sSaveError}]</td>
|
||||
</tr>
|
||||
</table>
|
||||
[{/if}]
|
||||
|
||||
[{if $oxid && $oxid != '-1'}]
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="card">
|
||||
[{block name="user_d3user_totp_form1"}]
|
||||
[{if false == $totp->getId()}]
|
||||
<div class="card-header">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTERNEW"}]
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
[{oxmultilang ident="D3_TOTP_QRCODE" suffix="COLON"}]
|
||||
</div>
|
||||
<div class="col-8">
|
||||
[{$totp->getQrCodeElement()}]
|
||||
[{oxinputhelp ident="D3_TOTP_QRCODE_HELP"}]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[{elseif $force2FA}]
|
||||
<div class="card-header">
|
||||
[{oxmultilang ident="D3_TOTP_ADMINBACKEND"}]
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<input
|
||||
type="submit" class="edittext" id="oLockButton" name="delete"
|
||||
value="[{oxmultilang ident="D3_TOTP_ADMINCONTINUE"}]"
|
||||
onClick="document.myedit.fnc.value='';document.myedit.cl.value='admin_start'"
|
||||
>
|
||||
</div>
|
||||
[{else}]
|
||||
<div class="card-header">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTEREXIST"}]
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTERDELETE_DESC"}]
|
||||
<br>
|
||||
<br>
|
||||
<button type="submit" [{$readonly}] class="btn btn-primary btn-outline-danger btn-sm" onClick="document.myedit.fnc.value='delete'">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTERDELETE"}]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
[{/if}]
|
||||
[{/block}]
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div class="card">
|
||||
[{block name="user_d3user_totp_form2"}]
|
||||
[{if false == $totp->getId()}]
|
||||
<div class="card-header">
|
||||
[{oxmultilang ident="D3_TOTP_CONFIRMATION"}]
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<label for="secret">[{oxmultilang ident="D3_TOTP_SECRET" suffix="COLON"}]</label>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<textarea rows="3" cols="50" id="secret" name="secret" class="editinput" readonly="readonly">[{$totp->getSecret()}]</textarea>
|
||||
[{oxinputhelp ident="D3_TOTP_SECRET_HELP"}]
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 20px;">
|
||||
<div class="col-4">
|
||||
<label for="otp">[{oxmultilang ident="D3_TOTP_CURROTP"}]</label>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<input type="text" class="editinput" size="6" maxlength="6" id="otp" name="otp" value="" autofocus="autofocus" [{$readonly}]>
|
||||
[{oxinputhelp ident="D3_TOTP_CURROTP_HELP"}]
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4"></div>
|
||||
<div class="col-8">
|
||||
<button type="submit" [{$readonly}] class="btn btn-primary btn-success btn-sm" onClick="document.myedit.fnc.value='save'">
|
||||
[{oxmultilang ident="D3_TOTP_SAVE"}]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[{else}]
|
||||
<div class="card-header">
|
||||
[{oxmultilang ident="D3_TOTP_BACKUPCODES"}]
|
||||
</div>
|
||||
<div class="card-body">
|
||||
[{if $oView->getBackupCodes()}]
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<label for="backupcodes">[{oxmultilang ident="D3_TOTP_BACKUPCODES_DESC"}]</label>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<textarea id="backupcodes" rows="10" cols="20">[{$oView->getBackupCodes()}]</textarea>
|
||||
</div>
|
||||
</div>
|
||||
[{else}]
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
[{oxmultilang ident="D3_TOTP_AVAILBACKUPCODECOUNT" args=$oView->getAvailableBackupCodeCount()}]
|
||||
<br>
|
||||
<br>
|
||||
[{oxmultilang ident="D3_TOTP_AVAILBACKUPCODECOUNT_DESC"}]
|
||||
</div>
|
||||
</div>
|
||||
[{/if}]
|
||||
</div>
|
||||
[{/if}]
|
||||
[{/block}]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[{/if}]
|
||||
</form>
|
||||
|
||||
[{if !$force2FA}]
|
||||
[{include file="bottomnaviitem.tpl"}]
|
||||
[{include file="bottomitem.tpl"}]
|
||||
[{/if}]
|
@ -38,7 +38,7 @@
|
||||
|
||||
<script type="text/javascript">
|
||||
function toggle(id) {
|
||||
var div1 = document.getElementById(id);
|
||||
let div1 = document.getElementById(id);
|
||||
if(document.getElementById('totp_use').checked) {
|
||||
div1.style.display = 'block';
|
||||
} else {
|
||||
@ -58,16 +58,21 @@
|
||||
<input type="hidden" name="cl" value="{{ oViewConf.getActiveClassName() }}">
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<input id="totp_use" value="1" type="checkbox" name="totp_use" {% if totp.getId() %} checked{% endif %} {% if false == totp.getId() %}onclick="toggle('registerNew'); toggle('submitBtn');"{% endif %}>
|
||||
<label for="totp_use">{{ translate({ ident: "D3_TOTP_ACCOUNT_USE" }) }}</label>
|
||||
</p>
|
||||
<div class="{# apex #} card">
|
||||
<h2 class="{# apex #} h5 card-header">
|
||||
{{ translate({ ident: "D3_TOTP_STATUS" }) }}
|
||||
</h2>
|
||||
<div class="{# apex #} card-body">
|
||||
<input id="totp_use" value="1" type="checkbox" name="totp_use" {% if totp.getId() %} checked{% endif %} {% if false == totp.getId() %}onclick="toggle('registerNew'); toggle('submitBtn');"{% endif %}>
|
||||
<label for="totp_use">{{ translate({ ident: "D3_TOTP_ACCOUNT_USE" }) }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if false == totp.getId() %}
|
||||
<div class="registerNew {# apex #} card" id="registerNew">
|
||||
<div class="{# apex #} card-header">
|
||||
<h2 class="{# apex #} h5 card-header">
|
||||
{{ translate({ ident: "D3_TOTP_REGISTERNEW" }) }}
|
||||
</div>
|
||||
</h2>
|
||||
<div class="{# apex #} card-body">
|
||||
<dl>
|
||||
<dt>
|
||||
@ -115,9 +120,9 @@
|
||||
{% if totp.getId() %}
|
||||
{% block d3_account_totp_deletenotes %}
|
||||
<div class="{# apex #} card">
|
||||
<div class="{# apex #} card-header">
|
||||
<h2 class="{# apex #} h5 card-header">
|
||||
{{ translate({ ident: "D3_TOTP_REGISTEREXIST" }) }}
|
||||
</div>
|
||||
</h2>
|
||||
<div class="{# apex #} card-body">
|
||||
{{ translate({ ident: "D3_TOTP_REGISTERDELETE_DESC" }) }}
|
||||
</div>
|
||||
@ -126,9 +131,9 @@
|
||||
|
||||
{% block d3_account_totp_backupcodes %}
|
||||
<div class="{# apex #} card">
|
||||
<div class="{# apex #} card-header">
|
||||
<h2 class="{# apex #} h5 card-header">
|
||||
{{ translate({ ident: "D3_TOTP_BACKUPCODES" }) }}
|
||||
</div>
|
||||
</h2>
|
||||
<div class="{# apex #} card-body">
|
||||
{% if oView.getBackupCodes() %}
|
||||
{% block d3_account_totp_backupcodes_list %}
|
||||
|
@ -1,149 +0,0 @@
|
||||
[{capture append="oxidBlock_content"}]
|
||||
|
||||
<h1 class="page-header">[{oxmultilang ident="D3_TOTP_ACCOUNT"}]</h1>
|
||||
|
||||
[{assign var="totp" value=$user->d3GetTotp()}]
|
||||
[{assign var="userid" value=$user->getId()}]
|
||||
[{$totp->loadByUserId($userid)}]
|
||||
|
||||
<style>
|
||||
.registerNew {
|
||||
display: none;
|
||||
}
|
||||
dt, dd {
|
||||
width: 50%;
|
||||
float: left;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
dd textarea {
|
||||
max-width: 98%;
|
||||
}
|
||||
dt label {
|
||||
font-weight: bold;
|
||||
}
|
||||
[{if false == $totp->getId()}]
|
||||
.submitBtn {
|
||||
display: none;
|
||||
}
|
||||
[{/if}]
|
||||
</style>
|
||||
|
||||
[{block name="d3_account_totp"}]
|
||||
<form action="[{$oViewConf->getSelfActionLink()}]" name="d3totpform" class="form-horizontal" method="post">
|
||||
<div class="hidden">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
[{$oViewConf->getNavFormParams()}]
|
||||
<input type="hidden" id="fncname" name="fnc" value="">
|
||||
<input type="hidden" name="cl" value="[{$oViewConf->getActiveClassName()}]">
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<input id="totp_use" value="1" type="checkbox" name="totp_use" [{if $totp->getId()}] checked[{/if}] [{if false == $totp->getId()}]onclick="$('.registerNew').toggle(); $('.submitBtn').toggle();"[{/if}]>
|
||||
<label for="totp_use">[{oxmultilang ident="D3_TOTP_ACCOUNT_USE"}]</label>
|
||||
</p>
|
||||
|
||||
[{if false == $totp->getId()}]
|
||||
<div class="registerNew [{* flow *}] panel panel-default [{* wave *}] card">
|
||||
<div class="[{* flow *}] panel-heading [{* wave *}] card-header">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTERNEW"}]
|
||||
</div>
|
||||
<div class="[{* flow *}] panel-body [{* wave *}] card-body">
|
||||
<dl>
|
||||
<dt>
|
||||
[{oxmultilang ident="D3_TOTP_QRCODE"}]
|
||||
</dt>
|
||||
<dd>
|
||||
[{$totp->getQrCodeElement()}]
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
[{oxmultilang ident="D3_TOTP_QRCODE_HELP"}]
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<label for="secret">[{oxmultilang ident="D3_TOTP_SECRET"}]</label>
|
||||
</dt>
|
||||
<dd>
|
||||
<textarea rows="3" cols="50" id="secret" name="secret" class="editinput" readonly="readonly">[{$totp->getSecret()}]</textarea>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
[{oxmultilang ident="D3_TOTP_SECRET_HELP"}]
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<label for="otp">[{oxmultilang ident="D3_TOTP_CURROTP"}]</label>
|
||||
</dt>
|
||||
<dd>
|
||||
<input type="text" class="editinput" size="6" maxlength="6" id="otp" name="otp" value="" [{$readonly}]>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>
|
||||
[{oxmultilang ident="D3_TOTP_CURROTP_HELP"}]
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
[{/if}]
|
||||
|
||||
[{if $totp->getId()}]
|
||||
[{block name="d3_account_totp_deletenotes"}]
|
||||
<div class="[{* flow *}] panel panel-default [{* wave *}] card">
|
||||
<div class="[{* flow *}] panel-heading [{* wave *}] card-header">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTEREXIST"}]
|
||||
</div>
|
||||
<div class="[{* flow *}] panel-body [{* wave *}] card-body">
|
||||
[{oxmultilang ident="D3_TOTP_REGISTERDELETE_DESC"}]
|
||||
</div>
|
||||
</div>
|
||||
[{/block}]
|
||||
|
||||
[{block name="d3_account_totp_backupcodes"}]
|
||||
<div class="[{* flow *}] panel panel-default [{* wave *}] card">
|
||||
<div class="[{* flow *}] panel-heading [{* wave *}] card-header">
|
||||
[{oxmultilang ident="D3_TOTP_BACKUPCODES"}]
|
||||
</div>
|
||||
<div class="[{* flow *}] panel-body [{* wave *}] card-body">
|
||||
[{if $oView->getBackupCodes()}]
|
||||
[{block name="d3_account_totp_backupcodes_list"}]
|
||||
<label for="backupcodes">[{oxmultilang ident="D3_TOTP_BACKUPCODES_DESC"}]</label>
|
||||
<textarea id="backupcodes" rows="10" cols="20">[{$oView->getBackupCodes()}]</textarea>
|
||||
[{/block}]
|
||||
[{else}]
|
||||
[{block name="d3_account_totp_backupcodes_info"}]
|
||||
[{oxmultilang ident="D3_TOTP_AVAILBACKUPCODECOUNT" args=$oView->getAvailableBackupCodeCount()}]<br>
|
||||
[{oxmultilang ident="D3_TOTP_AVAILBACKUPCODECOUNT_DESC"}]
|
||||
[{/block}]
|
||||
[{/if}]
|
||||
</div>
|
||||
</div>
|
||||
[{/block}]
|
||||
[{/if}]
|
||||
|
||||
<p class="submitBtn">
|
||||
<button type="submit" class="btn btn-primary"
|
||||
[{if $totp->getId()}]
|
||||
onclick="
|
||||
if(false === document.getElementById('totp_use').checked && false === confirm('[{oxmultilang ident="D3_TOTP_REGISTERDELETE_CONFIRM"}]')) {return false;}
|
||||
document.getElementById('fncname').value = 'delete';
|
||||
"
|
||||
[{else}]
|
||||
onclick="document.getElementById('fncname').value = 'create';"
|
||||
[{/if}]
|
||||
>
|
||||
[{oxmultilang ident="D3_TOTP_ACCOUNT_SAVE"}]
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
[{/block}]
|
||||
[{/capture}]
|
||||
|
||||
[{capture append="oxidBlock_sidebar"}]
|
||||
[{include file="page/account/inc/account_menu.tpl" active_link="d3totp"}]
|
||||
[{/capture}]
|
||||
[{include file="layout/page.tpl" sidebar="Left"}]
|
@ -1,92 +0,0 @@
|
||||
{% capture append = "oxidBlock_content" %}
|
||||
{% set template_title = "" %}
|
||||
|
||||
{% if oView.previousClassIsOrderStep() %}
|
||||
{# ordering steps #}
|
||||
{% include "page/checkout/inc/steps.html.twig" with {active: 2} %}
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-10 col-md-6 {# flow #} col-sm-offset-1 col-md-offset-3 {# wave #} offset-sm-1 offset-md-3 mainforms">
|
||||
<form action="{{ oViewConf.getSelfActionLink() }}" method="post" name="login" id="login">
|
||||
{{ oViewConf.getHiddenSid()|raw }}
|
||||
|
||||
<input type="hidden" name="fnc" value="d3TotpCheckTotpLogin">
|
||||
<input type="hidden" name="cl" value="{{ oView.getPreviousClass() }}">
|
||||
{{ navFormParams }}
|
||||
|
||||
<h3>{{ translate({ ident: "D3_TOTP_INPUT" }) }}</h3>
|
||||
|
||||
{% if not empty(Errors.default) %}
|
||||
{% include "inc_error.html.twig" with {Errorlist: Errors.default} %}
|
||||
{% endif %}
|
||||
|
||||
{{ oView.getBackupCodeCountMessage() }}
|
||||
|
||||
<div class="container">
|
||||
<label for="1st">erste TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">zweite TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">dritte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">vierte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">fünfte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">sechste TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
|
||||
{% capture name = "d3js" %}
|
||||
function clickEvent(previous, next){
|
||||
const digitKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
const deleteKeys = ['Backspace', 'Delete'];
|
||||
if(next && digitKeys.includes(event.key)){
|
||||
document.getElementById(next).focus();
|
||||
} else if(previous && deleteKeys.includes(event.key)){
|
||||
document.getElementById(previous).focus();
|
||||
}
|
||||
}
|
||||
document.addEventListener("paste", function(e) {
|
||||
if (e.target.type is same as("text") {
|
||||
)
|
||||
var data = e.clipboardData.getData('Text');
|
||||
data = data.split('');
|
||||
[].forEach.call(document.querySelectorAll("#login input[type=text]"), (node, index) => {
|
||||
node.value = data[index];
|
||||
});
|
||||
}
|
||||
});
|
||||
{% endcapture %}
|
||||
{{ script({ add: smarty.capture.d3js, dynamic: __oxid_include_dynamic }) }}
|
||||
|
||||
<div>{{ translate({ ident: "D3_TOTP_INPUT_HELP" }) }}</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{{ translate({ ident: "D3_TOTP_SUBMIT_LOGIN" }) }}
|
||||
</button><br>
|
||||
|
||||
</form>
|
||||
<form action="{{ oViewConf.getSelfActionLink() }}" method="post" name="login" id="login">
|
||||
{{ oViewConf.getHiddenSid()|raw }}
|
||||
|
||||
<input type="hidden" name="fnc" value="d3TotpCancelTotpLogin">
|
||||
<input type="hidden" name="cl" value="{{ oView.getPreviousClass() }}">
|
||||
{{ navFormParams }}
|
||||
|
||||
<button class="btn btn_cancel" type="submit">
|
||||
{{ translate({ ident: "D3_TOTP_CANCEL_LOGIN" }) }}
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ style({ include: oViewConf.getModuleUrl('d3totp',, out/flow/src/css/d3totplogin.css'): 'out/flow/src/css/d3totplogin.css') }) }}
|
||||
{{ style() }}
|
||||
|
||||
{{ insert_tracker({title: template_title}) }}
|
||||
{% endcapture %}
|
||||
|
||||
{% include "layout/page.html.twig" %}
|
95
views/twig/apex/d3totplogin.html.twig
Normal file
95
views/twig/apex/d3totplogin.html.twig
Normal file
@ -0,0 +1,95 @@
|
||||
{% capture append = "oxidBlock_content" %}
|
||||
{% set template_title = "" %}
|
||||
|
||||
<div class="container-xxl">
|
||||
<h3>{{ translate({ ident: "D3_TOTP_INPUT" }) }}</h3>
|
||||
<div class="card mb-5">
|
||||
<div class="card-body">
|
||||
<form action="{{ oViewConf.getSelfActionLink() }}" method="post" name="login" id="login">
|
||||
{{ oViewConf.getHiddenSid()|raw }}
|
||||
|
||||
<input type="hidden" name="fnc" value="d3TotpCheckTotpLogin">
|
||||
<input type="hidden" name="cl" value="{{ oView.getPreviousClass() }}">
|
||||
{{ navFormParams|raw }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
{{ translate({ ident: "D3_TOTP_INPUT_HELP" }) }}
|
||||
{{ oView.getBackupCodeCountMessage() }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col text-center my-5">
|
||||
<label for="1st">{{ translate({ ident: "D3_TOTP_INPUT_FIRST" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">{{ translate({ ident: "D3_TOTP_INPUT_SECOND" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">{{ translate({ ident: "D3_TOTP_INPUT_THIRD" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">{{ translate({ ident: "D3_TOTP_INPUT_FOURTH" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">{{ translate({ ident: "D3_TOTP_INPUT_FIFTH" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">{{ translate({ ident: "D3_TOTP_INPUT_SIXTH" }) }}</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% set d3js %}
|
||||
function clickEvent(previous, next){
|
||||
const digitKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
const deleteKeys = ['Backspace', 'Delete'];
|
||||
if(next && digitKeys.includes(event.key)){
|
||||
document.getElementById(next).focus();
|
||||
} else if(previous && deleteKeys.includes(event.key)){
|
||||
document.getElementById(previous).focus();
|
||||
}
|
||||
}
|
||||
document.addEventListener("paste", function(e) {
|
||||
if (e.target.type === "text") {
|
||||
var data = e.clipboardData.getData('Text');
|
||||
data = data.split('');
|
||||
[].forEach.call(document.querySelectorAll("#login input[type=text]"), (node, index) => {
|
||||
node.value = data[index];
|
||||
});
|
||||
}
|
||||
});
|
||||
{% endset %}
|
||||
{{ script({ add: d3js.__toString(), dynamic: __oxid_include_dynamic }) }}
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-6">
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
{{ translate({ ident: "D3_TOTP_SUBMIT_LOGIN" }) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form action="{{ oViewConf.getSelfActionLink() }}" method="post" name="login" id="login_cancel">
|
||||
{{ oViewConf.getHiddenSid()|raw }}
|
||||
|
||||
<input type="hidden" name="fnc" value="d3TotpCancelTotpLogin">
|
||||
<input type="hidden" name="cl" value="{{ oView.getPreviousClass()|raw }}">
|
||||
{{ navFormParams|raw }}
|
||||
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-6">
|
||||
<button class="btn btn-secondary btn-light w-100" type="submit">
|
||||
{{ translate({ ident: "D3_TOTP_CANCEL_LOGIN" }) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ style({ include: oViewConf.getModuleUrl('d3totp', 'out/flow/src/css/d3totplogin.css') }) }}
|
||||
{{ style() }}
|
||||
|
||||
{{ insert_tracker({title: template_title}) }}
|
||||
{% endcapture %}
|
||||
|
||||
{% include "layout/page.html.twig" %}
|
@ -1,91 +0,0 @@
|
||||
[{capture append="oxidBlock_content"}]
|
||||
[{assign var="template_title" value=""}]
|
||||
|
||||
[{if $oView->previousClassIsOrderStep()}]
|
||||
[{* ordering steps *}]
|
||||
[{include file="page/checkout/inc/steps.tpl" active=2}]
|
||||
[{/if}]
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-10 col-md-6 [{* flow *}] col-sm-offset-1 col-md-offset-3 [{* wave *}] offset-sm-1 offset-md-3 mainforms">
|
||||
<form action="[{$oViewConf->getSelfActionLink()}]" method="post" name="login" id="login">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
|
||||
<input type="hidden" name="fnc" value="d3TotpCheckTotpLogin">
|
||||
<input type="hidden" name="cl" value="[{$oView->getPreviousClass()}]">
|
||||
[{$navFormParams}]
|
||||
|
||||
<h3>[{oxmultilang ident="D3_TOTP_INPUT"}]</h3>
|
||||
|
||||
[{if !empty($Errors.default)}]
|
||||
[{include file="inc_error.tpl" Errorlist=$Errors.default}]
|
||||
[{/if}]
|
||||
|
||||
[{$oView->getBackupCodeCountMessage()}]
|
||||
|
||||
<div class="container">
|
||||
<label for="1st">erste TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id='1st' inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent(null, '2nd')" autofocus autocomplete="off">
|
||||
<label for="2nd">zweite TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="2nd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('1st', '3rd')" autocomplete="off">
|
||||
<label for="3rd">dritte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="3rd" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('2nd', '4th')" autocomplete="off">
|
||||
<label for="4th">vierte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="4th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('3rd', '5th')" autocomplete="off">
|
||||
<label for="5th">fünfte TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="5th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('4th', '6th')" autocomplete="off">
|
||||
<label for="6th">sechste TOTP-Ziffer</label>
|
||||
<input type="text" name="d3totp[]" class="digit" id="6th" inputmode="numeric" pattern="[0-9]*" maxlength="1" onkeyup="clickEvent('5th', null)" autocomplete="off">
|
||||
</div>
|
||||
|
||||
[{capture name="d3js"}]
|
||||
function clickEvent(previous, next){
|
||||
const digitKeys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
|
||||
const deleteKeys = ['Backspace', 'Delete'];
|
||||
if(next && digitKeys.includes(event.key)){
|
||||
document.getElementById(next).focus();
|
||||
} else if(previous && deleteKeys.includes(event.key)){
|
||||
document.getElementById(previous).focus();
|
||||
}
|
||||
}
|
||||
document.addEventListener("paste", function(e) {
|
||||
if (e.target.type === "text") {
|
||||
var data = e.clipboardData.getData('Text');
|
||||
data = data.split('');
|
||||
[].forEach.call(document.querySelectorAll("#login input[type=text]"), (node, index) => {
|
||||
node.value = data[index];
|
||||
});
|
||||
}
|
||||
});
|
||||
[{/capture}]
|
||||
[{oxscript add=$smarty.capture.d3js}]
|
||||
|
||||
<div>[{oxmultilang ident="D3_TOTP_INPUT_HELP"}]</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
[{oxmultilang ident="D3_TOTP_SUBMIT_LOGIN"}]
|
||||
</button><br>
|
||||
|
||||
</form>
|
||||
<form action="[{$oViewConf->getSelfActionLink()}]" method="post" name="login" id="login">
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
|
||||
<input type="hidden" name="fnc" value="d3TotpCancelTotpLogin">
|
||||
<input type="hidden" name="cl" value="[{$oView->getPreviousClass()}]">
|
||||
[{$navFormParams}]
|
||||
|
||||
<button class="btn btn_cancel" type="submit">
|
||||
[{oxmultilang ident="D3_TOTP_CANCEL_LOGIN"}]
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
[{oxstyle include=$oViewConf->getModuleUrl('d3totp', 'out/flow/src/css/d3totplogin.css')}]
|
||||
[{oxstyle}]
|
||||
|
||||
[{insert name="oxid_tracker" title=$template_title}]
|
||||
[{/capture}]
|
||||
|
||||
[{include file="layout/page.tpl"}]
|
@ -19,10 +19,10 @@
|
||||
<input type="submit" style="display:none !important;">
|
||||
|
||||
<input class="btn btn_cancel" value="{{ translate({ ident: "TOTP_CANCEL_LOGIN" }) }}" type="submit"
|
||||
onclick="document.getElementById('login').fnc.value='d3CancelLogin'; document.getElementById('login').submit();"
|
||||
onclick="document.getElementById('login').fnc.value='d3CancelLogin'; document.getElementById('login').submit();"
|
||||
>
|
||||
|
||||
{{ style({ include: oViewConf.getModuleUrl('d3totp',, out/admin/src/css/d3totplogin.css'): 'out/admin/src/css/d3totplogin.css') }) }}
|
||||
{{ style({ include: oViewConf.getModuleUrl('d3totp', 'out/admin/src/css/d3totplogin.css') }) }}
|
||||
{{ style() }}
|
||||
{% else %}
|
||||
{{ parent() }}
|
||||
|
@ -1,29 +0,0 @@
|
||||
[{if $request_totp}]
|
||||
[{$oViewConf->getHiddenSid()}]
|
||||
|
||||
<input type="hidden" name="fnc" value="checklogin">
|
||||
<input type="hidden" name="cl" value="login">
|
||||
|
||||
[{if !empty($Errors.default)}]
|
||||
[{include file="inc_error.tpl" Errorlist=$Errors.default}]
|
||||
[{/if}]
|
||||
|
||||
[{$oView->getBackupCodeCountMessage()}]
|
||||
|
||||
<label for="d3totp">[{oxmultilang ident="TOTP_INPUT"}]</label>
|
||||
<input type="text" name="d3totp" id="d3totp" value="" size="49" autofocus autocomplete="off"><br>
|
||||
|
||||
[{oxmultilang ident="TOTP_INPUT_HELP"}]
|
||||
|
||||
[{* prevent cancel button (1st button) action when form is sent via Enter key *}]
|
||||
<input type="submit" style="display:none !important;">
|
||||
|
||||
<input class="btn btn_cancel" value="[{oxmultilang ident="TOTP_CANCEL_LOGIN"}]" type="submit"
|
||||
onclick="document.getElementById('login').fnc.value='d3CancelLogin'; document.getElementById('login').submit();"
|
||||
>
|
||||
|
||||
[{oxstyle include=$oViewConf->getModuleUrl('d3totp', 'out/admin/src/css/d3totplogin.css')}]
|
||||
[{oxstyle}]
|
||||
[{else}]
|
||||
[{$smarty.block.parent}]
|
||||
[{/if}]
|
@ -0,0 +1,10 @@
|
||||
{% extends "widget/header/servicebox.html.twig" %}
|
||||
|
||||
{% block widget_header_servicebox_items %}
|
||||
{{ parent() }}
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ seo_url({ ident: oViewConf.getSslSelfLink() ~ "cl=d3_account_totp" }) }}">
|
||||
{{ translate({ ident: "D3_TOTP_ACCOUNT" }) }}
|
||||
</a>
|
||||
</li>
|
||||
{% endblock %}
|
@ -1,4 +0,0 @@
|
||||
{{ parent() }}
|
||||
<li>
|
||||
<a href="{{ seo_url({ ident: oViewConf.getSslSelfLink()|cat("cl=d3_account_totp") }) }}">{{ translate({ ident: "D3_TOTP_ACCOUNT" }) }}</a>
|
||||
</li>
|
@ -1,4 +0,0 @@
|
||||
[{$smarty.block.parent}]
|
||||
<li>
|
||||
<a href="[{oxgetseourl ident=$oViewConf->getSslSelfLink()|cat:"cl=d3_account_totp"}]">[{oxmultilang ident="D3_TOTP_ACCOUNT"}]</a>
|
||||
</li>
|
Laden…
x
Verwijs in nieuw issue
Block a user