Made the login more modular
Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
d82ca2ed41
commit
e410a83c3c
11 changed files with 182 additions and 187 deletions
|
@ -47,8 +47,11 @@ public class LoginPage extends LanguageComboboxAwarePage {
|
||||||
@FindBy(id = "password")
|
@FindBy(id = "password")
|
||||||
private WebElement passwordInput;
|
private WebElement passwordInput;
|
||||||
|
|
||||||
@FindBy(id = "input-error")
|
@FindBy(id = "input-error-username")
|
||||||
private WebElement inputError;
|
private WebElement userNameInputError;
|
||||||
|
|
||||||
|
@FindBy(id = "input-error-password")
|
||||||
|
private WebElement passwordInputError;
|
||||||
|
|
||||||
@FindBy(id = "rememberMe")
|
@FindBy(id = "rememberMe")
|
||||||
private WebElement rememberMe;
|
private WebElement rememberMe;
|
||||||
|
@ -161,9 +164,13 @@ public class LoginPage extends LanguageComboboxAwarePage {
|
||||||
|
|
||||||
public String getInputError() {
|
public String getInputError() {
|
||||||
try {
|
try {
|
||||||
return getTextFromElement(inputError);
|
return getTextFromElement(userNameInputError);
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException ex) {
|
||||||
return null;
|
try {
|
||||||
|
return getTextFromElement(passwordInputError);
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +253,7 @@ public class LoginPage extends LanguageComboboxAwarePage {
|
||||||
assertCurrent();
|
assertCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void open(String realm){
|
public void open(String realm) {
|
||||||
oauth.realm(realm);
|
oauth.realm(realm);
|
||||||
oauth.openLoginForm();
|
oauth.openLoginForm();
|
||||||
assertCurrent(realm);
|
assertCurrent(realm);
|
||||||
|
|
|
@ -148,11 +148,11 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
|
||||||
|
|
||||||
//assert field names
|
//assert field names
|
||||||
// i18n replaced
|
// i18n replaced
|
||||||
Assert.assertEquals("First name", updateProfilePage.getLabelForField("firstName"));
|
Assert.assertEquals("First name *", updateProfilePage.getLabelForField("firstName"));
|
||||||
// attribute name used if no display name set
|
// attribute name used if no display name set
|
||||||
Assert.assertEquals("lastName", updateProfilePage.getLabelForField("lastName"));
|
Assert.assertEquals("lastName", updateProfilePage.getLabelForField("lastName"));
|
||||||
// direct value in display name
|
// direct value in display name
|
||||||
Assert.assertEquals("Department", updateProfilePage.getLabelForField("department"));
|
Assert.assertEquals("Department *", updateProfilePage.getLabelForField("department"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -465,11 +465,11 @@ public class KcOidcFirstBrokerLoginTest extends AbstractFirstBrokerLoginTest {
|
||||||
|
|
||||||
//assert field names
|
//assert field names
|
||||||
// i18n replaced
|
// i18n replaced
|
||||||
org.junit.Assert.assertEquals("First name", updateAccountInformationPage.getLabelForField("firstName"));
|
org.junit.Assert.assertEquals("First name *", updateAccountInformationPage.getLabelForField("firstName"));
|
||||||
// attribute name used if no display name set
|
// attribute name used if no display name set
|
||||||
org.junit.Assert.assertEquals("lastName", updateAccountInformationPage.getLabelForField("lastName"));
|
org.junit.Assert.assertEquals("lastName", updateAccountInformationPage.getLabelForField("lastName"));
|
||||||
// direct value in display name
|
// direct value in display name
|
||||||
org.junit.Assert.assertEquals("Department", updateAccountInformationPage.getLabelForField("department"));
|
org.junit.Assert.assertEquals("Department *", updateAccountInformationPage.getLabelForField("department"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -265,11 +265,11 @@ public class RegisterWithUserProfileTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
//assert field names
|
//assert field names
|
||||||
// i18n replaced
|
// i18n replaced
|
||||||
Assert.assertEquals("First name",registerPage.getLabelForField("firstName"));
|
Assert.assertEquals("First name *",registerPage.getLabelForField("firstName"));
|
||||||
// attribute name used if no display name set
|
// attribute name used if no display name set
|
||||||
Assert.assertEquals("lastName",registerPage.getLabelForField("lastName"));
|
Assert.assertEquals("lastName",registerPage.getLabelForField("lastName"));
|
||||||
// direct value in display name
|
// direct value in display name
|
||||||
Assert.assertEquals("Department",registerPage.getLabelForField("department"));
|
Assert.assertEquals("Department *",registerPage.getLabelForField("department"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -191,11 +191,11 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest {
|
||||||
|
|
||||||
//assert field names
|
//assert field names
|
||||||
// i18n replaced
|
// i18n replaced
|
||||||
Assert.assertEquals("First name",verifyProfilePage.getLabelForField("firstName"));
|
Assert.assertEquals("First name *",verifyProfilePage.getLabelForField("firstName"));
|
||||||
// attribute name used if no display name set
|
// attribute name used if no display name set
|
||||||
Assert.assertEquals("lastName",verifyProfilePage.getLabelForField("lastName"));
|
Assert.assertEquals("lastName",verifyProfilePage.getLabelForField("lastName"));
|
||||||
// direct value in display name
|
// direct value in display name
|
||||||
Assert.assertEquals("Department",verifyProfilePage.getLabelForField("department"));
|
Assert.assertEquals("Department *",verifyProfilePage.getLabelForField("department"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
105
themes/src/main/resources/theme/keycloak.v2/login/field.ftl
Normal file
105
themes/src/main/resources/theme/keycloak.v2/login/field.ftl
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<#macro group name label error="" required=false>
|
||||||
|
|
||||||
|
<div class="${properties.kcFormGroupClass}">
|
||||||
|
<div class="${properties.kcFormGroupLabelClass}">
|
||||||
|
<label for="${name}" class="pf-v5-c-form__label">
|
||||||
|
<span class="pf-v5-c-form__label-text">
|
||||||
|
${label}
|
||||||
|
</span>
|
||||||
|
<#if required>
|
||||||
|
<span class="pf-v5-c-form__label-required" aria-hidden="true">*</span>
|
||||||
|
</#if>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<#nested>
|
||||||
|
|
||||||
|
<#if error?has_content>
|
||||||
|
<div class="${properties.kcFormHelperTextClass}" aria-live="polite">
|
||||||
|
<div class="${properties.kcInputHelperTextClass}">
|
||||||
|
<div
|
||||||
|
class="${properties.kcInputHelperTextItemClass} ${properties.kcError}"
|
||||||
|
id="input-error-${name}">
|
||||||
|
<span class="${properties.kcInputErrorMessageClass}">
|
||||||
|
${error}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro errorIcon error="">
|
||||||
|
<#if error?has_content>
|
||||||
|
<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>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro input name label value="" required=false>
|
||||||
|
<#assign error=kcSanitize(messagesPerField.get(name))?no_esc>
|
||||||
|
<@field.group name=name label=label error=error required=required>
|
||||||
|
<span class="${properties.kcInputClass} <#if error?has_content>${properties.kcError}</#if>">
|
||||||
|
<input id="${name}" name="${name}" value="${value}" type="text" autocomplete="off"
|
||||||
|
aria-invalid="<#if error?has_content>true</#if>"/>
|
||||||
|
<@errorIcon error=error/>
|
||||||
|
</span>
|
||||||
|
</@field.group>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro password name label value="" required=false forgotPassword=false>
|
||||||
|
<#assign error=kcSanitize(messagesPerField.get(name))?no_esc>
|
||||||
|
<@field.group name=name label=label error=error required=required>
|
||||||
|
<div class="${properties.kcInputGroup}">
|
||||||
|
<div class="${properties.kcInputGroupItemClass} ${properties.kcFill}">
|
||||||
|
<span class="${properties.kcInputClass} <#if error?has_content>${properties.kcError}</#if>">
|
||||||
|
<input id="${name}" name="${name}" value="${value}" type="password" autocomplete="off"
|
||||||
|
aria-invalid="<#if error?has_content>true</#if>"/>
|
||||||
|
<@errorIcon error=error/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputGroupItemClass}">
|
||||||
|
<button class="pf-v5-c-button pf-m-control" type="button" aria-label="${msg('showPassword')}"
|
||||||
|
aria-controls="${name}" data-password-toggle
|
||||||
|
data-icon-show="fa-eye fas" data-icon-hide="fa-eye-slash fas"
|
||||||
|
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
||||||
|
<i class="fa-eye fas" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<#if forgotPassword>
|
||||||
|
<div class="${properties.kcFormHelperTextClass}" aria-live="polite">
|
||||||
|
<div class="${properties.kcInputHelperTextClass}">
|
||||||
|
<div class="${properties.kcInputHelperTextItemClass}">
|
||||||
|
<span class="${properties.kcInputHelperTextItemTextClass}">
|
||||||
|
<a tabindex="3" href="${url.loginResetCredentialsUrl}">${msg("doForgotPassword")}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</#if>
|
||||||
|
</@field.group>
|
||||||
|
</#macro>
|
||||||
|
|
||||||
|
<#macro checkbox name label value=false required=false>
|
||||||
|
<div class="${properties.kcCheckboxClass}">
|
||||||
|
<label for="${name}" class="${properties.kcCheckboxClass}">
|
||||||
|
<input
|
||||||
|
class="${properties.kcCheckboxInputClass}"
|
||||||
|
type="checkbox"
|
||||||
|
id="${name}"
|
||||||
|
name="${name}"
|
||||||
|
<#if value>checked</#if>
|
||||||
|
/>
|
||||||
|
<span class="${properties.kcCheckboxLabelClass}">${label}</span>
|
||||||
|
<#if required>
|
||||||
|
<span class="${properties.kcCheckboxLabelRequiredClass}" aria-hidden="true">*</span>
|
||||||
|
</#if>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</#macro>
|
|
@ -1,4 +1,5 @@
|
||||||
<#import "template.ftl" as layout>
|
<#import "template.ftl" as layout>
|
||||||
|
<#import "field.ftl" as field>
|
||||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section>
|
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','password') displayInfo=realm.password && realm.registrationAllowed && !registrationDisabled??; section>
|
||||||
<#if section = "header">
|
<#if section = "header">
|
||||||
${msg("loginAccountTitle")}
|
${msg("loginAccountTitle")}
|
||||||
|
@ -6,93 +7,26 @@
|
||||||
<div id="kc-form">
|
<div id="kc-form">
|
||||||
<div id="kc-form-wrapper">
|
<div id="kc-form-wrapper">
|
||||||
<#if realm.password>
|
<#if realm.password>
|
||||||
<form id="kc-form-login" class="${properties.kcFormClass!} onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post" novalidate="novalidate">
|
<form id="kc-form-login" class="pf-v5-c-form" onsubmit="login.disabled = true; return true;" action="${url.loginAction}" method="post" novalidate="novalidate">
|
||||||
<#if !usernameHidden??>
|
<#if !usernameHidden??>
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<#assign label>
|
||||||
<label for="username" class="${properties.kcLabelClass!}">
|
<#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if>
|
||||||
<span class="pf-v5-c-form__label-text">
|
</#assign>
|
||||||
<#if !realm.loginWithEmailAllowed>${msg("username")}<#elseif !realm.registrationEmailAsUsername>${msg("usernameOrEmail")}<#else>${msg("email")}</#if>
|
<@field.input name="username" label=label value="${(login.username!'')}" />
|
||||||
</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"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
|
||||||
dir="ltr"
|
|
||||||
/>
|
|
||||||
<#if messagesPerField.existsError('username','password')>
|
|
||||||
<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>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('username','password')>
|
|
||||||
<span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<@field.password name="password" label=msg("password") forgotPassword=realm.resetPasswordAllowed/>
|
||||||
<label for="password" class="${properties.kcLabelClass!}">
|
|
||||||
<span class="pf-v5-c-form__label-text">${msg("password")}</span>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<div class="${properties.kcInputGroup!}" dir="ltr">
|
<div class="pf-v5-c-form__group">
|
||||||
<span class="${properties.kcInputClass!}">
|
<#if realm.rememberMe && !usernameHidden??>
|
||||||
<input tabindex="2" id="password" name="password" type="password" autocomplete="off"
|
<@field.checkbox name="rememberMe" label=msg("rememberMe") value=login.rememberMe?? />
|
||||||
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<button class="${properties.kcFormPasswordVisibilityButtonClass!}" type="button" aria-label="${msg('showPassword')}"
|
|
||||||
aria-controls="password" data-password-toggle
|
|
||||||
data-icon-show="${properties.kcFormPasswordVisibilityIconShow!}" data-icon-hide="${properties.kcFormPasswordVisibilityIconHide!}"
|
|
||||||
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
|
||||||
<i class="${properties.kcFormPasswordVisibilityIconShow!}" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<#if usernameHidden?? && messagesPerField.existsError('username','password')>
|
|
||||||
<span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
|
<div id="kc-form-buttons" class="pf-v5-c-form__group">
|
||||||
<div id="kc-form-options">
|
<input type="hidden" id="id-hidden-input" name="credentialId" <#if auth.selectedCredential?has_content>value="${auth.selectedCredential}"</#if>/>
|
||||||
<#if realm.rememberMe && !usernameHidden??>
|
<input tabindex="4" class="pf-v5-c-button pf-m-primary pf-m-block" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
||||||
<div class="checkbox">
|
</div>
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcFormOptionsWrapperClass!}">
|
|
||||||
<#if realm.resetPasswordAllowed>
|
|
||||||
<span><a tabindex="5" href="${url.loginResetCredentialsUrl}">${msg("doForgotPassword")}</a></span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="kc-form-buttons" class="${properties.kcFormGroupClass!}">
|
|
||||||
<input type="hidden" id="id-hidden-input" name="credentialId" <#if auth.selectedCredential?has_content>value="${auth.selectedCredential}"</#if>/>
|
|
||||||
<input tabindex="4" class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" name="login" id="kc-login" type="submit" value="${msg("doLogIn")}"/>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<#import "template.ftl" as layout>
|
<#import "template.ftl" as layout>
|
||||||
|
<#import "field.ftl" as field>
|
||||||
<#import "user-profile-commons.ftl" as userProfileCommons>
|
<#import "user-profile-commons.ftl" as userProfileCommons>
|
||||||
<#import "register-commons.ftl" as registerCommons>
|
<#import "register-commons.ftl" as registerCommons>
|
||||||
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
|
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
|
||||||
|
@ -15,65 +16,8 @@
|
||||||
<#if callback = "afterField">
|
<#if callback = "afterField">
|
||||||
<#-- render password fields just under the username or email (if used as username) -->
|
<#-- render password fields just under the username or email (if used as username) -->
|
||||||
<#if passwordRequired?? && (attribute.name == 'username' || (attribute.name == 'email' && realm.registrationEmailAsUsername))>
|
<#if passwordRequired?? && (attribute.name == 'username' || (attribute.name == 'email' && realm.registrationEmailAsUsername))>
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<@field.password name="password" label=msg("password") />
|
||||||
<label for="password" class="${properties.kcLabelClass!}">
|
<@field.password name="password-confirm" label=msg("passwordConfirm") />
|
||||||
<span class="pf-v5-c-form__label-text">
|
|
||||||
${msg("password")}
|
|
||||||
<span class="pf-v5-c-form__label-required" aria-hidden="true">*</span>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
<span class="${properties.kcInputGroup!}">
|
|
||||||
<span class="${properties.kcInputClass!}" dir="ltr">
|
|
||||||
<input type="password" id="password" name="password"
|
|
||||||
autocomplete="new-password"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<button class="${properties.kcFormPasswordVisibilityButtonClass!}" type="button" aria-label="${msg('showPassword')}"
|
|
||||||
aria-controls="password" data-password-toggle
|
|
||||||
data-icon-show="${properties.kcFormPasswordVisibilityIconShow!}" data-icon-hide="${properties.kcFormPasswordVisibilityIconHide!}"
|
|
||||||
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
|
||||||
<i class="${properties.kcFormPasswordVisibilityIconShow!}" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password')>
|
|
||||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="password-confirm" class="${properties.kcLabelClass!}">
|
|
||||||
<span class="pf-v5-c-form__label-text">
|
|
||||||
${msg("passwordConfirm")}
|
|
||||||
<span class="pf-v5-c-form__label-required" aria-hidden="true">*</span>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputGroup!}" dir="ltr">
|
|
||||||
<span class="${properties.kcInputClass!}">
|
|
||||||
<input type="password" id="password-confirm"
|
|
||||||
name="password-confirm"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<button class="${properties.kcFormPasswordVisibilityButtonClass!}" type="button" aria-label="${msg('showPassword')}"
|
|
||||||
aria-controls="password-confirm" data-password-toggle
|
|
||||||
data-icon-show="${properties.kcFormPasswordVisibilityIconShow!}" data-icon-hide="${properties.kcFormPasswordVisibilityIconHide!}"
|
|
||||||
data-label-show="${msg('showPassword')}" data-label-hide="${msg('hidePassword')}">
|
|
||||||
<i class="${properties.kcFormPasswordVisibilityIconShow!}" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password-confirm')>
|
|
||||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
</@userProfileCommons.userProfileFormFields>
|
</@userProfileCommons.userProfileFormFields>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<#import "footer.ftl" as loginFooter>
|
|
||||||
<#macro registrationLayout bodyClass="" displayInfo=false displayMessage=true displayRequiredFields=false>
|
<#macro registrationLayout bodyClass="" displayInfo=false displayMessage=true displayRequiredFields=false>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html class="${properties.kcHtmlClass!}"<#if realm.internationalizationEnabled> lang="${locale.currentLanguageTag}" dir="${(locale.rtl)?then('rtl','ltr')}"</#if>>
|
<html class="${properties.kcHtmlClass!}"<#if realm.internationalizationEnabled> lang="${locale.currentLanguageTag}"</#if>>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
@ -60,7 +59,7 @@
|
||||||
class="pf-v5-c-brand">${kcSanitize(msg("loginTitleHtml",(realm.displayNameHtml!'')))?no_esc}</div>
|
class="pf-v5-c-brand">${kcSanitize(msg("loginTitleHtml",(realm.displayNameHtml!'')))?no_esc}</div>
|
||||||
</header>
|
</header>
|
||||||
<main class="pf-v5-c-login__main">
|
<main class="pf-v5-c-login__main">
|
||||||
<header class="pf-v5-c-login__main-header">
|
<div class="pf-v5-c-login__main-header">
|
||||||
<h1 class="pf-v5-c-title pf-m-3xl" id="kc-page-title"><#nested "header"></h1>
|
<h1 class="pf-v5-c-title pf-m-3xl" id="kc-page-title"><#nested "header"></h1>
|
||||||
<#if realm.internationalizationEnabled && locale.supported?size gt 1>
|
<#if realm.internationalizationEnabled && locale.supported?size gt 1>
|
||||||
<div class="pf-v5-c-login__main-header-utilities">
|
<div class="pf-v5-c-login__main-header-utilities">
|
||||||
|
@ -100,7 +99,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
</header>
|
</div>
|
||||||
<div class="pf-v5-c-login__main-body">
|
<div class="pf-v5-c-login__main-body">
|
||||||
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
||||||
<#if displayRequiredFields>
|
<#if displayRequiredFields>
|
||||||
|
@ -180,8 +179,6 @@
|
||||||
<footer class="pf-v5-c-login__main-footer">
|
<footer class="pf-v5-c-login__main-footer">
|
||||||
<#nested "socialProviders">
|
<#nested "socialProviders">
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<@loginFooter.content/>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,9 +5,22 @@ styles=css/styles.css
|
||||||
stylesCommon=vendor/patternfly-v5/patternfly.min.css vendor/patternfly-v5/patternfly-addons.css
|
stylesCommon=vendor/patternfly-v5/patternfly.min.css vendor/patternfly-v5/patternfly-addons.css
|
||||||
|
|
||||||
kcFormGroupClass=pf-v5-c-form__group
|
kcFormGroupClass=pf-v5-c-form__group
|
||||||
|
kcFormGroupLabelClass=pf-v5-c-form__group-label
|
||||||
kcLabelClass=pf-v5-c-form__label
|
kcLabelClass=pf-v5-c-form__label
|
||||||
kcInputClass=pf-v5-c-form-control
|
kcInputClass=pf-v5-c-form-control
|
||||||
kcInputGroup=pf-v5-c-input-group
|
kcInputGroup=pf-v5-c-input-group
|
||||||
|
kcFormHelperTextClass=pf-v5-c-form__helper-text
|
||||||
|
kcInputHelperTextClass=pf-v5-c-helper-text
|
||||||
|
kcInputHelperTextItemClass=pf-v5-c-helper-text__item
|
||||||
|
kcInputHelperTextItemTextClass=pf-v5-c-helper-text__item-text
|
||||||
|
kcInputGroupItemClass=pf-v5-c-input-group__item
|
||||||
|
kcFill=pf-m-fill
|
||||||
|
kcError=pf-m-error
|
||||||
|
|
||||||
|
kcCheckboxClass=pf-v5-c-check
|
||||||
|
kcCheckboxInputClass=pf-v5-c-check__input
|
||||||
|
kcCheckboxLabelClass=pf-v5-c-check__label
|
||||||
|
kcCheckboxLabelRequiredClass=pf-v5-c-check__label-required
|
||||||
|
|
||||||
kcInputErrorMessageClass=pf-v5-c-helper-text__item pf-m-error pf-v5-c-form__label-required kc-feedback-text
|
kcInputErrorMessageClass=pf-v5-c-helper-text__item pf-m-error pf-v5-c-form__label-required kc-feedback-text
|
||||||
kcAlertClass=pf-v5-c-alert pf-m-inline
|
kcAlertClass=pf-v5-c-alert pf-m-inline
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
<#import "field.ftl" as field>
|
||||||
<#macro userProfileFormFields>
|
<#macro userProfileFormFields>
|
||||||
<#assign currentGroup="">
|
<#assign currentGroup="">
|
||||||
|
|
||||||
|
@ -35,26 +36,18 @@
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#nested "beforeField" attribute>
|
<#nested "beforeField" attribute>
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
<@field.group name=attribute.name label=advancedMsg(attribute.displayName!'') error=kcSanitize(messagesPerField.get('${attribute.name}'))?no_esc required=attribute.required>
|
||||||
<label for="${attribute.name}" class="${properties.kcLabelClass!}">${advancedMsg(attribute.displayName!'')}</label>
|
|
||||||
<#if attribute.required>*</#if>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
<#if attribute.annotations.inputHelperTextBefore??>
|
<#if attribute.annotations.inputHelperTextBefore??>
|
||||||
<div class="${properties.kcInputHelperTextBeforeClass!}" id="form-help-text-before-${attribute.name}" aria-live="polite">${kcSanitize(advancedMsg(attribute.annotations.inputHelperTextBefore))?no_esc}</div>
|
<div class="${properties.kcInputHelperTextBeforeClass!}" id="form-help-text-before-${attribute.name}" aria-live="polite">${kcSanitize(advancedMsg(attribute.annotations.inputHelperTextBefore))?no_esc}</div>
|
||||||
</#if>
|
</#if>
|
||||||
<@inputFieldByType attribute=attribute/>
|
<@inputFieldByType attribute=attribute/>
|
||||||
<#if messagesPerField.existsError('${attribute.name}')>
|
|
||||||
<span id="input-error-${attribute.name}" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('${attribute.name}'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
<#if attribute.annotations.inputHelperTextAfter??>
|
<#if attribute.annotations.inputHelperTextAfter??>
|
||||||
<div class="${properties.kcInputHelperTextAfterClass!}" id="form-help-text-after-${attribute.name}" aria-live="polite">${kcSanitize(advancedMsg(attribute.annotations.inputHelperTextAfter))?no_esc}</div>
|
<div class="${properties.kcInputHelperTextAfterClass!}" id="form-help-text-after-${attribute.name}" aria-live="polite">${kcSanitize(advancedMsg(attribute.annotations.inputHelperTextAfter))?no_esc}</div>
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</@field.group>
|
||||||
<#nested "afterField" attribute>
|
<#nested "afterField" attribute>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
|
@ -88,23 +81,25 @@
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro inputTag attribute value>
|
<#macro inputTag attribute value>
|
||||||
<input type="<@inputTagType attribute=attribute/>" id="${attribute.name}" name="${attribute.name}" value="${(value!'')}" class="${properties.kcInputClass!}"
|
<span class="${properties.kcInputClass} <#if error?has_content>${properties.kcError}</#if>">
|
||||||
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
|
<input type="<@inputTagType attribute=attribute/>" id="${attribute.name}" name="${attribute.name}" value="${(value!'')}" class="${properties.kcInputClass!}"
|
||||||
<#if attribute.readOnly>disabled</#if>
|
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
|
||||||
<#if attribute.autocomplete??>autocomplete="${attribute.autocomplete}"</#if>
|
<#if attribute.readOnly>disabled</#if>
|
||||||
<#if attribute.annotations.inputTypePlaceholder??>placeholder="${advancedMsg(attribute.annotations.inputTypePlaceholder)}"</#if>
|
<#if attribute.autocomplete??>autocomplete="${attribute.autocomplete}"</#if>
|
||||||
<#if attribute.annotations.inputTypePattern??>pattern="${attribute.annotations.inputTypePattern}"</#if>
|
<#if attribute.annotations.inputTypePlaceholder??>placeholder="${advancedMsg(attribute.annotations.inputTypePlaceholder)}"</#if>
|
||||||
<#if attribute.annotations.inputTypeSize??>size="${attribute.annotations.inputTypeSize}"</#if>
|
<#if attribute.annotations.inputTypePattern??>pattern="${attribute.annotations.inputTypePattern}"</#if>
|
||||||
<#if attribute.annotations.inputTypeMaxlength??>maxlength="${attribute.annotations.inputTypeMaxlength}"</#if>
|
<#if attribute.annotations.inputTypeSize??>size="${attribute.annotations.inputTypeSize}"</#if>
|
||||||
<#if attribute.annotations.inputTypeMinlength??>minlength="${attribute.annotations.inputTypeMinlength}"</#if>
|
<#if attribute.annotations.inputTypeMaxlength??>maxlength="${attribute.annotations.inputTypeMaxlength}"</#if>
|
||||||
<#if attribute.annotations.inputTypeMax??>max="${attribute.annotations.inputTypeMax}"</#if>
|
<#if attribute.annotations.inputTypeMinlength??>minlength="${attribute.annotations.inputTypeMinlength}"</#if>
|
||||||
<#if attribute.annotations.inputTypeMin??>min="${attribute.annotations.inputTypeMin}"</#if>
|
<#if attribute.annotations.inputTypeMax??>max="${attribute.annotations.inputTypeMax}"</#if>
|
||||||
<#if attribute.annotations.inputTypeStep??>step="${attribute.annotations.inputTypeStep}"</#if>
|
<#if attribute.annotations.inputTypeMin??>min="${attribute.annotations.inputTypeMin}"</#if>
|
||||||
<#if attribute.annotations.inputTypeStep??>step="${attribute.annotations.inputTypeStep}"</#if>
|
<#if attribute.annotations.inputTypeStep??>step="${attribute.annotations.inputTypeStep}"</#if>
|
||||||
<#list attribute.html5DataAnnotations as key, value>
|
<#if attribute.annotations.inputTypeStep??>step="${attribute.annotations.inputTypeStep}"</#if>
|
||||||
data-${key}="${value}"
|
<#list attribute.html5DataAnnotations as key, value>
|
||||||
</#list>
|
data-${key}="${value}"
|
||||||
/>
|
</#list>
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro inputTagType attribute>
|
<#macro inputTagType attribute>
|
||||||
|
|
Loading…
Reference in a new issue