--- /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}{*
+*}>
{/if}
{/if}
+ {lang}wcf.user.security.multifactor.totp.newDevice.description{/lang}
+
<div class="multifactorTotpNewDevice">
{if $container->getNodeById('secret')->isAvailable()}
- {@$container->getNodeById('secret')->getHtml()}
+ {@$container->getNodeById('secret')->getFieldHtml()}
{/if}
<div class="multifactorTotpNewDeviceFields">
<div class="totpSecretContainer">
<input type="hidden" name="{@$field->getPrefixedId()}" value="{$field->getSignedValue()}">
- <canvas></canvas>
-
+ <canvas></canvas><br>
<kbd {*
*}class="totpSecret" {*
*}data-issuer="{PAGE_TITLE}" {*
SecretFormField::create(),
CodeFormField::create()
->label('wcf.user.security.multifactor.totp.code')
+ ->description('wcf.user.security.multifactor.totp.code.description')
->required()
->addValidator(new FormFieldValidator('totpSecretValid', function (CodeFormField $field) {
/** @var SecretFormField $secret */
})),
TextFormField::create('deviceName')
->label('wcf.user.security.multifactor.totp.deviceName')
- ->placeholder('wcf.user.security.multifactor.totp.deviceName.placeholder'),
+ ->description('wcf.user.security.multifactor.totp.deviceName.description')
+ ->placeholder('wcf.user.security.multifactor.totp.deviceName.placeholder')
+ ->maximumLength(200),
FormButton::create('submitButton')
->label('wcf.global.button.submit')
->accessKey('s')
class CodeFormField extends TextFormField {
use TDefaultIdFormField;
+ /**
+ * @inheritDoc
+ */
+ protected $templateName = '__totpCodeField';
+
/**
* @var ?int
*/
public function __construct() {
$this->minimumLength(Totp::CODE_LENGTH);
$this->maximumLength(Totp::CODE_LENGTH);
+ $this->placeholder("123456");
}
/**
}
}
+// Just .multifactorTotpCode is not specific enough.
+input.multifactorTotpCode {
+ font-family: monospace;
+ font-weight: 600;
+ font-size: 28px;
+}
+
.multifactorTotpNewDevice {
display: flex;
+ flex-direction: column;
.totpSecretContainer {
text-align: center;
- width: 250px;
- margin: 0 5px;
canvas {
width: 200px;
.multifactorTotpNewDeviceFields {
flex: 1 1 auto;
}
+
+ @include screen-md-up {
+ flex-direction: row;
+
+ .totpSecretContainer {
+ width: 250px;
+ margin: 0 5px;
+ }
+ }
}
<item name="wcf.user.security.multifactor.totp.deviceName.default"><![CDATA[{TIME_NOW|plainTime}]]></item>
<item name="wcf.user.security.multifactor.totp.error.flood"><![CDATA[Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}versuche es{else}versuchen Sie es{/if} später erneut.]]></item>
<item name="wcf.user.security.multifactor.backup.error.flood"><![CDATA[Bitte {if LANGUAGE_USE_INFORMAL_VARIANT}versuche es{else}versuchen Sie es{/if} später erneut.]]></item>
+ <item name="wcf.user.security.multifactor.totp.deviceName.description"><![CDATA[Ein beliebiger Name, der dieses Gerät identifiziert.]]></item>
+ <item name="wcf.user.security.multifactor.totp.code.description"><![CDATA[Der durch die Smartphone-App generierte 6-stellige Einmalcode.]]></item>
+ <item name="wcf.user.security.multifactor.totp.newDevice.description"><![CDATA[<p>Authentifizieren Sie sich mit Hilfe einer App auf Ihrem Smartphone.</p>
+<ol class="nativeList">
+<li>{if LANGUAGE_USE_INFORMAL_VARIANT}Installiere{else}Installieren Sie{/if} eine Authentifizierungs-App wie beispielsweise Google Authenticator (<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" class="externalURL">Android</a>, <a href="https://apps.apple.com/app/google-authenticator/id388497605" class="externalURL">iOS</a>) oder Authy (<a href="https://play.google.com/store/apps/details?id=com.authy.authy" class="externalURL">Android</a>, <a href="https://apps.apple.com/app/authy/id494168017" class="externalURL">iOS</a>).</li>
+<li>{if LANGUAGE_USE_INFORMAL_VARIANT}Scanne{else}Scannen Sie{/if} den QR-Code in der App.</li>
+<li>{if LANGUAGE_USE_INFORMAL_VARIANT}Gib{else}Geben Sie{/if} den durch die App generierten 6-stelligen Einmalcode ein.</li>
+</ol>]]></item>
</category>
<category name="wcf.user.trophy">
<item name="wcf.user.trophy.trophyPoints"><![CDATA[Trophäen]]></item>
<item name="wcf.user.security.multifactor.totp.deviceName.default"><![CDATA[{TIME_NOW|plainTime}]]></item>
<item name="wcf.user.security.multifactor.totp.error.flood"><![CDATA[Please try again later.]]></item>
<item name="wcf.user.security.multifactor.backup.error.flood"><![CDATA[Please try again later.]]></item>
+ <item name="wcf.user.security.multifactor.totp.deviceName.description"><![CDATA[An arbitrary name identifying this device.]]></item>
+ <item name="wcf.user.security.multifactor.totp.code.description"><![CDATA[The 6-digit one time code generated by the smartphone app.]]></item>
+ <item name="wcf.user.security.multifactor.totp.newDevice.description"><![CDATA[<p>Authenticate using an app on your smartphone.</p>
+<ol class="nativeList">
+<li>Install an authentication app such as Google Authenticator (<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" class="externalURL">Android</a>, <a href="https://apps.apple.com/app/google-authenticator/id388497605" class="externalURL">iOS</a>) or Authy (<a href="https://play.google.com/store/apps/details?id=com.authy.authy" class="externalURL">Android</a>, <a href="https://apps.apple.com/app/authy/id494168017" class="externalURL">iOS</a>).</li>
+<li>Scan the QR code within the app.</li>
+<li>Enter the 6 digit one time code generated by the app.</li>
+</ol>]]></item>
</category>
<category name="wcf.user.trophy">
<item name="wcf.user.trophy.trophyPoints"><![CDATA[Trophies]]></item>