updated otp screen to patternfly 5 (#26528)
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
56b0f9ec03
commit
ab41f270fc
4 changed files with 156 additions and 3 deletions
133
themes/src/main/resources/theme/keycloak.v2/login/login-config-totp.ftl
Executable file
133
themes/src/main/resources/theme/keycloak.v2/login/login-config-totp.ftl
Executable file
|
@ -0,0 +1,133 @@
|
||||||
|
<#import "pf-5-template.ftl" as layout>
|
||||||
|
<#import "password-commons.ftl" as passwordCommons>
|
||||||
|
<@layout.registrationLayout displayRequiredFields=false displayMessage=!messagesPerField.existsError('totp','userLabel'); section>
|
||||||
|
|
||||||
|
<#if section = "header">
|
||||||
|
${msg("loginTotpTitle")}
|
||||||
|
<#elseif section = "form">
|
||||||
|
<ol id="kc-totp-settings" class="pf-v5-c-list pf-v5-u-mb-md">
|
||||||
|
<li>
|
||||||
|
<p>${msg("loginTotpStep1")}</p>
|
||||||
|
|
||||||
|
<ul id="kc-totp-supported-apps">
|
||||||
|
<#list totp.supportedApplications as app>
|
||||||
|
<li>${msg(app)}</li>
|
||||||
|
</#list>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<#if mode?? && mode = "manual">
|
||||||
|
<li>
|
||||||
|
<p>${msg("loginTotpManualStep2")}</p>
|
||||||
|
<p><span id="kc-totp-secret-key">${totp.totpSecretEncoded}</span></p>
|
||||||
|
<p><a href="${totp.qrUrl}" id="mode-barcode">${msg("loginTotpScanBarcode")}</a></p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>${msg("loginTotpManualStep3")}</p>
|
||||||
|
<p>
|
||||||
|
<ul>
|
||||||
|
<li id="kc-totp-type">${msg("loginTotpType")}: ${msg("loginTotp." + totp.policy.type)}</li>
|
||||||
|
<li id="kc-totp-algorithm">${msg("loginTotpAlgorithm")}: ${totp.policy.getAlgorithmKey()}</li>
|
||||||
|
<li id="kc-totp-digits">${msg("loginTotpDigits")}: ${totp.policy.digits}</li>
|
||||||
|
<#if totp.policy.type = "totp">
|
||||||
|
<li id="kc-totp-period">${msg("loginTotpInterval")}: ${totp.policy.period}</li>
|
||||||
|
<#elseif totp.policy.type = "hotp">
|
||||||
|
<li id="kc-totp-counter">${msg("loginTotpCounter")}: ${totp.policy.initialCounter}</li>
|
||||||
|
</#if>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<#else>
|
||||||
|
<li>
|
||||||
|
<p>${msg("loginTotpStep2")}</p>
|
||||||
|
<img id="kc-totp-secret-qr-code" src="data:image/png;base64, ${totp.totpSecretQrCode}" alt="Figure: Barcode"><br/>
|
||||||
|
<p><a href="${totp.manualUrl}" id="mode-manual">${msg("loginTotpUnableToScan")}</a></p>
|
||||||
|
</li>
|
||||||
|
</#if>
|
||||||
|
<li>
|
||||||
|
<p>${msg("loginTotpStep3")}</p>
|
||||||
|
<p>${msg("loginTotpStep3DeviceName")}</p>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<form action="${url.loginAction}" class="${properties.kcFormClass!}" id="kc-totp-settings-form" method="post">
|
||||||
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
|
<div class="${properties.kcLabelClass!}">
|
||||||
|
<label class="pf-v5-c-form__label" for="form-vertical-name">
|
||||||
|
<span class="pf-v5-c-form__label-text">${msg("authenticatorCode")}</span> <span class="pf-v5-c-form__label-required" aria-hidden="true">*</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputClass!} <#if messagesPerField.existsError('totp')>pf-m-error</#if>">
|
||||||
|
<input type="text" required id="totp" name="totp" autocomplete="off"
|
||||||
|
aria-invalid="<#if messagesPerField.existsError('totp')>true</#if>"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<#if messagesPerField.existsError('totp')>
|
||||||
|
<span class="pf-v5-c-form-control__utilities">
|
||||||
|
<span class="pf-v5-c-form-control__icon pf-m-status">
|
||||||
|
<i class="fas fa-exclamation-circle" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
<#if messagesPerField.existsError('totp')>
|
||||||
|
<span id="input-error-otp-code" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
${kcSanitize(messagesPerField.get('totp'))?no_esc}
|
||||||
|
</span>
|
||||||
|
</#if>
|
||||||
|
<input type="hidden" id="totpSecret" name="totpSecret" value="${totp.totpSecret}" />
|
||||||
|
<#if mode??><input type="hidden" id="mode" name="mode" value="${mode}"/></#if>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
|
<div class="${properties.kcLabelClass!}">
|
||||||
|
<label class="pf-v5-c-form__label" for="form-vertical-name">
|
||||||
|
<span class="pf-v5-c-form__label-text">${msg("loginTotpDeviceName")}</span><#if totp.otpCredentials?size gte 1> <span class="pf-v5-c-form__label-required" aria-hidden="true">*</span></#if>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcInputClass!}">
|
||||||
|
<input type="text" id="userLabel" name="userLabel" autocomplete="off"
|
||||||
|
aria-invalid="<#if messagesPerField.existsError('userLabel')>true</#if>"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<#if messagesPerField.existsError('userLabel')>
|
||||||
|
<span class="pf-v5-c-form-control__utilities">
|
||||||
|
<span class="pf-v5-c-form-control__icon pf-m-status">
|
||||||
|
<i class="fas fa-exclamation-circle" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
<#if messagesPerField.existsError('userLabel')>
|
||||||
|
<span id="input-error-otp-label" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
|
${kcSanitize(messagesPerField.get('userLabel'))?no_esc}
|
||||||
|
</span>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
|
<@passwordCommons.logoutOtherSessions/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pf-v5-c-form__group pf-m-action">
|
||||||
|
<div class="pf-v5-c-form__actions">
|
||||||
|
<#if isAppInitiatedAction??>
|
||||||
|
<input type="submit"
|
||||||
|
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}"
|
||||||
|
id="saveTOTPBtn" value="${msg("doSubmit")}"
|
||||||
|
/>
|
||||||
|
<button type="submit"
|
||||||
|
class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!} ${properties.kcButtonLargeClass!}"
|
||||||
|
id="cancelTOTPBtn" name="cancel-aia" value="true" />${msg("doCancel")}
|
||||||
|
</button>
|
||||||
|
<#else>
|
||||||
|
<input type="submit"
|
||||||
|
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
||||||
|
id="saveTOTPBtn" value="${msg("doSubmit")}"
|
||||||
|
/>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</#if>
|
||||||
|
</@layout.registrationLayout>
|
|
@ -9,7 +9,11 @@
|
||||||
<form id="kc-form-login" class="${properties.kcFormClass!} onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
|
<form id="kc-form-login" class="${properties.kcFormClass!} onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
|
||||||
<#if !usernameHidden??>
|
<#if !usernameHidden??>
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<label for="username" class="${properties.kcLabelClass!}"><#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if></label>
|
<label for="username" class="${properties.kcLabelClass!}">
|
||||||
|
<span class="pf-v5-c-form__label-text">
|
||||||
|
<#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
<span class="${properties.kcInputClass!} ${messagesPerField.existsError('username','password')?then('pf-m-error', '')}">
|
<span class="${properties.kcInputClass!} ${messagesPerField.existsError('username','password')?then('pf-m-error', '')}">
|
||||||
<input tabindex="1" id="username" name="username" value="${(login.username!'')}" type="text" autofocus autocomplete="off"
|
<input tabindex="1" id="username" name="username" value="${(login.username!'')}" type="text" autofocus autocomplete="off"
|
||||||
|
@ -34,7 +38,9 @@
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
<label for="password" class="${properties.kcLabelClass!}">
|
||||||
|
<span class="pf-v5-c-form__label-text">${msg("password")}</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
<div class="${properties.kcInputGroup!}">
|
<div class="${properties.kcInputGroup!}">
|
||||||
<span class="${properties.kcInputClass!}">
|
<span class="${properties.kcInputClass!}">
|
||||||
|
@ -63,11 +69,13 @@
|
||||||
<#if realm.rememberMe && !usernameHidden??>
|
<#if realm.rememberMe && !usernameHidden??>
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
|
<span class="pf-v5-c-form__label-text">
|
||||||
<#if login.rememberMe??>
|
<#if login.rememberMe??>
|
||||||
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox" checked> ${msg("rememberMe")}
|
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox" checked> ${msg("rememberMe")}
|
||||||
<#else>
|
<#else>
|
||||||
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"> ${msg("rememberMe")}
|
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"> ${msg("rememberMe")}
|
||||||
</#if>
|
</#if>
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<#macro logoutOtherSessions>
|
||||||
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
|
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||||
|
<div class="pf-v5-c-check">
|
||||||
|
<input class="pf-v5-c-check__input" type="checkbox" id="logout-sessions" name="logout-sessions" value="on" checked>
|
||||||
|
<label class="pf-v5-c-check__label" for="logout-sessions">
|
||||||
|
${msg("logoutOtherSessions")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#macro>
|
|
@ -178,7 +178,7 @@
|
||||||
<#-- App-initiated actions should not see warning messages about the need to complete the action -->
|
<#-- App-initiated actions should not see warning messages about the need to complete the action -->
|
||||||
<#-- during login. -->
|
<#-- during login. -->
|
||||||
<#if displayMessage && message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)>
|
<#if displayMessage && message?has_content && (message.type != 'warning' || !isAppInitiatedAction??)>
|
||||||
<div class="${properties.kcAlertClass!} pf-v5-c-alert pf-m-${(message.type = 'error')?then('danger', message.type)}">
|
<div class="${properties.kcAlertClass!} pf-m-${(message.type = 'error')?then('danger', message.type)}">
|
||||||
<div class="pf-v5-c-alert__icon">
|
<div class="pf-v5-c-alert__icon">
|
||||||
<#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon!}"></span></#if>
|
<#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon!}"></span></#if>
|
||||||
<#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon!}"></span></#if>
|
<#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon!}"></span></#if>
|
||||||
|
|
Loading…
Reference in a new issue