+++ /dev/null
-<input type="text" {*
- *}id="{@$field->getPrefixedId()}" {*
- *}name="{@$field->getPrefixedId()}" {*
- *}value="{if !$field->isI18n() || !$field->hasI18nValues() || $availableLanguages|count === 1}{$field->getValue()}{/if}" {*
- *}class="multifactorBackupCode" {*
- *}autocomplete="off" {*
- *}pattern="[0-9\s]*" {*
- *}inputmode="numeric"{*
- *}{if $field->getChunks() && $field->getChunkLength()} size="{$field->getChunks() - 1 + $field->getChunks() * $field->getChunkLength()}"{/if}{*
- *}{if $field->isAutofocused()} autofocus{/if}{*
- *}{if $field->isRequired()} required{/if}{*
- *}{if $field->isImmutable()} disabled{/if}{*
- *}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
- *}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
- *}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
- *}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
-*}>
+++ /dev/null
-<input type="text" {*
- *}id="{@$field->getPrefixedId()}" {*
- *}name="{@$field->getPrefixedId()}" {*
- *}value="{if !$field->isI18n() || !$field->hasI18nValues() || $availableLanguages|count === 1}{$field->getValue()}{/if}" {*
- *}class="multifactorEmailCode" {*
- *}autocomplete="off" {*
- *}{if $field->getMaximumLength() !== null}size="{$field->getMaximumLength()}" {/if}{*
- *}pattern="[0-9]*" {*
- *}inputmode="numeric"{*
- *}{if $field->isAutofocused()} autofocus{/if}{*
- *}{if $field->isRequired()} required{/if}{*
- *}{if $field->isImmutable()} disabled{/if}{*
- *}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
- *}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
- *}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
- *}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
-*}>
--- /dev/null
+<input type="text" {*
+ *}id="{@$field->getPrefixedId()}" {*
+ *}name="{@$field->getPrefixedId()}" {*
+ *}value="{if !$field->isI18n() || !$field->hasI18nValues() || $availableLanguages|count === 1}{$field->getValue()}{/if}" {*
+ *}class="multifactorBackupCode" {*
+ *}autocomplete="off" {*
+ *}pattern="[0-9\s]*" {*
+ *}inputmode="numeric"{*
+ *}{if $field->getChunks() && $field->getChunkLength()} size="{$field->getChunks() - 1 + $field->getChunks() * $field->getChunkLength()}"{/if}{*
+ *}{if $field->isAutofocused()} autofocus{/if}{*
+ *}{if $field->isRequired()} required{/if}{*
+ *}{if $field->isImmutable()} disabled{/if}{*
+ *}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
+ *}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
+ *}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
+ *}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
+*}>
--- /dev/null
+<input type="text" {*
+ *}id="{@$field->getPrefixedId()}" {*
+ *}name="{@$field->getPrefixedId()}" {*
+ *}value="{if !$field->isI18n() || !$field->hasI18nValues() || $availableLanguages|count === 1}{$field->getValue()}{/if}" {*
+ *}class="multifactorEmailCode" {*
+ *}autocomplete="off" {*
+ *}{if $field->getMaximumLength() !== null}size="{$field->getMaximumLength()}" {/if}{*
+ *}pattern="[0-9]*" {*
+ *}inputmode="numeric"{*
+ *}{if $field->isAutofocused()} autofocus{/if}{*
+ *}{if $field->isRequired()} required{/if}{*
+ *}{if $field->isImmutable()} disabled{/if}{*
+ *}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
+ *}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
+ *}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
+ *}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
+*}>
--- /dev/null
+<input type="text" {*
+ *}id="{@$field->getPrefixedId()}" {*
+ *}name="{@$field->getPrefixedId()}" {*
+ *}value="{if !$field->isI18n() || !$field->hasI18nValues() || $availableLanguages|count === 1}{$field->getValue()}{/if}" {*
+ *}class="multifactorTotpCode" {*
+ *}autocomplete="off" {*
+ *}{if $field->getMaximumLength() !== null}size="{$field->getMaximumLength()}" {/if}{*
+ *}pattern="[0-9]*" {*
+ *}inputmode="numeric"{*
+ *}{if $field->isAutofocused()} autofocus{/if}{*
+ *}{if $field->isRequired()} required{/if}{*
+ *}{if $field->isImmutable()} disabled{/if}{*
+ *}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
+ *}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
+ *}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
+ *}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
+*}>
--- /dev/null
+<button type="button" id="{@$button->getPrefixedId()}" class="jsStaticDialog" data-dialog-id="{@$button->getPrefixedId()}DeletionInfo">{$button->getLabel()}</button>
+<div style="display: none;" id="{@$button->getPrefixedId()}DeletionInfo" data-title="{lang}wcf.user.security.multifactor.totp.lastDevice.title{/lang}">
+ {lang deviceName=$device[deviceName]}wcf.user.security.multifactor.totp.lastDevice{/lang}
+</div>
--- /dev/null
+
+<tr>
+ <td class="columnText">{$device[deviceName]}</td>
+ <td class="columnDate">{$device[createTime]|plainTime}</td>
+ <td class="columnDate">{if $device[useTime]}{$device[useTime]|plainTime}{else}–{/if}</td>
+ <td class="columnText">
+ {foreach from=$container item='child'}
+ {if $child->isAvailable()}
+ {@$child->getHtml()}
+ {/if}
+ {/foreach}
+ </td>
+</tr>
--- /dev/null
+<section id="{@$container->getPrefixedId()}Container"{*
+ *}{if !$container->getClasses()|empty} class="{implode from=$container->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
+ *}{foreach from=$container->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{*
+ *}{if !$container->checkDependencies()} style="display: none;"{/if}{*
+*}>
+ {if $container->getLabel() !== null}
+ {if $container->getDescription() !== null}
+ <header class="sectionHeader">
+ <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
+ <p class="sectionDescription">{@$container->getDescription()}</p>
+ </header>
+ {else}
+ <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
+ {/if}
+ {/if}
+
+ <table class="table table-responsive">
+ <thead>
+ <tr>
+ <th class="columnText">{lang}wcf.user.security.multifactor.totp.deviceName{/lang}</th>
+ <th class="columnText">{lang}wcf.user.security.multifactor.totp.createTime{/lang}</th>
+ <th class="columnText">{lang}wcf.user.security.multifactor.totp.useTime{/lang}</th>
+ <th></th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {foreach from=$container item='child'}
+ {if $child->isAvailable()}
+ {@$child->getHtml()}
+ {/if}
+ {/foreach}
+ </tbody>
+ </table>
+</section>
+
+{include file='__formContainerDependencies'}
+
+<script data-relocate="true">
+ require(['WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default'], function(DefaultContainerDependency) {
+ new DefaultContainerDependency('{@$container->getPrefixedId()}Container');
+ });
+</script>
--- /dev/null
+<section id="{@$container->getPrefixedId()}Container"{*
+ *}{if !$container->getClasses()|empty} class="{implode from=$container->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
+ *}{foreach from=$container->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{*
+ *}{if !$container->checkDependencies()} style="display: none;"{/if}{*
+*}>
+ {if $container->getLabel() !== null}
+ {if $container->getDescription() !== null}
+ <header class="sectionHeader">
+ <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
+ <p class="sectionDescription">{@$container->getDescription()}</p>
+ </header>
+ {else}
+ <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
+ {/if}
+ {/if}
+
+ {lang}wcf.user.security.multifactor.totp.newDevice.description{/lang}
+
+ <div class="multifactorTotpNewDevice">
+ {if $container->getNodeById('secret')->isAvailable()}
+ {@$container->getNodeById('secret')->getFieldHtml()}
+ {/if}
+
+ <div class="multifactorTotpNewDeviceFields">
+ {foreach from=$container item='child'}
+ {if $child->getId() !== 'secret' && $child->getId() !== 'submitButton' && $child->isAvailable()}
+ {@$child->getHtml()}
+ {/if}
+ {/foreach}
+
+ {if $container->getNodeById('submitButton')->isAvailable()}
+ <div class="formSubmit">
+ {@$container->getNodeById('submitButton')->getHtml()}
+ </div>
+ {/if}
+ </div>
+ </div>
+</section>
+
+{include file='__formContainerDependencies'}
+
+<script data-relocate="true">
+ require(['WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default'], function(DefaultContainerDependency) {
+ new DefaultContainerDependency('{@$container->getPrefixedId()}Container');
+ });
+</script>
--- /dev/null
+<div class="totpSecretContainer">
+ <input type="hidden" name="{@$field->getPrefixedId()}" value="{$field->getSignedValue()}">
+ <canvas></canvas><br>
+ <kbd {*
+ *}class="totpSecret" {*
+ *}data-issuer="{PAGE_TITLE}" {*
+ *}data-accountname="{$__wcf->user->username}"{*
+ *}>{$field->getEncodedValue()}</kbd>
+
+ <script>
+ (function (script) {
+ require(['WoltLabSuite/Core/Ui/User/Multifactor/Totp/Qr'], (Qr) => Qr.render(script.closest(".totpSecretContainer")));
+ })(document.currentScript);
+ </script>
+</div>
+++ /dev/null
-<input type="text" {*
- *}id="{@$field->getPrefixedId()}" {*
- *}name="{@$field->getPrefixedId()}" {*
- *}value="{if !$field->isI18n() || !$field->hasI18nValues() || $availableLanguages|count === 1}{$field->getValue()}{/if}" {*
- *}class="multifactorTotpCode" {*
- *}autocomplete="off" {*
- *}{if $field->getMaximumLength() !== null}size="{$field->getMaximumLength()}" {/if}{*
- *}pattern="[0-9]*" {*
- *}inputmode="numeric"{*
- *}{if $field->isAutofocused()} autofocus{/if}{*
- *}{if $field->isRequired()} required{/if}{*
- *}{if $field->isImmutable()} disabled{/if}{*
- *}{if $field->getMinimumLength() !== null} minlength="{$field->getMinimumLength()}"{/if}{*
- *}{if $field->getMaximumLength() !== null} maxlength="{$field->getMaximumLength()}"{/if}{*
- *}{if $field->getPlaceholder() !== null} placeholder="{$field->getPlaceholder()}"{/if}{*
- *}{if $field->getDocument()->isAjax()} data-dialog-submit-on-enter="true"{/if}{*
-*}>
+++ /dev/null
-<button type="button" id="{@$button->getPrefixedId()}" class="jsStaticDialog" data-dialog-id="{@$button->getPrefixedId()}DeletionInfo">{$button->getLabel()}</button>
-<div style="display: none;" id="{@$button->getPrefixedId()}DeletionInfo" data-title="{lang}wcf.user.security.multifactor.totp.lastDevice.title{/lang}">
- {lang deviceName=$device[deviceName]}wcf.user.security.multifactor.totp.lastDevice{/lang}
-</div>
+++ /dev/null
-
-<tr>
- <td class="columnText">{$device[deviceName]}</td>
- <td class="columnDate">{$device[createTime]|plainTime}</td>
- <td class="columnDate">{if $device[useTime]}{$device[useTime]|plainTime}{else}–{/if}</td>
- <td class="columnText">
- {foreach from=$container item='child'}
- {if $child->isAvailable()}
- {@$child->getHtml()}
- {/if}
- {/foreach}
- </td>
-</tr>
+++ /dev/null
-<section id="{@$container->getPrefixedId()}Container"{*
- *}{if !$container->getClasses()|empty} class="{implode from=$container->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
- *}{foreach from=$container->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{*
- *}{if !$container->checkDependencies()} style="display: none;"{/if}{*
-*}>
- {if $container->getLabel() !== null}
- {if $container->getDescription() !== null}
- <header class="sectionHeader">
- <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
- <p class="sectionDescription">{@$container->getDescription()}</p>
- </header>
- {else}
- <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
- {/if}
- {/if}
-
- <table class="table table-responsive">
- <thead>
- <tr>
- <th class="columnText">{lang}wcf.user.security.multifactor.totp.deviceName{/lang}</th>
- <th class="columnText">{lang}wcf.user.security.multifactor.totp.createTime{/lang}</th>
- <th class="columnText">{lang}wcf.user.security.multifactor.totp.useTime{/lang}</th>
- <th></th>
- </tr>
- </thead>
-
- <tbody>
- {foreach from=$container item='child'}
- {if $child->isAvailable()}
- {@$child->getHtml()}
- {/if}
- {/foreach}
- </tbody>
- </table>
-</section>
-
-{include file='__formContainerDependencies'}
-
-<script data-relocate="true">
- require(['WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default'], function(DefaultContainerDependency) {
- new DefaultContainerDependency('{@$container->getPrefixedId()}Container');
- });
-</script>
+++ /dev/null
-<section id="{@$container->getPrefixedId()}Container"{*
- *}{if !$container->getClasses()|empty} class="{implode from=$container->getClasses() item='class' glue=' '}{$class}{/implode}"{/if}{*
- *}{foreach from=$container->getAttributes() key='attributeName' item='attributeValue'} {$attributeName}="{$attributeValue}"{/foreach}{*
- *}{if !$container->checkDependencies()} style="display: none;"{/if}{*
-*}>
- {if $container->getLabel() !== null}
- {if $container->getDescription() !== null}
- <header class="sectionHeader">
- <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
- <p class="sectionDescription">{@$container->getDescription()}</p>
- </header>
- {else}
- <h2 class="sectionTitle">{@$container->getLabel()}{if $container->markAsRequired()} <span class="formFieldRequired">*</span>{/if}</h2>
- {/if}
- {/if}
-
- {lang}wcf.user.security.multifactor.totp.newDevice.description{/lang}
-
- <div class="multifactorTotpNewDevice">
- {if $container->getNodeById('secret')->isAvailable()}
- {@$container->getNodeById('secret')->getFieldHtml()}
- {/if}
-
- <div class="multifactorTotpNewDeviceFields">
- {foreach from=$container item='child'}
- {if $child->getId() !== 'secret' && $child->getId() !== 'submitButton' && $child->isAvailable()}
- {@$child->getHtml()}
- {/if}
- {/foreach}
-
- {if $container->getNodeById('submitButton')->isAvailable()}
- <div class="formSubmit">
- {@$container->getNodeById('submitButton')->getHtml()}
- </div>
- {/if}
- </div>
- </div>
-</section>
-
-{include file='__formContainerDependencies'}
-
-<script data-relocate="true">
- require(['WoltLabSuite/Core/Form/Builder/Field/Dependency/Container/Default'], function(DefaultContainerDependency) {
- new DefaultContainerDependency('{@$container->getPrefixedId()}Container');
- });
-</script>
+++ /dev/null
-<div class="totpSecretContainer">
- <input type="hidden" name="{@$field->getPrefixedId()}" value="{$field->getSignedValue()}">
- <canvas></canvas><br>
- <kbd {*
- *}class="totpSecret" {*
- *}data-issuer="{PAGE_TITLE}" {*
- *}data-accountname="{$__wcf->user->username}"{*
- *}>{$field->getEncodedValue()}</kbd>
-
- <script>
- (function (script) {
- require(['WoltLabSuite/Core/Ui/User/Multifactor/Totp/Qr'], (Qr) => Qr.render(script.closest(".totpSecretContainer")));
- })(document.currentScript);
- </script>
-</div>
}
else {
$button = new class extends FormButton {
- protected $templateName = '__totpDeviceNoDeleteButton';
+ protected $templateName = '__multifactorTotpDeviceNoDeleteButton';
};
$button->id('no-delete-'.$row['deviceID'])
->label('wcf.global.button.delete');
/**
* @inheritDoc
*/
- protected $templateName = '__backupCodeField';
+ protected $templateName = '__multifactorBackupCodeField';
public function __construct() {
$this->chunks(BackupMultifactorMethod::CHUNKS);
/**
* @inheritDoc
*/
- protected $templateName = '__emailCodeField';
+ protected $templateName = '__multifactorEmailCodeField';
public function __construct() {
$this->minimumLength(EmailMultifactorMethod::LENGTH);
/**
* @inheritDoc
*/
- protected $templateName = '__totpCodeField';
+ protected $templateName = '__multifactorTotpCodeField';
/**
* @var ?int
/**
* @inheritDoc
*/
- protected $templateName = '__totpDeviceNode';
+ protected $templateName = '__multifactorTotpDeviceNode';
/**
* @inheritDoc
/**
* @inheritDoc
*/
- protected $templateName = '__totpDevicesContainer';
+ protected $templateName = '__multifacatorTotpDevicesContainer';
/**
* @inheritDoc
/**
* @inheritDoc
*/
- protected $templateName = '__totpNewDeviceContainer';
+ protected $templateName = '__multifactorTotpNewDeviceContainer';
/**
* @inheritDoc
/**
* @inheritDoc
*/
- protected $templateName = '__totpSecretField';
+ protected $templateName = '__multifactorTotpSecretField';
public function __construct() {
$this->value(Totp::generateSecret());