2024-05-14 05:30:03 +02:00
|
|
|
<#assign pageId="PAGE_ID_xIgLsPgGId9D8e">
|
2024-07-07 18:45:14 +02:00
|
|
|
<#assign themeType="KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr">
|
2024-06-14 22:24:51 +02:00
|
|
|
const kcContext = ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
|
|
|
if( kcContext.messagesPerField ){
|
|
|
|
var existsError_singleFieldName = kcContext.messagesPerField.existsError;
|
|
|
|
kcContext.messagesPerField.existsError = function (){
|
2024-06-12 20:13:44 +02:00
|
|
|
for( let i = 0; i < arguments.length; i++ ){
|
|
|
|
if( existsError_singleFieldName(arguments[i]) ){
|
|
|
|
return true;
|
2024-05-14 05:30:03 +02:00
|
|
|
}
|
2024-06-12 20:13:44 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
2024-06-14 22:24:51 +02:00
|
|
|
kcContext.messagesPerField.exists = function (fieldName) {
|
|
|
|
return kcContext.messagesPerField.get(fieldName) !== "";
|
2024-06-12 19:41:05 +02:00
|
|
|
};
|
2024-06-14 22:24:51 +02:00
|
|
|
kcContext.messagesPerField.printIfExists = function (fieldName, text) {
|
|
|
|
return kcContext.messagesPerField.exists(fieldName) ? text : undefined;
|
2024-06-12 19:41:05 +02:00
|
|
|
};
|
2024-06-14 22:24:51 +02:00
|
|
|
kcContext.messagesPerField.getFirstError = function () {
|
2024-05-14 05:30:03 +02:00
|
|
|
for( let i = 0; i < arguments.length; i++ ){
|
|
|
|
const fieldName = arguments[i];
|
2024-06-14 22:24:51 +02:00
|
|
|
if( kcContext.messagesPerField.existsError(fieldName) ){
|
|
|
|
return kcContext.messagesPerField.get(fieldName);
|
2024-04-13 04:28:28 +02:00
|
|
|
}
|
2021-12-08 10:30:36 +03:00
|
|
|
}
|
2024-06-12 19:41:05 +02:00
|
|
|
};
|
|
|
|
}
|
2024-06-14 22:24:51 +02:00
|
|
|
kcContext.keycloakifyVersion = "KEYCLOAKIFY_VERSION_xEdKd3xEdr";
|
|
|
|
kcContext.themeVersion = "KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx";
|
2024-07-07 18:45:14 +02:00
|
|
|
kcContext.themeType = "${themeType}";
|
2024-06-14 22:24:51 +02:00
|
|
|
kcContext.themeName = "KEYCLOAKIFY_THEME_NAME_cXxKd3xEer";
|
|
|
|
kcContext.pageId = "${pageId}";
|
|
|
|
if( kcContext.url && kcContext.url.resourcesPath ){
|
|
|
|
kcContext.url.resourcesCommonPath = kcContext.url.resourcesPath + "/" + "RESOURCES_COMMON_cLsLsMrtDkpVv";
|
2024-06-12 19:41:05 +02:00
|
|
|
}
|
2024-06-21 02:01:32 +02:00
|
|
|
kcContext["x-keycloakify"] = {};
|
2024-05-26 16:21:04 +02:00
|
|
|
<#if profile?? && profile.attributes??>
|
2024-06-21 02:01:32 +02:00
|
|
|
kcContext["x-keycloakify"].realmMessageBundleUserProfile = {
|
2024-05-26 16:21:04 +02:00
|
|
|
<#list profile.attributes as attribute>
|
|
|
|
<#if attribute.annotations?? && attribute.displayName??>
|
2024-05-27 17:18:06 +02:00
|
|
|
"${attribute.displayName}": decodeHtmlEntities("${advancedMsg(attribute.displayName)?js_string}"),
|
2024-05-26 16:21:04 +02:00
|
|
|
</#if>
|
|
|
|
<#if attribute.annotations.inputHelperTextBefore??>
|
2024-05-27 17:18:06 +02:00
|
|
|
"${attribute.annotations.inputHelperTextBefore}": decodeHtmlEntities("${advancedMsg(attribute.annotations.inputHelperTextBefore)?js_string}"),
|
2024-05-26 16:21:04 +02:00
|
|
|
</#if>
|
|
|
|
<#if attribute.annotations.inputHelperTextAfter??>
|
2024-05-27 17:18:06 +02:00
|
|
|
"${attribute.annotations.inputHelperTextAfter}": decodeHtmlEntities("${advancedMsg(attribute.annotations.inputHelperTextAfter)?js_string}"),
|
2024-05-26 16:21:04 +02:00
|
|
|
</#if>
|
|
|
|
<#if attribute.annotations.inputTypePlaceholder??>
|
2024-05-27 17:18:06 +02:00
|
|
|
"${attribute.annotations.inputTypePlaceholder}": decodeHtmlEntities("${advancedMsg(attribute.annotations.inputTypePlaceholder)?js_string}"),
|
2024-05-26 16:21:04 +02:00
|
|
|
</#if>
|
2024-06-11 16:10:54 +02:00
|
|
|
<!-- Loop through the options that are in attribute.validators.options.options -->
|
|
|
|
<#if (
|
|
|
|
attribute.annotations.inputOptionLabelsI18nPrefix?? &&
|
|
|
|
attribute.validators?? &&
|
|
|
|
attribute.validators.options??
|
|
|
|
)>
|
|
|
|
<#list attribute.validators.options.options as option>
|
|
|
|
"${attribute.annotations.inputOptionLabelsI18nPrefix}.${option}": decodeHtmlEntities("${msg(attribute.annotations.inputOptionLabelsI18nPrefix + "." + option)?js_string}"),
|
|
|
|
</#list>
|
|
|
|
</#if>
|
2024-05-26 16:21:04 +02:00
|
|
|
</#list>
|
|
|
|
};
|
|
|
|
</#if>
|
2024-06-21 02:01:32 +02:00
|
|
|
<#if pageId == "terms.ftl" || termsAcceptanceRequired?? && termsAcceptanceRequired>
|
|
|
|
kcContext["x-keycloakify"].realmMessageBundleTermsText= decodeHtmlEntities("${msg("termsText")?js_string}");
|
|
|
|
</#if>
|
2024-06-10 17:30:00 +02:00
|
|
|
attributes_to_attributesByName: {
|
2024-06-14 22:24:51 +02:00
|
|
|
if( !kcContext.profile ){
|
2024-06-10 17:30:00 +02:00
|
|
|
break attributes_to_attributesByName;
|
|
|
|
}
|
2024-06-14 22:24:51 +02:00
|
|
|
if( !kcContext.profile.attributes ){
|
2024-06-10 17:30:00 +02:00
|
|
|
break attributes_to_attributesByName;
|
|
|
|
}
|
2024-06-14 22:24:51 +02:00
|
|
|
var attributes = kcContext.profile.attributes;
|
|
|
|
delete kcContext.profile.attributes;
|
|
|
|
kcContext.profile.attributesByName = {};
|
2024-06-10 17:30:00 +02:00
|
|
|
attributes.forEach(function(attribute){
|
2024-06-14 22:24:51 +02:00
|
|
|
kcContext.profile.attributesByName[attribute.name] = attribute;
|
2024-06-10 17:30:00 +02:00
|
|
|
});
|
|
|
|
}
|
2024-06-14 22:24:51 +02:00
|
|
|
window.kcContext = kcContext;
|
2024-05-27 17:18:06 +02:00
|
|
|
function decodeHtmlEntities(htmlStr){
|
|
|
|
var element = decodeHtmlEntities.element;
|
|
|
|
if (!element) {
|
|
|
|
element = document.createElement("textarea");
|
|
|
|
decodeHtmlEntities.element = element;
|
|
|
|
}
|
|
|
|
element.innerHTML = htmlStr;
|
2024-05-28 00:23:48 +02:00
|
|
|
return element.value;
|
2024-05-27 17:18:06 +02:00
|
|
|
}
|
2024-06-14 22:24:51 +02:00
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
<#function ftl_object_to_js_code_declaring_an_object object path>
|
|
|
|
|
|
|
|
<#local isHash = "">
|
|
|
|
<#attempt>
|
|
|
|
<#local isHash = object?is_hash || object?is_hash_ex>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Can't evaluate if " + path?join(".") + " is hash">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#if isHash>
|
|
|
|
|
|
|
|
<#if path?size gt 10>
|
2024-02-27 06:51:37 +01:00
|
|
|
<#return "ABORT: Too many recursive calls, path: " + path?join(".")>
|
2021-12-08 10:30:36 +03:00
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local keys = "">
|
|
|
|
|
|
|
|
<#attempt>
|
|
|
|
<#local keys = object?keys>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: We can't list keys on this object">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#local out_seq = []>
|
|
|
|
|
|
|
|
<#list keys as key>
|
|
|
|
|
|
|
|
<#if ["class","declaredConstructors","superclass","declaringClass" ]?seq_contains(key) >
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
2022-01-19 01:35:37 +03:00
|
|
|
<#if
|
2021-12-12 19:34:50 +01:00
|
|
|
(
|
2022-01-19 01:35:37 +03:00
|
|
|
["loginUpdatePasswordUrl", "loginUpdateProfileUrl", "loginUsernameReminderUrl", "loginUpdateTotpUrl"]?seq_contains(key) &&
|
2021-12-12 19:34:50 +01:00
|
|
|
are_same_path(path, ["url"])
|
|
|
|
) || (
|
2022-01-19 01:35:37 +03:00
|
|
|
key == "updateProfileCtx" &&
|
2021-12-12 19:34:50 +01:00
|
|
|
are_same_path(path, [])
|
2021-12-12 20:17:50 +01:00
|
|
|
) || (
|
2023-03-24 04:14:41 +01:00
|
|
|
<#-- https://github.com/keycloakify/keycloakify/pull/65#issuecomment-991896344 (reports with saml-post-form.ftl) -->
|
|
|
|
<#-- https://github.com/keycloakify/keycloakify/issues/91#issue-1212319466 (reports with error.ftl and Kc18) -->
|
|
|
|
<#-- https://github.com/keycloakify/keycloakify/issues/109#issuecomment-1134610163 -->
|
2023-06-12 21:34:24 +02:00
|
|
|
<#-- https://github.com/keycloakify/keycloakify/issues/357 -->
|
2024-02-17 03:45:43 +01:00
|
|
|
<#-- https://github.com/keycloakify/keycloakify/discussions/406#discussioncomment-7514787 -->
|
2022-01-19 01:35:37 +03:00
|
|
|
key == "loginAction" &&
|
|
|
|
are_same_path(path, ["url"]) &&
|
2024-02-17 03:45:43 +01:00
|
|
|
["saml-post-form.ftl", "error.ftl", "info.ftl", "login-oauth-grant.ftl", "logout-confirm.ftl", "login-oauth2-device-verify-user-code.ftl"]?seq_contains(pageId) &&
|
2022-05-23 16:51:18 +02:00
|
|
|
!(auth?has_content && auth.showTryAnotherWayLink())
|
2022-01-20 01:49:35 +01:00
|
|
|
) || (
|
2023-06-18 00:27:20 +02:00
|
|
|
<#-- https://github.com/keycloakify/keycloakify/issues/362 -->
|
|
|
|
["secretData", "value"]?seq_contains(key) &&
|
2023-06-18 16:13:18 +02:00
|
|
|
are_same_path(path, [ "totp", "otpCredentials", "*" ])
|
2023-06-18 00:27:20 +02:00
|
|
|
) || (
|
2022-01-20 01:49:35 +01:00
|
|
|
["contextData", "idpConfig", "idp", "authenticationSession"]?seq_contains(key) &&
|
|
|
|
are_same_path(path, ["brokerContext"]) &&
|
|
|
|
["login-idp-link-confirm.ftl", "login-idp-link-email.ftl" ]?seq_contains(pageId)
|
|
|
|
) || (
|
|
|
|
key == "identityProviderBrokerCtx" &&
|
|
|
|
are_same_path(path, []) &&
|
|
|
|
["login-idp-link-confirm.ftl", "login-idp-link-email.ftl" ]?seq_contains(pageId)
|
2022-07-02 11:01:14 +03:00
|
|
|
) || (
|
|
|
|
["masterAdminClient", "delegateForUpdate", "defaultRole"]?seq_contains(key) &&
|
|
|
|
are_same_path(path, ["realm"])
|
2023-03-07 17:05:03 +01:00
|
|
|
) || (
|
|
|
|
"error.ftl" == pageId &&
|
|
|
|
are_same_path(path, ["realm"]) &&
|
|
|
|
!["name", "displayName", "displayNameHtml", "internationalizationEnabled", "registrationEmailAsUsername" ]?seq_contains(key)
|
2023-10-22 16:39:15 +02:00
|
|
|
) || (
|
|
|
|
"applications.ftl" == pageId &&
|
2024-02-27 06:51:37 +01:00
|
|
|
(
|
|
|
|
key == "realm" ||
|
|
|
|
key == "container"
|
2024-05-28 01:08:02 +02:00
|
|
|
) &&
|
|
|
|
is_subpath(path, ["applications", "applications"])
|
2024-02-27 23:19:55 +01:00
|
|
|
) || (
|
2024-05-28 01:08:02 +02:00
|
|
|
key == "delegateForUpdate" &&
|
|
|
|
are_same_path(path, ["user"])
|
2024-03-19 14:57:32 +01:00
|
|
|
) || (
|
|
|
|
<#-- Security audit forwarded by Garth (Gmail) -->
|
2024-05-28 01:08:02 +02:00
|
|
|
key == "saml.signing.private.key" &&
|
|
|
|
are_same_path(path, ["client", "attributes"])
|
2024-04-09 17:17:12 +02:00
|
|
|
) || (
|
|
|
|
<#-- See: https://github.com/keycloakify/keycloakify/issues/534 -->
|
2024-05-28 01:08:02 +02:00
|
|
|
key == "password" &&
|
|
|
|
are_same_path(path, ["login"])
|
2024-04-21 20:29:18 +02:00
|
|
|
) || (
|
|
|
|
<#-- Remove realmAttributes added by https://github.com/jcputney/keycloak-theme-additional-info-extension for peace of mind. -->
|
2024-05-28 01:08:02 +02:00
|
|
|
key == "realmAttributes" &&
|
|
|
|
are_same_path(path, [])
|
2024-05-28 01:05:35 +02:00
|
|
|
) || (
|
2024-06-10 17:30:00 +02:00
|
|
|
<#-- attributesByName adds a lot of noise to the output and is not needed, we already have profile.attributes -->
|
|
|
|
key == "attributesByName" &&
|
2024-06-03 18:28:34 +02:00
|
|
|
are_same_path(path, ["profile"])
|
|
|
|
) || (
|
|
|
|
<#-- We already have the attributes in profile speedup the rendering by filtering it out from the register object -->
|
|
|
|
(key == "attributes" || key == "attributesByName") &&
|
2024-05-28 01:26:33 +02:00
|
|
|
are_same_path(path, ["register"])
|
2024-06-12 20:12:11 +02:00
|
|
|
) || (
|
|
|
|
are_same_path(path, ["properties"]) &&
|
|
|
|
(
|
|
|
|
key?starts_with("kc") ||
|
|
|
|
key == "locales" ||
|
|
|
|
key == "import" ||
|
|
|
|
key == "parent" ||
|
|
|
|
key == "meta" ||
|
|
|
|
key == "stylesCommon" ||
|
|
|
|
key == "styles" ||
|
|
|
|
key == "accountResourceProvider"
|
|
|
|
)
|
2024-06-12 22:18:55 +02:00
|
|
|
) || (
|
|
|
|
key == "execution" &&
|
|
|
|
are_same_path(path, [])
|
2024-06-21 02:01:32 +02:00
|
|
|
) || (
|
|
|
|
key == "entity" &&
|
|
|
|
are_same_path(path, ["user"])
|
2021-12-12 19:34:50 +01:00
|
|
|
)
|
2021-12-08 10:30:36 +03:00
|
|
|
>
|
2024-06-12 20:12:11 +02:00
|
|
|
<#-- <#local out_seq += ["/*" + path?join(".") + "." + key + " excluded*/"]> -->
|
2021-12-08 10:30:36 +03:00
|
|
|
<#continue>
|
|
|
|
</#if>
|
2024-06-06 01:31:00 +02:00
|
|
|
|
2024-02-17 03:45:43 +01:00
|
|
|
<#-- https://github.com/keycloakify/keycloakify/discussions/406 -->
|
|
|
|
<#if (
|
2024-06-11 11:37:45 +02:00
|
|
|
["register.ftl", "register-user-profile.ftl", "terms.ftl", "info.ftl", "login.ftl", "login-update-password.ftl", "login-oauth2-device-verify-user-code.ftl"]?seq_contains(pageId) &&
|
2024-02-17 03:45:43 +01:00
|
|
|
key == "attemptedUsername" && are_same_path(path, ["auth"])
|
|
|
|
)>
|
2021-12-12 19:19:17 +01:00
|
|
|
<#attempt>
|
|
|
|
<#-- https://github.com/keycloak/keycloak/blob/3a2bf0c04bcde185e497aaa32d0bb7ab7520cf4a/themes/src/main/resources/theme/base/login/template.ftl#L63 -->
|
|
|
|
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
2024-05-14 05:53:22 +02:00
|
|
|
<#local out_seq += ["/*" + path?join(".") + "." + key + " excluded*/"]>
|
2021-12-12 19:19:17 +01:00
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
<#recover>
|
2024-05-13 23:20:40 +02:00
|
|
|
<#local out_seq += ["/*Accessing attemptedUsername throwed an exception */"]>
|
2021-12-12 19:19:17 +01:00
|
|
|
</#attempt>
|
|
|
|
</#if>
|
2024-06-23 00:18:03 +02:00
|
|
|
|
|
|
|
USER_DEFINED_EXCLUSIONS_eKsaY4ZsZ4eMr2
|
2022-05-23 16:51:18 +02:00
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
<#attempt>
|
|
|
|
<#if !object[key]??>
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
<#recover>
|
|
|
|
<#local out_seq += ["/*Couldn't test if '" + key + "' is available on this object*/"]>
|
|
|
|
<#continue>
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#local propertyValue = "">
|
|
|
|
|
|
|
|
<#attempt>
|
|
|
|
<#local propertyValue = object[key]>
|
|
|
|
<#recover>
|
|
|
|
<#local out_seq += ["/*Couldn't dereference '" + key + "' on this object*/"]>
|
|
|
|
<#continue>
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#local rec_out = ftl_object_to_js_code_declaring_an_object(propertyValue, path + [ key ])>
|
|
|
|
|
|
|
|
<#if rec_out?starts_with("ABORT:")>
|
|
|
|
|
|
|
|
<#local errorMessage = rec_out?remove_beginning("ABORT:")>
|
|
|
|
|
|
|
|
<#if errorMessage != " It's a method" >
|
|
|
|
<#local out_seq += ["/*" + key + ": " + errorMessage + "*/"]>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local out_seq += ['"' + key + '": ' + rec_out + ","]>
|
|
|
|
|
|
|
|
</#list>
|
|
|
|
|
|
|
|
<#return (["{"] + out_seq?map(str -> ""?right_pad(4 * (path?size + 1)) + str) + [ ""?right_pad(4 * path?size) + "}"])?join("\n")>
|
|
|
|
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local isMethod = "">
|
|
|
|
<#attempt>
|
|
|
|
<#local isMethod = object?is_method>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Can't test if it'sa method.">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#if isMethod>
|
2022-06-19 23:30:05 +02:00
|
|
|
|
|
|
|
<#if are_same_path(path, ["auth", "showUsername"])>
|
|
|
|
<#attempt>
|
|
|
|
<#return auth.showUsername()?c>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Couldn't evaluate auth.showUsername()">
|
|
|
|
</#attempt>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if are_same_path(path, ["auth", "showResetCredentials"])>
|
|
|
|
<#attempt>
|
|
|
|
<#return auth.showResetCredentials()?c>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Couldn't evaluate auth.showResetCredentials()">
|
|
|
|
</#attempt>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if are_same_path(path, ["auth", "showTryAnotherWayLink"])>
|
|
|
|
<#attempt>
|
|
|
|
<#return auth.showTryAnotherWayLink()?c>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Couldn't evaluate auth.showTryAnotherWayLink()">
|
|
|
|
</#attempt>
|
|
|
|
</#if>
|
|
|
|
|
2024-05-14 03:30:27 +02:00
|
|
|
<#if are_same_path(path, ["url", "getLogoutUrl"])>
|
|
|
|
<#local returnValue = "">
|
|
|
|
<#attempt>
|
2024-05-14 05:05:18 +02:00
|
|
|
<#local returnValue = url.getLogoutUrl()>
|
2024-05-14 03:30:27 +02:00
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Couldn't evaluate url.getLogoutUrl()">
|
|
|
|
</#attempt>
|
|
|
|
<#return 'function(){ return "' + returnValue + '"; }'>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if are_same_path(path, ["totp", "policy", "getAlgorithmKey"])>
|
2024-06-15 17:33:27 +02:00
|
|
|
<#local returnValue = "error">
|
|
|
|
<#if mode?? && mode = "manual">
|
|
|
|
<#attempt>
|
|
|
|
<#local returnValue = totp.policy.getAlgorithmKey()>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Couldn't evaluate totp.policy.getAlgorithmKey()">
|
|
|
|
</#attempt>
|
|
|
|
</#if>
|
2024-05-14 03:30:27 +02:00
|
|
|
<#return 'function(){ return "' + returnValue + '"; }'>
|
|
|
|
</#if>
|
|
|
|
|
2024-06-12 19:41:05 +02:00
|
|
|
<#assign fieldNames = [ FIELD_NAMES_eKsIY4ZsZ4xeM ]>
|
|
|
|
<#if profile?? && profile.attributes??>
|
|
|
|
<#list profile.attributes as attribute>
|
|
|
|
<#if fieldNames?seq_contains(attribute.name)>
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
<#assign fieldNames += [attribute.name]>
|
|
|
|
</#list>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if are_same_path(path, ["messagesPerField", "get"])>
|
|
|
|
|
|
|
|
<#local jsFunctionCode = "function (fieldName) { ">
|
|
|
|
|
|
|
|
<#list fieldNames as fieldName>
|
|
|
|
|
|
|
|
<#-- See: https://github.com/keycloakify/keycloakify/issues/217 -->
|
2024-06-12 22:52:53 +02:00
|
|
|
<#if pageId == "login.ftl" >
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#if fieldName == "username">
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#local jsFunctionCode += "if(fieldName === 'username' || fieldName === 'password' ){ ">
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#if messagesPerField.exists('username') || messagesPerField.exists('password')>
|
2024-06-14 22:24:51 +02:00
|
|
|
<#local jsFunctionCode += "return kcContext.message && kcContext.message.summary ? kcContext.message.summary : 'error'; ">
|
2024-06-12 22:17:58 +02:00
|
|
|
<#else>
|
|
|
|
<#local jsFunctionCode += "return ''; ">
|
|
|
|
</#if>
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#local jsFunctionCode += "} ">
|
|
|
|
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if fieldName == "password">
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
2024-06-12 19:41:05 +02:00
|
|
|
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local jsFunctionCode += "if(fieldName === '" + fieldName + "'){ ">
|
|
|
|
|
|
|
|
<#if messagesPerField.exists('${fieldName}')>
|
|
|
|
<#local jsFunctionCode += 'return decodeHtmlEntities("' + messagesPerField.get('${fieldName}')?js_string + '"); '>
|
|
|
|
<#else>
|
|
|
|
<#local jsFunctionCode += "return ''; ">
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local jsFunctionCode += "} ">
|
|
|
|
|
|
|
|
</#list>
|
|
|
|
|
|
|
|
<#local jsFunctionCode += "}">
|
|
|
|
|
|
|
|
<#return jsFunctionCode>
|
|
|
|
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if are_same_path(path, ["messagesPerField", "existsError"])>
|
|
|
|
|
|
|
|
<#local jsFunctionCode = "function (fieldName) { ">
|
|
|
|
|
|
|
|
<#list fieldNames as fieldName>
|
|
|
|
|
|
|
|
<#-- See: https://github.com/keycloakify/keycloakify/issues/217 -->
|
2024-06-12 22:52:53 +02:00
|
|
|
<#if pageId == "login.ftl" >
|
2024-06-12 22:17:58 +02:00
|
|
|
<#if fieldName == "username">
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#local jsFunctionCode += "if(fieldName === 'username' || fieldName === 'password' ){ ">
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#if messagesPerField.existsError('username') || messagesPerField.existsError('password')>
|
|
|
|
<#local jsFunctionCode += "return true; ">
|
|
|
|
<#else>
|
|
|
|
<#local jsFunctionCode += "return false; ">
|
|
|
|
</#if>
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#local jsFunctionCode += "} ">
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#continue>
|
|
|
|
</#if>
|
2024-06-12 19:41:05 +02:00
|
|
|
|
2024-06-12 22:17:58 +02:00
|
|
|
<#if fieldName == "password">
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
2024-06-12 19:41:05 +02:00
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local jsFunctionCode += "if(fieldName === '" + fieldName + "' ){ ">
|
|
|
|
|
|
|
|
<#if messagesPerField.existsError('${fieldName}')>
|
|
|
|
<#local jsFunctionCode += 'return true; '>
|
|
|
|
<#else>
|
|
|
|
<#local jsFunctionCode += "return false; ">
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local jsFunctionCode += "}">
|
|
|
|
|
|
|
|
</#list>
|
|
|
|
|
|
|
|
<#local jsFunctionCode += "}">
|
|
|
|
|
|
|
|
<#return jsFunctionCode>
|
|
|
|
|
|
|
|
</#if>
|
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
<#return "ABORT: It's a method">
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local isBoolean = "">
|
|
|
|
<#attempt>
|
|
|
|
<#local isBoolean = object?is_boolean>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Can't test if it's a boolean">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#if isBoolean>
|
|
|
|
<#return object?c>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local isEnumerable = "">
|
|
|
|
<#attempt>
|
|
|
|
<#local isEnumerable = object?is_enumerable>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Can't test if it's an enumerable">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
|
|
|
|
<#if isEnumerable>
|
|
|
|
|
|
|
|
<#local out_seq = []>
|
|
|
|
|
|
|
|
<#local i = 0>
|
|
|
|
|
|
|
|
<#list object as array_item>
|
|
|
|
|
2022-09-13 10:49:20 +02:00
|
|
|
<#if !array_item??>
|
|
|
|
<#local out_seq += ["null,"]>
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
<#local rec_out = ftl_object_to_js_code_declaring_an_object(array_item, path + [ i ])>
|
|
|
|
|
|
|
|
<#local i = i + 1>
|
|
|
|
|
|
|
|
<#if rec_out?starts_with("ABORT:")>
|
|
|
|
|
|
|
|
<#local errorMessage = rec_out?remove_beginning("ABORT:")>
|
|
|
|
|
|
|
|
<#if errorMessage != " It's a method" >
|
|
|
|
<#local out_seq += ["/*" + i?string + ": " + errorMessage + "*/"]>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local out_seq += [rec_out + ","]>
|
|
|
|
|
|
|
|
</#list>
|
|
|
|
|
|
|
|
<#return (["["] + out_seq?map(str -> ""?right_pad(4 * (path?size + 1)) + str) + [ ""?right_pad(4 * path?size) + "]"])?join("\n")>
|
|
|
|
|
|
|
|
</#if>
|
|
|
|
|
2023-05-15 16:09:15 +02:00
|
|
|
<#local isDate = "">
|
|
|
|
<#attempt>
|
|
|
|
<#local isDate = object?is_date_like>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Can't test if it's a date">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#if isDate>
|
|
|
|
<#return '"' + object?datetime?iso_utc + '"'>
|
|
|
|
</#if>
|
|
|
|
|
2024-05-11 16:06:42 +02:00
|
|
|
<#local isNumber = "">
|
|
|
|
<#attempt>
|
|
|
|
<#local isNumber = object?is_number>
|
|
|
|
<#recover>
|
|
|
|
<#return "ABORT: Can't test if it's a number">
|
|
|
|
</#attempt>
|
|
|
|
|
|
|
|
<#if isNumber>
|
|
|
|
<#return object?c>
|
|
|
|
</#if>
|
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
<#attempt>
|
|
|
|
<#return '"' + object?js_string + '"'>;
|
|
|
|
<#recover>
|
|
|
|
</#attempt>
|
|
|
|
|
2024-05-11 16:06:42 +02:00
|
|
|
<#return "ABORT: Couldn't convert into string non hash, non method, non boolean, non number, non enumerable object">
|
2021-12-08 10:30:36 +03:00
|
|
|
|
2021-12-12 18:59:39 +01:00
|
|
|
</#function>
|
2024-02-27 06:51:37 +01:00
|
|
|
<#function is_subpath path searchedPath>
|
2021-12-12 18:59:39 +01:00
|
|
|
|
2024-02-27 06:51:37 +01:00
|
|
|
<#if path?size < searchedPath?size>
|
2021-12-12 18:59:39 +01:00
|
|
|
<#return false>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#local i=0>
|
|
|
|
|
|
|
|
<#list path as property>
|
|
|
|
|
2024-02-27 06:51:37 +01:00
|
|
|
<#if i == searchedPath?size >
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
2021-12-12 18:59:39 +01:00
|
|
|
<#local searchedProperty=searchedPath[i]>
|
|
|
|
|
2024-02-27 06:51:37 +01:00
|
|
|
<#local i+= 1>
|
|
|
|
|
2021-12-12 18:59:39 +01:00
|
|
|
<#if searchedProperty?is_string && searchedProperty == "*">
|
|
|
|
<#continue>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if searchedProperty?is_string && !property?is_string>
|
|
|
|
<#return false>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if searchedProperty?is_number && !property?is_number>
|
|
|
|
<#return false>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
<#if searchedProperty?string != property?string>
|
|
|
|
<#return false>
|
|
|
|
</#if>
|
|
|
|
|
|
|
|
</#list>
|
|
|
|
|
|
|
|
<#return true>
|
|
|
|
|
2021-12-08 10:30:36 +03:00
|
|
|
</#function>
|
2024-02-27 06:51:37 +01:00
|
|
|
|
|
|
|
<#function are_same_path path searchedPath>
|
|
|
|
<#return path?size == searchedPath?size && is_subpath(path, searchedPath)>
|
2024-06-14 22:24:51 +02:00
|
|
|
</#function>
|