Compare commits
6 commits
base-theme
...
main
Author | SHA1 | Date | |
---|---|---|---|
teutat3s | 060ecccc5f | ||
teutat3s | 2da41f4343 | ||
b12f | a63c3462f8 | ||
teutat3s | 87edb5c89c | ||
teutat3s | 09f7b1ed16 | ||
teutat3s | cab1c36247 |
|
@ -39,9 +39,6 @@
|
||||||
<input type="text" class="ps-input" id="email" name="email" autofocus value="${(account.email!'')}"/>
|
<input type="text" class="ps-input" id="email" name="email" autofocus value="${(account.email!'')}"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3>Personal details</h3>
|
|
||||||
<p>Please note that providing identifying data is not required and should be done with great care. At the moment, your first name and last name are only displayed in Nextcloud.</p>
|
|
||||||
|
|
||||||
<div class="ps-form-group ${messagesPerField.printIfExists('firstName','has-error')}">
|
<div class="ps-form-group ${messagesPerField.printIfExists('firstName','has-error')}">
|
||||||
<label for="firstName" class="ps-form-group--label">${msg("firstName")}</label>
|
<label for="firstName" class="ps-form-group--label">${msg("firstName")}</label>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
parent=account-v1
|
parent=keycloak.v2
|
||||||
import=common/pub.solar
|
import=common/pub.solar
|
||||||
|
|
||||||
styles=
|
styles=
|
||||||
|
|
|
@ -21,8 +21,10 @@ html {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 20px; }
|
font-size: 16px; }
|
||||||
|
@media screen and (min-width: 1200px) {
|
||||||
|
html {
|
||||||
|
font-size: 20px; } }
|
||||||
*:focus-visible {
|
*:focus-visible {
|
||||||
outline: 0.2rem solid var(--accent); }
|
outline: 0.2rem solid var(--accent); }
|
||||||
|
|
||||||
|
@ -57,23 +59,26 @@ html {
|
||||||
padding: 0rem 2rem; }
|
padding: 0rem 2rem; }
|
||||||
|
|
||||||
.ps-button {
|
.ps-button {
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
line-height: 1.2rem;
|
padding: 0.5em 1em;
|
||||||
border: 2px solid var(--foreground);
|
line-height: 1.2em;
|
||||||
border-radius: 1.5rem;
|
border: 0.125em solid var(--foreground);
|
||||||
|
border-radius: 1.5em;
|
||||||
background-color: var(--background-darker-2);
|
background-color: var(--background-darker-2);
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
.ps-button:hover, .ps-button:focus {
|
.ps-button:hover, .ps-button:focus {
|
||||||
border-color: var(--accent); }
|
border-color: var(--accent); }
|
||||||
.ps-button_primary {
|
.ps-button_primary {
|
||||||
border: 4px solid var(--foreground);
|
border: 0.25em solid var(--foreground);
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
.ps-button_primary:focus, .ps-button_primary:hover {
|
.ps-button_primary:focus, .ps-button_primary:hover {
|
||||||
background-color: var(--foreground);
|
background-color: var(--foreground);
|
||||||
color: var(--background); }
|
color: var(--background); }
|
||||||
|
.ps-button_small {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 0.25em 0.7em; }
|
||||||
|
|
||||||
.ps-input {
|
.ps-input {
|
||||||
padding: 0.5rem 0.5rem;
|
padding: 0.5rem 0.5rem;
|
||||||
|
@ -116,18 +121,20 @@ html {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column; }
|
flex-direction: column; }
|
||||||
.ps-form-group--label {
|
.ps-form-group--label {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.25rem;
|
||||||
display: flex;
|
display: inline-block;
|
||||||
font-weight: bold; }
|
font-weight: bold;
|
||||||
|
margin-top: 0.5rem; }
|
||||||
.ps-form-group .ps-button {
|
.ps-form-group .ps-button {
|
||||||
align-self: flex-start; }
|
align-self: flex-start; }
|
||||||
.ps-form-group--error {
|
.ps-form-group--error {
|
||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
|
.ps-form-group--buttons {
|
||||||
|
margin: 0.5rem 0; }
|
||||||
|
|
||||||
.ps-homelink {
|
.ps-homelink {
|
||||||
z-index: 100;
|
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
color: var(--foreground);
|
color: var(--foreground);
|
||||||
background: white;
|
background: white;
|
||||||
|
@ -197,7 +204,9 @@ html {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0; }
|
margin: 0;
|
||||||
|
overflow-x: auto;
|
||||||
|
z-index: 100; }
|
||||||
.ps-header--title {
|
.ps-header--title {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
|
@ -206,8 +215,9 @@ html {
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
border-right: 0.5rem solid var(--foreground);
|
border-right: 0.5rem solid var(--foreground);
|
||||||
pointer-events: all; }
|
pointer-events: all; }
|
||||||
|
.ps-header--i18n {
|
||||||
|
margin-left: auto; }
|
||||||
.ps-header--nav {
|
.ps-header--nav {
|
||||||
margin-left: auto;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
border-bottom: 0.5rem solid var(--foreground);
|
border-bottom: 0.5rem solid var(--foreground);
|
||||||
border-left: 0.5rem solid var(--foreground);
|
border-left: 0.5rem solid var(--foreground);
|
||||||
|
@ -260,6 +270,9 @@ html {
|
||||||
border-bottom: 0.5rem solid var(--foreground);
|
border-bottom: 0.5rem solid var(--foreground);
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
margin: 2rem; }
|
margin: 2rem; }
|
||||||
|
.ps-page--subtitle {
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
margin: 2rem; }
|
||||||
.ps-page--section {
|
.ps-page--section {
|
||||||
border: 12px solid black;
|
border: 12px solid black;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
|
@ -357,7 +370,8 @@ html {
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
border-bottom: 2px solid var(--foreground); }
|
border-bottom: 2px solid var(--foreground);
|
||||||
|
overflow-x: auto; }
|
||||||
.ps-section-nav--list {
|
.ps-section-nav--list {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
&--label {
|
&--label {
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.25rem;
|
||||||
display: flex;
|
display: inline-block;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
margin-top: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ps-button {
|
.ps-button {
|
||||||
|
@ -18,4 +19,8 @@
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
// font-family: monospace;
|
// font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--buttons {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,11 @@
|
||||||
margin: 2rem;
|
margin: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--subtitle {
|
||||||
|
padding-bottom: 0.25rem;
|
||||||
|
margin: 2rem;
|
||||||
|
};
|
||||||
|
|
||||||
&--section {
|
&--section {
|
||||||
border: 12px solid black;
|
border: 12px solid black;
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
|
|
|
@ -1,83 +1,12 @@
|
||||||
<#import "template.ftl" as layout>
|
<#import "template.ftl" as layout>
|
||||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('username','email','firstName','lastName'); section>
|
<#import "user-profile-commons.ftl" as userProfileCommons>
|
||||||
|
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
|
||||||
<#if section = "header">
|
<#if section = "header">
|
||||||
${msg("loginProfileTitle")}
|
${msg("loginProfileTitle")}
|
||||||
<#elseif section = "form">
|
<#elseif section = "form">
|
||||||
<form id="kc-update-profile-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
<form id="kc-update-profile-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||||
<#if user.editUsernameAllowed>
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" id="username" name="username" value="${(user.username!'')}"
|
|
||||||
class="${properties.kcInputClass!}"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('username')>
|
<@userProfileCommons.userProfileFormFields/>
|
||||||
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('username'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</#if>
|
|
||||||
<#if user.editEmailAllowed>
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" id="email" name="email" value="${(user.email!'')}"
|
|
||||||
class="${properties.kcInputClass!}"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('email')>
|
|
||||||
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('email'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" id="firstName" name="firstName" value="${(user.firstName!'')}"
|
|
||||||
class="${properties.kcInputClass!}"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('firstName')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('firstName')>
|
|
||||||
<span id="input-error-firstname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('firstName'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" id="lastName" name="lastName" value="${(user.lastName!'')}"
|
|
||||||
class="${properties.kcInputClass!}"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('lastName')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('lastName')>
|
|
||||||
<span id="input-error-lastname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('lastName'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
|
@ -87,13 +16,13 @@
|
||||||
|
|
||||||
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||||
<#if isAppInitiatedAction??>
|
<#if isAppInitiatedAction??>
|
||||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||||
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" type="submit" name="cancel-aia" value="true" />${msg("doCancel")}</button>
|
<button class="${properties.kcButtonClass!} ${properties.kcButtonDefaultClass!} ${properties.kcButtonLargeClass!}" type="submit" name="cancel-aia" value="true" formnovalidate/>${msg("doCancel")}</button>
|
||||||
<#else>
|
<#else>
|
||||||
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doSubmit")}" />
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</#if>
|
</#if>
|
||||||
</@layout.registrationLayout>
|
</@layout.registrationLayout>
|
|
@ -1,112 +1,99 @@
|
||||||
<#import "template.ftl" as layout>
|
<#import "template.ftl" as layout>
|
||||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('firstName','lastName','email','username','password','password-confirm'); section>
|
<#import "user-profile-commons.ftl" as userProfileCommons>
|
||||||
<#if section = "header">
|
<#import "register-commons.ftl" as registerCommons>
|
||||||
${msg("registerTitle")}
|
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
|
||||||
<#elseif section = "form">
|
<#if section = "header">
|
||||||
<form id="kc-register-form" class="ps-container" action="${url.registrationAction}" method="post">
|
<#if messageHeader??>
|
||||||
<!--div class="${properties.kcFormGroupClass!}">
|
${kcSanitize(msg("${messageHeader}"))?no_esc}
|
||||||
<label for="firstName" class="${properties.kcLabelClass!}">${msg("firstName")}</label>
|
<#else>
|
||||||
<input type="text" id="firstName" class="${properties.kcInputClass!}" name="firstName"
|
${msg("registerTitle")}
|
||||||
value="${(register.formData.firstName!'')}"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('firstName')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('firstName')>
|
|
||||||
<span id="input-error-firstname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('firstName'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
<#elseif section = "form">
|
||||||
|
<form id="kc-register-form" class="${properties.kcFormClass!}" action="${url.registrationAction}" method="post">
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<@userProfileCommons.userProfileFormFields; callback, attribute>
|
||||||
<label for="lastName" class="${properties.kcLabelClass!}">${msg("lastName")}</label>
|
<#if callback = "afterField">
|
||||||
<input type="text" id="lastName" class="${properties.kcInputClass!}" name="lastName"
|
<#-- render password fields just under the username or email (if used as username) -->
|
||||||
value="${(register.formData.lastName!'')}"
|
<#if passwordRequired?? && (attribute.name == 'username' || (attribute.name == 'email' && realm.registrationEmailAsUsername))>
|
||||||
aria-invalid="<#if messagesPerField.existsError('lastName')>true</#if>"
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
/>
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
|
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label> *
|
||||||
|
</div>
|
||||||
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
|
<div class="${properties.kcInputGroup!}">
|
||||||
|
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
||||||
|
autocomplete="new-password"
|
||||||
|
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('lastName')>
|
<#if messagesPerField.existsError('password')>
|
||||||
<span id="input-error-lastname" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
${kcSanitize(messagesPerField.get('lastName'))?no_esc}
|
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
||||||
</span>
|
</span>
|
||||||
</#if>
|
</#if>
|
||||||
</div-->
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if !realm.registrationEmailAsUsername>
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
<label for="username" class="${properties.kcLabelClass!}">${msg("username")}</label>
|
<label for="password-confirm"
|
||||||
<input type="text" id="username" class="${properties.kcInputClass!}" name="username"
|
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label> *
|
||||||
value="${(register.formData.username!'')}" autocomplete="username"
|
</div>
|
||||||
aria-invalid="<#if messagesPerField.existsError('username')>true</#if>"
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
/>
|
<div class="${properties.kcInputGroup!}">
|
||||||
|
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
||||||
|
name="password-confirm"
|
||||||
|
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<#if messagesPerField.existsError('username')>
|
<#if messagesPerField.existsError('password-confirm')>
|
||||||
<span id="input-error-username" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
||||||
${kcSanitize(messagesPerField.get('username'))?no_esc}
|
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
|
||||||
</span>
|
</span>
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</div>
|
||||||
|
</#if>
|
||||||
|
</#if>
|
||||||
|
</@userProfileCommons.userProfileFormFields>
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<@registerCommons.termsAcceptance/>
|
||||||
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
|
||||||
<input type="text" id="email" class="${properties.kcInputClass!}" name="email"
|
|
||||||
value="${(register.formData.email!'')}" autocomplete="email"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('email')>
|
<#if recaptchaRequired?? && (recaptchaVisible!false)>
|
||||||
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<div class="form-group">
|
||||||
${kcSanitize(messagesPerField.get('email'))?no_esc}
|
<div class="${properties.kcInputWrapperClass!}">
|
||||||
</span>
|
<div class="g-recaptcha" data-size="compact" data-sitekey="${recaptchaSiteKey}" data-action="${recaptchaAction}"></div>
|
||||||
</#if>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</#if>
|
||||||
|
|
||||||
<#if passwordRequired??>
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
|
|
||||||
<input type="password" id="password" class="${properties.kcInputClass!}" name="password"
|
|
||||||
autocomplete="new-password"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('password','password-confirm')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('password')>
|
<#if recaptchaRequired?? && !(recaptchaVisible!false)>
|
||||||
<span id="input-error-password" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<script>
|
||||||
${kcSanitize(messagesPerField.get('password'))?no_esc}
|
function onSubmitRecaptcha(token) {
|
||||||
</span>
|
document.getElementById("kc-register-form").submit();
|
||||||
</#if>
|
}
|
||||||
</div>
|
</script>
|
||||||
|
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<button class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!} g-recaptcha"
|
||||||
<label for="password-confirm"
|
data-sitekey="${recaptchaSiteKey}" data-callback='onSubmitRecaptcha' data-action='${recaptchaAction}' type="submit">
|
||||||
class="${properties.kcLabelClass!}">${msg("passwordConfirm")}</label>
|
${msg("doRegister")}
|
||||||
<input type="password" id="password-confirm" class="${properties.kcInputClass!}"
|
</button>
|
||||||
name="password-confirm"
|
</div>
|
||||||
aria-invalid="<#if messagesPerField.existsError('password-confirm')>true</#if>"
|
<#else>
|
||||||
/>
|
<div id="kc-form-buttons" class="${properties.kcFormButtonsClass!}">
|
||||||
|
<input class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}" type="submit" value="${msg("doRegister")}"/>
|
||||||
<#if messagesPerField.existsError('password-confirm')>
|
</div>
|
||||||
<span id="input-error-password-confirm" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
${kcSanitize(messagesPerField.get('password-confirm'))?no_esc}
|
<div class="${properties.kcFormOptionsWrapperClass!}">
|
||||||
</span>
|
<span><a href="${url.loginUrl}">${kcSanitize(msg("backToLogin"))?no_esc}</a></span>
|
||||||
</#if>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
|
</div>
|
||||||
<#if recaptchaRequired??>
|
</form>
|
||||||
<div class="ps-form-group">
|
</#if>
|
||||||
<div class="g-recaptcha" data-size="compact" data-sitekey="${recaptchaSiteKey}"></div>
|
|
||||||
</div>
|
|
||||||
</#if>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<button
|
|
||||||
class="${properties.kcButtonClass!} ${properties.kcButtonPrimaryClass!} ${properties.kcButtonBlockClass!} ${properties.kcButtonLargeClass!}"
|
|
||||||
>${msg("doRegister")}</button>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
|
||||||
<span><a href="${url.loginUrl}">${kcSanitize(msg("backToLogin"))?no_esc}</a></span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</#if>
|
|
||||||
</@layout.registrationLayout>
|
</@layout.registrationLayout>
|
||||||
|
|
115
login/resources/js/base64url.js
Normal file
115
login/resources/js/base64url.js
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// for embedded scripts, quoted and modified from https://github.com/swansontec/rfc4648.js by William Swanson
|
||||||
|
'use strict';
|
||||||
|
var base64url = base64url || {};
|
||||||
|
(function(base64url) {
|
||||||
|
|
||||||
|
function parse (string, encoding, opts = {}) {
|
||||||
|
// Build the character lookup table:
|
||||||
|
if (!encoding.codes) {
|
||||||
|
encoding.codes = {};
|
||||||
|
for (let i = 0; i < encoding.chars.length; ++i) {
|
||||||
|
encoding.codes[encoding.chars[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The string must have a whole number of bytes:
|
||||||
|
if (!opts.loose && (string.length * encoding.bits) & 7) {
|
||||||
|
throw new SyntaxError('Invalid padding');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the padding bytes:
|
||||||
|
let end = string.length;
|
||||||
|
while (string[end - 1] === '=') {
|
||||||
|
--end;
|
||||||
|
|
||||||
|
// If we get a whole number of bytes, there is too much padding:
|
||||||
|
if (!opts.loose && !(((string.length - end) * encoding.bits) & 7)) {
|
||||||
|
throw new SyntaxError('Invalid padding');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate the output:
|
||||||
|
const out = new (opts.out || Uint8Array)(((end * encoding.bits) / 8) | 0);
|
||||||
|
|
||||||
|
// Parse the data:
|
||||||
|
let bits = 0; // Number of bits currently in the buffer
|
||||||
|
let buffer = 0; // Bits waiting to be written out, MSB first
|
||||||
|
let written = 0; // Next byte to write
|
||||||
|
for (let i = 0; i < end; ++i) {
|
||||||
|
// Read one character from the string:
|
||||||
|
const value = encoding.codes[string[i]];
|
||||||
|
if (value === void 0) {
|
||||||
|
throw new SyntaxError('Invalid character ' + string[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the bits to the buffer:
|
||||||
|
buffer = (buffer << encoding.bits) | value;
|
||||||
|
bits += encoding.bits;
|
||||||
|
|
||||||
|
// Write out some bits if the buffer has a byte's worth:
|
||||||
|
if (bits >= 8) {
|
||||||
|
bits -= 8;
|
||||||
|
out[written++] = 0xff & (buffer >> bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that we have received just enough bits:
|
||||||
|
if (bits >= encoding.bits || 0xff & (buffer << (8 - bits))) {
|
||||||
|
throw new SyntaxError('Unexpected end of data');
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringify (data, encoding, opts = {}) {
|
||||||
|
const { pad = true } = opts;
|
||||||
|
const mask = (1 << encoding.bits) - 1;
|
||||||
|
let out = '';
|
||||||
|
|
||||||
|
let bits = 0; // Number of bits currently in the buffer
|
||||||
|
let buffer = 0; // Bits waiting to be written out, MSB first
|
||||||
|
for (let i = 0; i < data.length; ++i) {
|
||||||
|
// Slurp data into the buffer:
|
||||||
|
buffer = (buffer << 8) | (0xff & data[i]);
|
||||||
|
bits += 8;
|
||||||
|
|
||||||
|
// Write out as much as we can:
|
||||||
|
while (bits > encoding.bits) {
|
||||||
|
bits -= encoding.bits;
|
||||||
|
out += encoding.chars[mask & (buffer >> bits)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Partial character:
|
||||||
|
if (bits) {
|
||||||
|
out += encoding.chars[mask & (buffer << (encoding.bits - bits))];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add padding characters until we hit a byte boundary:
|
||||||
|
if (pad) {
|
||||||
|
while ((out.length * encoding.bits) & 7) {
|
||||||
|
out += '=';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
const encoding = {
|
||||||
|
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
|
||||||
|
bits: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
base64url.decode = function (string, opts) {
|
||||||
|
return parse(string, encoding, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
base64url.encode = function (data, opts) {
|
||||||
|
return stringify(data, encoding, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return base64url;
|
||||||
|
}(base64url));
|
||||||
|
|
||||||
|
|
||||||
|
|
15
login/resources/js/passwordVisibility.js
Normal file
15
login/resources/js/passwordVisibility.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
const toggle = (button) => {
|
||||||
|
const passwordElement = document.getElementById(button.getAttribute('aria-controls'));
|
||||||
|
if (passwordElement.type === "password") {
|
||||||
|
passwordElement.type = "text";
|
||||||
|
button.children.item(0).className = button.dataset.iconHide;
|
||||||
|
button.setAttribute("aria-label", button.dataset.labelHide);
|
||||||
|
} else if(passwordElement.type === "text") {
|
||||||
|
passwordElement.type = "password";
|
||||||
|
button.children.item(0).className = button.dataset.iconShow;
|
||||||
|
button.setAttribute("aria-label", button.dataset.labelShow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-password-toggle]')
|
||||||
|
.forEach(button => button.onclick = () => toggle(button));
|
|
@ -85,11 +85,13 @@
|
||||||
|
|
||||||
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
||||||
<h1 class="ps-page--title"><#nested "header"></h1>
|
<h1 class="ps-page--title"><#nested "header"></h1>
|
||||||
|
<div class="ps-page--subtitle">
|
||||||
<#if displayRequiredFields>
|
<#if displayRequiredFields>
|
||||||
<div class="${properties.kcLabelWrapperClass!} subtitle">
|
<div class="${properties.kcLabelWrapperClass!} subtitle">
|
||||||
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
<span class="subtitle"><span class="required">*</span> ${msg("requiredFields")}</span>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
|
</div>
|
||||||
<#else>
|
<#else>
|
||||||
<#if displayRequiredFields>
|
<#if displayRequiredFields>
|
||||||
<div class="${properties.kcContentWrapperClass!}">
|
<div class="${properties.kcContentWrapperClass!}">
|
||||||
|
|
|
@ -12,6 +12,9 @@ kcButtonLargeClass=ps-button_large
|
||||||
kcFormGroupClass=ps-form-group
|
kcFormGroupClass=ps-form-group
|
||||||
kcLabelClass=ps-form-group--label
|
kcLabelClass=ps-form-group--label
|
||||||
kcInputErrorMessageClass=ps-form-group--error
|
kcInputErrorMessageClass=ps-form-group--error
|
||||||
|
kcFormOptionsClass=ps-form-group--options
|
||||||
|
kcFormOptionsWrapperClass=ps-form-group--options-wrapper
|
||||||
|
kcFormButtonsClass=ps-form-group--buttons
|
||||||
|
|
||||||
kcInputClass=ps-input
|
kcInputClass=ps-input
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,12 @@
|
||||||
<#import "template.ftl" as layout>
|
<#import "template.ftl" as layout>
|
||||||
<#import "password-commons.ftl" as passwordCommons>
|
<#import "password-commons.ftl" as passwordCommons>
|
||||||
<@layout.registrationLayout displayMessage=!messagesPerField.existsError('email'); section>
|
<#import "user-profile-commons.ftl" as userProfileCommons>
|
||||||
|
<@layout.registrationLayout displayMessage=messagesPerField.exists('global') displayRequiredFields=true; section>
|
||||||
<#if section = "header">
|
<#if section = "header">
|
||||||
${msg("updateEmailTitle")}
|
${msg("updateEmailTitle")}
|
||||||
<#elseif section = "form">
|
<#elseif section = "form">
|
||||||
<form id="kc-update-email-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
<form id="kc-update-email-form" class="${properties.kcFormClass!}" action="${url.loginAction}" method="post">
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<@userProfileCommons.userProfileFormFields/>
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
|
||||||
<label for="email" class="${properties.kcLabelClass!}">${msg("email")}</label>
|
|
||||||
</div>
|
|
||||||
<div class="${properties.kcInputWrapperClass!}">
|
|
||||||
<input type="text" id="email" name="email" value="${(email.value!'')}"
|
|
||||||
class="${properties.kcInputClass!}"
|
|
||||||
aria-invalid="<#if messagesPerField.existsError('email')>true</#if>"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<#if messagesPerField.existsError('email')>
|
|
||||||
<span id="input-error-email" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
|
|
||||||
${kcSanitize(messagesPerField.get('email'))?no_esc}
|
|
||||||
</span>
|
|
||||||
</#if>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}">
|
||||||
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
<div id="kc-form-options" class="${properties.kcFormOptionsClass!}">
|
||||||
|
|
|
@ -3,27 +3,31 @@
|
||||||
|
|
||||||
<#list profile.attributes as attribute>
|
<#list profile.attributes as attribute>
|
||||||
|
|
||||||
<#assign groupName = attribute.group!"">
|
<#assign group = (attribute.group)!"">
|
||||||
<#if groupName != currentGroup>
|
<#if group != currentGroup>
|
||||||
<#assign currentGroup=groupName>
|
<#assign currentGroup=group>
|
||||||
<#if currentGroup != "" >
|
<#if currentGroup != "">
|
||||||
<div class="${properties.kcFormGroupClass!}">
|
<div class="${properties.kcFormGroupClass!}"
|
||||||
|
<#list group.html5DataAnnotations as key, value>
|
||||||
|
data-${key}="${value}"
|
||||||
|
</#list>
|
||||||
|
>
|
||||||
|
|
||||||
<#assign groupDisplayHeader=attribute.groupDisplayHeader!"">
|
<#assign groupDisplayHeader=group.displayHeader!"">
|
||||||
<#if groupDisplayHeader != "">
|
<#if groupDisplayHeader != "">
|
||||||
<#assign groupHeaderText=advancedMsg(attribute.groupDisplayHeader)!groupName>
|
<#assign groupHeaderText=advancedMsg(groupDisplayHeader)!group>
|
||||||
<#else>
|
<#else>
|
||||||
<#assign groupHeaderText=groupName>
|
<#assign groupHeaderText=group.name!"">
|
||||||
</#if>
|
</#if>
|
||||||
<div class="${properties.kcContentWrapperClass!}">
|
<div class="${properties.kcContentWrapperClass!}">
|
||||||
<label id="header-${groupName}" class="${kcFormGroupHeader!}">${groupHeaderText}</label>
|
<label id="header-${attribute.group.name}" class="${kcFormGroupHeader!}">${groupHeaderText}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<#assign groupDisplayDescription=attribute.groupDisplayDescription!"">
|
<#assign groupDisplayDescription=group.displayDescription!"">
|
||||||
<#if groupDisplayDescription != "">
|
<#if groupDisplayDescription != "">
|
||||||
<#assign groupDescriptionText=advancedMsg(attribute.groupDisplayDescription)!"">
|
<#assign groupDescriptionText=advancedMsg(groupDisplayDescription)!"">
|
||||||
<div class="${properties.kcLabelWrapperClass!}">
|
<div class="${properties.kcLabelWrapperClass!}">
|
||||||
<label id="description-${groupName}" class="${properties.kcLabelClass!}">${groupDescriptionText}</label>
|
<label id="description-${group.name}" class="${properties.kcLabelClass!}">${groupDescriptionText}</label>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,6 +57,10 @@
|
||||||
</div>
|
</div>
|
||||||
<#nested "afterField" attribute>
|
<#nested "afterField" attribute>
|
||||||
</#list>
|
</#list>
|
||||||
|
|
||||||
|
<#list profile.html5DataAnnotations?keys as key>
|
||||||
|
<script type="module" src="${url.resourcesPath}/js/${key}.js"></script>
|
||||||
|
</#list>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro inputFieldByType attribute>
|
<#macro inputFieldByType attribute>
|
||||||
|
@ -69,16 +77,22 @@
|
||||||
<@inputTagSelects attribute=attribute/>
|
<@inputTagSelects attribute=attribute/>
|
||||||
<#break>
|
<#break>
|
||||||
<#default>
|
<#default>
|
||||||
<@inputTag attribute=attribute/>
|
<#if attribute.multivalued && attribute.values?has_content>
|
||||||
|
<#list attribute.values as value>
|
||||||
|
<@inputTag attribute=attribute value=value!''/>
|
||||||
|
</#list>
|
||||||
|
<#else>
|
||||||
|
<@inputTag attribute=attribute value=attribute.value!''/>
|
||||||
|
</#if>
|
||||||
</#switch>
|
</#switch>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro inputTag attribute>
|
<#macro inputTag attribute value>
|
||||||
<input type="<@inputTagType attribute=attribute/>" id="${attribute.name}" name="${attribute.name}" value="${(attribute.value!'')}" class="${properties.kcInputClass!}"
|
<input type="<@inputTagType attribute=attribute/>" id="${attribute.name}" name="${attribute.name}" value="${(value!'')}" class="${properties.kcInputClass!}"
|
||||||
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
|
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
|
||||||
<#if attribute.readOnly>disabled</#if>
|
<#if attribute.readOnly>disabled</#if>
|
||||||
<#if attribute.autocomplete??>autocomplete="${attribute.autocomplete}"</#if>
|
<#if attribute.autocomplete??>autocomplete="${attribute.autocomplete}"</#if>
|
||||||
<#if attribute.annotations.inputTypePlaceholder??>placeholder="${attribute.annotations.inputTypePlaceholder}"</#if>
|
<#if attribute.annotations.inputTypePlaceholder??>placeholder="${advancedMsg(attribute.annotations.inputTypePlaceholder)}"</#if>
|
||||||
<#if attribute.annotations.inputTypePattern??>pattern="${attribute.annotations.inputTypePattern}"</#if>
|
<#if attribute.annotations.inputTypePattern??>pattern="${attribute.annotations.inputTypePattern}"</#if>
|
||||||
<#if attribute.annotations.inputTypeSize??>size="${attribute.annotations.inputTypeSize}"</#if>
|
<#if attribute.annotations.inputTypeSize??>size="${attribute.annotations.inputTypeSize}"</#if>
|
||||||
<#if attribute.annotations.inputTypeMaxlength??>maxlength="${attribute.annotations.inputTypeMaxlength}"</#if>
|
<#if attribute.annotations.inputTypeMaxlength??>maxlength="${attribute.annotations.inputTypeMaxlength}"</#if>
|
||||||
|
@ -86,6 +100,10 @@
|
||||||
<#if attribute.annotations.inputTypeMax??>max="${attribute.annotations.inputTypeMax}"</#if>
|
<#if attribute.annotations.inputTypeMax??>max="${attribute.annotations.inputTypeMax}"</#if>
|
||||||
<#if attribute.annotations.inputTypeMin??>min="${attribute.annotations.inputTypeMin}"</#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>
|
||||||
|
<#if attribute.annotations.inputTypeStep??>step="${attribute.annotations.inputTypeStep}"</#if>
|
||||||
|
<#list attribute.html5DataAnnotations as key, value>
|
||||||
|
data-${key}="${value}"
|
||||||
|
</#list>
|
||||||
/>
|
/>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
|
@ -128,13 +146,14 @@
|
||||||
<#assign options=attribute.validators[attribute.annotations.inputOptionsFromValidation].options>
|
<#assign options=attribute.validators[attribute.annotations.inputOptionsFromValidation].options>
|
||||||
<#elseif attribute.validators.options?? && attribute.validators.options.options??>
|
<#elseif attribute.validators.options?? && attribute.validators.options.options??>
|
||||||
<#assign options=attribute.validators.options.options>
|
<#assign options=attribute.validators.options.options>
|
||||||
|
<#else>
|
||||||
|
<#assign options=[]>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#if options??>
|
<#list options as option>
|
||||||
<#list options as option>
|
|
||||||
<option value="${option}" <#if attribute.values?seq_contains(option)>selected</#if>><@selectOptionLabelText attribute=attribute option=option/></option>
|
<option value="${option}" <#if attribute.values?seq_contains(option)>selected</#if>><@selectOptionLabelText attribute=attribute option=option/></option>
|
||||||
</#list>
|
</#list>
|
||||||
</#if>
|
|
||||||
</select>
|
</select>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
|
@ -144,21 +163,22 @@
|
||||||
<#assign classDiv=properties.kcInputClassRadio!>
|
<#assign classDiv=properties.kcInputClassRadio!>
|
||||||
<#assign classInput=properties.kcInputClassRadioInput!>
|
<#assign classInput=properties.kcInputClassRadioInput!>
|
||||||
<#assign classLabel=properties.kcInputClassRadioLabel!>
|
<#assign classLabel=properties.kcInputClassRadioLabel!>
|
||||||
<#else>
|
<#else>
|
||||||
<#assign inputType='checkbox'>
|
<#assign inputType='checkbox'>
|
||||||
<#assign classDiv=properties.kcInputClassCheckbox!>
|
<#assign classDiv=properties.kcInputClassCheckbox!>
|
||||||
<#assign classInput=properties.kcInputClassCheckboxInput!>
|
<#assign classInput=properties.kcInputClassCheckboxInput!>
|
||||||
<#assign classLabel=properties.kcInputClassCheckboxLabel!>
|
<#assign classLabel=properties.kcInputClassCheckboxLabel!>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#if attribute.annotations.inputOptionsFromValidation?? && attribute.validators[attribute.annotations.inputOptionsFromValidation]?? && attribute.validators[attribute.annotations.inputOptionsFromValidation].options??>
|
<#if attribute.annotations.inputOptionsFromValidation?? && attribute.validators[attribute.annotations.inputOptionsFromValidation]?? && attribute.validators[attribute.annotations.inputOptionsFromValidation].options??>
|
||||||
<#assign options=attribute.validators[attribute.annotations.inputOptionsFromValidation].options>
|
<#assign options=attribute.validators[attribute.annotations.inputOptionsFromValidation].options>
|
||||||
<#elseif attribute.validators.options?? && attribute.validators.options.options??>
|
<#elseif attribute.validators.options?? && attribute.validators.options.options??>
|
||||||
<#assign options=attribute.validators.options.options>
|
<#assign options=attribute.validators.options.options>
|
||||||
|
<#else>
|
||||||
|
<#assign options=[]>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#if options??>
|
<#list options as option>
|
||||||
<#list options as option>
|
|
||||||
<div class="${classDiv}">
|
<div class="${classDiv}">
|
||||||
<input type="${inputType}" id="${attribute.name}-${option}" name="${attribute.name}" value="${option}" class="${classInput}"
|
<input type="${inputType}" id="${attribute.name}-${option}" name="${attribute.name}" value="${option}" class="${classInput}"
|
||||||
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
|
aria-invalid="<#if messagesPerField.existsError('${attribute.name}')>true</#if>"
|
||||||
|
@ -167,9 +187,7 @@
|
||||||
/>
|
/>
|
||||||
<label for="${attribute.name}-${option}" class="${classLabel}<#if attribute.readOnly> ${properties.kcInputClassRadioCheckboxLabelDisabled!}</#if>"><@selectOptionLabelText attribute=attribute option=option/></label>
|
<label for="${attribute.name}-${option}" class="${classLabel}<#if attribute.readOnly> ${properties.kcInputClassRadioCheckboxLabelDisabled!}</#if>"><@selectOptionLabelText attribute=attribute option=option/></label>
|
||||||
</div>
|
</div>
|
||||||
</#list>
|
</#list>
|
||||||
</#if>
|
|
||||||
</select>
|
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
||||||
<#macro selectOptionLabelText attribute option>
|
<#macro selectOptionLabelText attribute option>
|
||||||
|
@ -184,4 +202,4 @@
|
||||||
</#if>
|
</#if>
|
||||||
</#if>
|
</#if>
|
||||||
</#compress>
|
</#compress>
|
||||||
</#macro>
|
</#macro>
|
||||||
|
|
12
overlay.nix
12
overlay.nix
|
@ -1,22 +1,10 @@
|
||||||
final: prev:
|
final: prev:
|
||||||
let
|
let
|
||||||
pkgs = final;
|
pkgs = final;
|
||||||
version = "0.1";
|
|
||||||
keycloak-account-v1 = prev.fetchMavenArtifact {
|
|
||||||
artifactId = "keycloak-account-v1";
|
|
||||||
groupId = "io.phasetwo.keycloak";
|
|
||||||
inherit version;
|
|
||||||
hash = "sha256-t4kuc5ZieqsC06/alFN0W1ktORuk36TIgKXfrmBtesA=";
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# this key should be the same as the simpleFlake name attribute.
|
# this key should be the same as the simpleFlake name attribute.
|
||||||
keycloak-theme-pub-solar = {
|
keycloak-theme-pub-solar = {
|
||||||
keycloak-theme-pub-solar = import ./pkgs/keycloak-theme-pub-solar.nix { inherit pkgs; };
|
keycloak-theme-pub-solar = import ./pkgs/keycloak-theme-pub-solar.nix { inherit pkgs; };
|
||||||
keycloak = prev.keycloak.overrideAttrs (finalAttrs: previousAttrs: {
|
|
||||||
installPhase = previousAttrs.installPhase + ''
|
|
||||||
ln -s ${keycloak-account-v1}/share/java/keycloak-account-v1-${version}.jar $out/providers/keycloak-account-v1-${version}.jar
|
|
||||||
'';
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue