updated otp screen to patternfly 5 (#26528)

Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
Erik Jan de Wit 2024-02-13 13:51:43 +01:00 committed by GitHub
parent 56b0f9ec03
commit ab41f270fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 156 additions and 3 deletions

View 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>&nbsp;<span class="pf-v5-c-form__label-required" aria-hidden="true">&#42;</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>&nbsp;<span class="pf-v5-c-form__label-required" aria-hidden="true">&#42;</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>

View file

@ -9,7 +9,11 @@
<form id="kc-form-login" class="${properties.kcFormClass!} onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post">
<#if !usernameHidden??>
<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', '')}">
<input tabindex="1" id="username" name="username" value="${(login.username!'')}" type="text" autofocus autocomplete="off"
@ -34,7 +38,9 @@
</#if>
<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!}">
<span class="${properties.kcInputClass!}">
@ -63,11 +69,13 @@
<#if realm.rememberMe && !usernameHidden??>
<div class="checkbox">
<label>
<span class="pf-v5-c-form__label-text">
<#if login.rememberMe??>
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox" checked> ${msg("rememberMe")}
<#else>
<input tabindex="3" id="rememberMe" name="rememberMe" type="checkbox"> ${msg("rememberMe")}
</#if>
</span>
</label>
</div>
</#if>

View file

@ -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>

View file

@ -178,7 +178,7 @@
<#-- App-initiated actions should not see warning messages about the need to complete the action -->
<#-- during login. -->
<#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">
<#if message.type = 'success'><span class="${properties.kcFeedbackSuccessIcon!}"></span></#if>
<#if message.type = 'warning'><span class="${properties.kcFeedbackWarningIcon!}"></span></#if>