From 2754900f7a6f7c970a0f34880bb894c7e7aee8b6 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sat, 13 Jul 2024 18:17:21 +0200 Subject: [PATCH] Refactor of the FreeMarker template --- src/bin/keycloakify/buildJars/buildJar.ts | 13 +- .../keycloakify/generateFtl/generateFtl.ts | 30 +- .../kcContextDeclarationTemplate.ftl | 849 +++++++++--------- .../generateResourcesForMainTheme.ts | 6 +- .../generateResourcesForThemeVariant.ts | 4 +- .../replacers/replaceImportsInCssCode.ts | 5 +- .../replacers/replaceImportsInJsCode/vite.ts | 10 +- .../replaceImportsInJsCode/webpack.ts | 4 +- src/vite-plugin/vite-plugin.ts | 2 +- test/bin/replacers.spec.ts | 46 +- 10 files changed, 487 insertions(+), 482 deletions(-) diff --git a/src/bin/keycloakify/buildJars/buildJar.ts b/src/bin/keycloakify/buildJars/buildJar.ts index a516f0ea..064fef18 100644 --- a/src/bin/keycloakify/buildJars/buildJar.ts +++ b/src/bin/keycloakify/buildJars/buildJar.ts @@ -24,6 +24,7 @@ export type BuildContextLike = BuildContextLike_generatePom & { artifactId: string; themeVersion: string; cacheDirPath: string; + recordIsImplementedByThemeType: BuildContext["recordIsImplementedByThemeType"]; }; assert(); @@ -134,6 +135,10 @@ export async function buildJar(params: { } route_legacy_pages: { + if (!buildContext.recordIsImplementedByThemeType.login) { + break route_legacy_pages; + } + // NOTE: If there's no account theme there is no special target for keycloak 24 and up so we create // the pages anyway. If there is an account pages, since we know that account-v1 is only support keycloak // 24 in version 0.4 and up, we can safely break the route for legacy pages. @@ -165,7 +170,7 @@ export async function buildJar(params: { const ftlFileContent = readFileSync(ftlFilePath).toString("utf8"); - const realPageId = (() => { + const ftlFileBasename = (() => { switch (pageId) { case "register.ftl": return "register-user-profile.ftl"; @@ -176,14 +181,14 @@ export async function buildJar(params: { })(); const modifiedFtlFileContent = ftlFileContent.replace( - `kcContext.pageId = "\${pageId}";`, - `kcContext.pageId = "${pageId}"; kcContext.realPageId = "${realPageId}";` + `"ftlTemplateFileName": "${pageId}"`, + `"ftlTemplateFileName": "${ftlFileBasename}"` ); assert(modifiedFtlFileContent !== ftlFileContent); fs.writeFile( - pathJoin(pathDirname(ftlFilePath), realPageId), + pathJoin(pathDirname(ftlFilePath), ftlFileBasename), Buffer.from(modifiedFtlFileContent, "utf8") ); }) diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts index 18e81527..fb0fe797 100644 --- a/src/bin/keycloakify/generateFtl/generateFtl.ts +++ b/src/bin/keycloakify/generateFtl/generateFtl.ts @@ -34,7 +34,6 @@ export function generateFtlFilesCodeFactory(params: { keycloakifyVersion: string; themeType: ThemeType; fieldNames: string[]; - isAccountV3: boolean; }) { const { themeName, @@ -42,8 +41,7 @@ export function generateFtlFilesCodeFactory(params: { buildContext, keycloakifyVersion, themeType, - fieldNames, - isAccountV3 + fieldNames } = params; const $ = cheerio.load(indexHtmlCode); @@ -70,8 +68,7 @@ export function generateFtlFilesCodeFactory(params: { const { fixedCssCode } = replaceImportsInCssCode({ cssCode, cssFileRelativeDirPath: undefined, - buildContext, - isAccountV3 + buildContext }); $(element).text(fixedCssCode); @@ -96,7 +93,7 @@ export function generateFtlFilesCodeFactory(params: { new RegExp( `^${(buildContext.urlPathname ?? "/").replace(/\//g, "\\/")}` ), - `\${${!isAccountV3 ? "url.resourcesPath" : "resourceUrl"}}/${basenameOfTheKeycloakifyResourcesDir}/` + `\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/` ) ); }) @@ -116,19 +113,17 @@ export function generateFtlFilesCodeFactory(params: { ) ) .toString("utf8") + .replace("{{themeType}}", themeType) + .replace("{{themeName}}", themeName) + .replace("{{keycloakifyVersion}}", keycloakifyVersion) + .replace("{{themeVersion}}", buildContext.themeVersion) + .replace("{{fieldNames}}", fieldNames.map(name => `"${name}"`).join(", ")) + .replace("{{RESOURCES_COMMON}}", resources_common) .replace( - "FIELD_NAMES_eKsIY4ZsZ4xeM", - fieldNames.map(name => `"${name}"`).join(", ") - ) - .replace("KEYCLOAKIFY_VERSION_xEdKd3xEdr", keycloakifyVersion) - .replace("KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx", buildContext.themeVersion) - .replace("KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr", themeType) - .replace("KEYCLOAKIFY_THEME_NAME_cXxKd3xEer", themeName) - .replace("RESOURCES_COMMON_cLsLsMrtDkpVv", resources_common) - .replace( - "USER_DEFINED_EXCLUSIONS_eKsaY4ZsZ4eMr2", + "{{userDefinedExclusions}}", buildContext.kcContextExclusionsFtlCode ?? "" ); + const ftlObjectToJsCodeDeclaringAnObjectPlaceholder = '{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }'; @@ -173,7 +168,8 @@ export function generateFtlFilesCodeFactory(params: { Object.entries({ [ftlObjectToJsCodeDeclaringAnObjectPlaceholder]: kcContextDeclarationTemplateFtl, - PAGE_ID_xIgLsPgGId9D8e: pageId + "{{pageId}}": pageId, + "{{ftlTemplateFileName}}": pageId }).map( ([searchValue, replaceValue]) => (ftlCode = ftlCode.replace(searchValue, replaceValue)) diff --git a/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl b/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl index 2b1479f4..5d7f0e17 100644 --- a/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +++ b/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl @@ -1,19 +1,48 @@ -<#assign pageId="PAGE_ID_xIgLsPgGId9D8e"> -<#assign themeType="KEYCLOAKIFY_THEME_TYPE_dExKd3xEdr"> -<#assign xKeycloakifyMessages = {}> +<#assign xKeycloakify={ + "messages": {}, + "pageId": "{{pageId}}", + "ftlTemplateFileName": "{{ftlTemplateFileName}}", + "themeType": "{{themeType}}", + "themeName": "{{themeName}}", + "keycloakifyVersion": "{{keycloakifyVersion}}", + "themeVersion": "{{themeVersion}}", + "resourcesPath": "" +}> -const kcContext = ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc}; +<#if url?? && url?is_hash && url.resourcesPath?? && url.resourcesPath?is_string> + <#assign xKeycloakify = xKeycloakify + { "resourcesPath": url.resourcesPath }> + +<#if resourceUrl?? && resourceUrl?is_string> + <#assign xKeycloakify = xKeycloakify + { "resourcesPath": resourceUrl }> + + +const kcContext = ${toJsDeclarationString(.data_model, [])?no_esc}; +kcContext.keycloakifyVersion = "${xKeycloakify.keycloakifyVersion}"; +kcContext.themeVersion = "${xKeycloakify.themeVersion}"; +kcContext.themeType = "${xKeycloakify.themeType}"; +kcContext.themeName = "${xKeycloakify.themeName}"; +kcContext.pageId = "${xKeycloakify.pageId}"; +kcContext.ftlTemplateFileName = "${xKeycloakify.ftlTemplateFileName}"; <@addNonAutomaticallyGatherableMessagesToXKeycloakifyMessages /> kcContext["x-keycloakify"] = {}; +kcContext["x-keycloakify"].resourcesPath = "${xKeycloakify.resourcesPath}"; + { - var messages = {}; - <#list xKeycloakifyMessages as key, resolvedMsg> - messages["${key}"] = decodeHtmlEntities("${resolvedMsg?js_string}"); - - kcContext["x-keycloakify"].messages = messages; + var messages = {}; + <#list xKeycloakify.messages as key, resolvedMsg> + messages["${key}"] = decodeHtmlEntities("${resolvedMsg?js_string}"); + + kcContext["x-keycloakify"].messages = messages; +} + +if( + kcContext.url instanceof Object && + typeof kcContext.url.resourcesPath === "string" +){ + kcContext.url.resourcesCommonPath = kcContext.url.resourcesPath + "/{{RESOURCES_COMMON}}"; } if( kcContext.messagesPerField ){ @@ -41,23 +70,6 @@ if( kcContext.messagesPerField ){ } }; } -kcContext.keycloakifyVersion = "KEYCLOAKIFY_VERSION_xEdKd3xEdr"; -kcContext.themeVersion = "KEYCLOAKIFY_THEME_VERSION_sIgKd3xEdr3dx"; -kcContext.themeType = "${themeType}"; -kcContext.themeName = "KEYCLOAKIFY_THEME_NAME_cXxKd3xEer"; -kcContext.pageId = "${pageId}"; -if( kcContext.url && kcContext.url.resourcesPath ){ - kcContext.url.resourcesCommonPath = kcContext.url.resourcesPath + "/" + "RESOURCES_COMMON_cLsLsMrtDkpVv"; -} -if( kcContext.resourceUrl && !kcContext.url ){ - Object.defineProperty(kcContext, "url", { - value: { - resourcesPath: kcContext.resourceUrl - }, - enumerable: false - }); -} - attributes_to_attributesByName: { if( !kcContext.profile ){ break attributes_to_attributesByName; @@ -83,451 +95,450 @@ function decodeHtmlEntities(htmlStr){ return element.value; } -<#function ftl_object_to_js_code_declaring_an_object object path> +<#function toJsDeclarationString object path> + <#local isHash = -1> + <#attempt> + <#local isHash = object?is_hash || object?is_hash_ex> + <#recover> + <#return "ABORT: Can't evaluate if " + path?join(".") + " is a hash"> + + + <#if isHash> + <#if path?size gt 10> + <#return "ABORT: Too many recursive calls, path: " + path?join(".")> + + <#local keys = -1> - <#local isHash = ""> <#attempt> - <#local isHash = object?is_hash || object?is_hash_ex> + <#local keys = object?keys> <#recover> - <#return "ABORT: Can't evaluate if " + path?join(".") + " is hash"> + <#return "ABORT: We can't list keys on object"> - <#if isHash> + <#local outSeq = []> - <#if path?size gt 10> - <#return "ABORT: Too many recursive calls, path: " + path?join(".")> + <#list keys as key> + <#if ["class","declaredConstructors","superclass","declaringClass" ]?seq_contains(key) > + <#continue> - <#local keys = ""> + <#if ( + areSamePath(path, ["url"]) && + ["loginUpdatePasswordUrl", "loginUpdateProfileUrl", "loginUsernameReminderUrl", "loginUpdateTotpUrl"]?seq_contains(key) + ) || ( + key == "updateProfileCtx" && + areSamePath(path, []) + ) || ( + <#-- 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 --> + <#-- https://github.com/keycloakify/keycloakify/issues/357 --> + <#-- https://github.com/keycloakify/keycloakify/discussions/406#discussioncomment-7514787 --> + key == "loginAction" && + areSamePath(path, ["url"]) && + ["saml-post-form.ftl", "error.ftl", "info.ftl", "login-oauth-grant.ftl", "logout-confirm.ftl", "login-oauth2-device-verify-user-code.ftl"]?seq_contains(xKeycloakify.pageId) && + !(auth?has_content && auth.showTryAnotherWayLink()) + ) || ( + <#-- https://github.com/keycloakify/keycloakify/issues/362 --> + ["secretData", "value"]?seq_contains(key) && + areSamePath(path, [ "totp", "otpCredentials", "*" ]) + ) || ( + ["contextData", "idpConfig", "idp", "authenticationSession"]?seq_contains(key) && + areSamePath(path, ["brokerContext"]) && + ["login-idp-link-confirm.ftl", "login-idp-link-email.ftl" ]?seq_contains(xKeycloakify.pageId) + ) || ( + key == "identityProviderBrokerCtx" && + areSamePath(path, []) && + ["login-idp-link-confirm.ftl", "login-idp-link-email.ftl" ]?seq_contains(xKeycloakify.pageId) + ) || ( + ["masterAdminClient", "delegateForUpdate", "defaultRole"]?seq_contains(key) && + areSamePath(path, ["realm"]) + ) || ( + xKeycloakify.pageId == "error.ftl" && + areSamePath(path, ["realm"]) && + !["name", "displayName", "displayNameHtml", "internationalizationEnabled", "registrationEmailAsUsername" ]?seq_contains(key) + ) || ( + xKeycloakify.pageId == "applications.ftl" && + ( + key == "realm" || + key == "container" + ) && + isSubpath(path, ["applications", "applications"]) + ) || ( + key == "delegateForUpdate" && + areSamePath(path, ["user"]) + ) || ( + <#-- Security audit forwarded by Garth (Gmail) --> + key == "saml.signing.private.key" && + areSamePath(path, ["client", "attributes"]) + ) || ( + <#-- See: https://github.com/keycloakify/keycloakify/issues/534 --> + key == "password" && + areSamePath(path, ["login"]) + ) || ( + <#-- Remove realmAttributes added by https://github.com/jcputney/keycloak-theme-additional-info-extension for peace of mind. --> + key == "realmAttributes" && + areSamePath(path, []) + ) || ( + <#-- attributesByName adds a lot of noise to the output and is not needed, we already have profile.attributes --> + key == "attributesByName" && + areSamePath(path, ["profile"]) + ) || ( + <#-- We already have the attributes in profile speedup the rendering by filtering it out from the register object --> + (key == "attributes" || key == "attributesByName") && + areSamePath(path, ["register"]) + ) || ( + areSamePath(path, ["properties"]) && + ( + key?starts_with("kc") || + key == "locales" || + key == "import" || + key == "parent" || + key == "meta" || + key == "stylesCommon" || + key == "styles" || + key == "accountResourceProvider" + ) + ) || ( + key == "execution" && + areSamePath(path, []) + ) || ( + key == "entity" && + areSamePath(path, ["user"]) + ) + > + <#-- <#local outSeq += ["/*" + path?join(".") + "." + key + " excluded*/"]> --> + <#continue> + + + <#-- https://github.com/keycloakify/keycloakify/discussions/406 --> + <#if ( + key == "attemptedUsername" && + areSamePath(path, ["auth"]) && + [ + "register.ftl", "terms.ftl", "info.ftl", "login.ftl", + "login-update-password.ftl", "login-oauth2-device-verify-user-code.ftl" + ]?seq_contains(xKeycloakify.pageId) + )> + <#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())> + <#local outSeq += ["/*" + path?join(".") + "." + key + " excluded*/"]> + <#continue> + + <#recover> + <#local outSeq += ["/*Accessing attemptedUsername throwed an exception */"]> + + + + {{userDefinedExclusions}} <#attempt> - <#local keys = object?keys> + <#if !object[key]??> + <#continue> + <#recover> - <#return "ABORT: We can't list keys on this object"> + <#local outSeq += ["/*Couldn't test if '" + key + "' is available on this object*/"]> + <#continue> - <#local out_seq = []> + <#local propertyValue = -1> - <#list keys as key> + <#attempt> + <#local propertyValue = object[key]> + <#recover> + <#local outSeq += ["/*Couldn't dereference '" + key + "' on this object*/"]> + <#continue> + - <#if ["class","declaredConstructors","superclass","declaringClass" ]?seq_contains(key) > - <#continue> + <#local recOut = toJsDeclarationString(propertyValue, path + [ key ])> + + <#if recOut?starts_with("ABORT:")> + + <#local errorMessage = recOut?remove_beginning("ABORT:")> + + <#if errorMessage != " It's a method" > + <#local outSeq += ["/*" + key + ": " + errorMessage + "*/"]> - <#if - ( - ["loginUpdatePasswordUrl", "loginUpdateProfileUrl", "loginUsernameReminderUrl", "loginUpdateTotpUrl"]?seq_contains(key) && - are_same_path(path, ["url"]) - ) || ( - key == "updateProfileCtx" && - are_same_path(path, []) - ) || ( - <#-- 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 --> - <#-- https://github.com/keycloakify/keycloakify/issues/357 --> - <#-- https://github.com/keycloakify/keycloakify/discussions/406#discussioncomment-7514787 --> - key == "loginAction" && - are_same_path(path, ["url"]) && - ["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) && - !(auth?has_content && auth.showTryAnotherWayLink()) - ) || ( - <#-- https://github.com/keycloakify/keycloakify/issues/362 --> - ["secretData", "value"]?seq_contains(key) && - are_same_path(path, [ "totp", "otpCredentials", "*" ]) - ) || ( - ["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) - ) || ( - ["masterAdminClient", "delegateForUpdate", "defaultRole"]?seq_contains(key) && - are_same_path(path, ["realm"]) - ) || ( - "error.ftl" == pageId && - are_same_path(path, ["realm"]) && - !["name", "displayName", "displayNameHtml", "internationalizationEnabled", "registrationEmailAsUsername" ]?seq_contains(key) - ) || ( - "applications.ftl" == pageId && - ( - key == "realm" || - key == "container" - ) && - is_subpath(path, ["applications", "applications"]) - ) || ( - key == "delegateForUpdate" && - are_same_path(path, ["user"]) - ) || ( - <#-- Security audit forwarded by Garth (Gmail) --> - key == "saml.signing.private.key" && - are_same_path(path, ["client", "attributes"]) - ) || ( - <#-- See: https://github.com/keycloakify/keycloakify/issues/534 --> - key == "password" && - are_same_path(path, ["login"]) - ) || ( - <#-- Remove realmAttributes added by https://github.com/jcputney/keycloak-theme-additional-info-extension for peace of mind. --> - key == "realmAttributes" && - are_same_path(path, []) - ) || ( - <#-- attributesByName adds a lot of noise to the output and is not needed, we already have profile.attributes --> - key == "attributesByName" && - 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") && - are_same_path(path, ["register"]) - ) || ( - are_same_path(path, ["properties"]) && - ( - key?starts_with("kc") || - key == "locales" || - key == "import" || - key == "parent" || - key == "meta" || - key == "stylesCommon" || - key == "styles" || - key == "accountResourceProvider" - ) - ) || ( - key == "execution" && - are_same_path(path, []) - ) || ( - key == "entity" && - are_same_path(path, ["user"]) - ) - > - <#-- <#local out_seq += ["/*" + path?join(".") + "." + key + " excluded*/"]> --> - <#continue> - - - <#-- https://github.com/keycloakify/keycloakify/discussions/406 --> - <#if ( - ["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) && - key == "attemptedUsername" && are_same_path(path, ["auth"]) - )> - <#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())> - <#local out_seq += ["/*" + path?join(".") + "." + key + " excluded*/"]> - <#continue> - - <#recover> - <#local out_seq += ["/*Accessing attemptedUsername throwed an exception */"]> - - + <#continue> + - USER_DEFINED_EXCLUSIONS_eKsaY4ZsZ4eMr2 - + <#local outSeq += ['"' + key + '": ' + recOut + ","]> + + + + <#return (["{"] + outSeq?map(str -> ""?right_pad(4 * (path?size + 1)) + str) + [ ""?right_pad(4 * path?size) + "}"])?join("\n")> + + + + <#local isMethod = -1> + <#attempt> + <#local isMethod = object?is_method> + <#recover> + <#return "ABORT: Can't test if it'sa method."> + + + <#if isMethod> + + <#if areSamePath(path, ["auth", "showUsername"])> + <#attempt> + <#return auth.showUsername()?c> + <#recover> + <#return "ABORT: Couldn't evaluate auth.showUsername()"> + + + + <#if areSamePath(path, ["auth", "showResetCredentials"])> + <#attempt> + <#return auth.showResetCredentials()?c> + <#recover> + <#return "ABORT: Couldn't evaluate auth.showResetCredentials()"> + + + + <#if areSamePath(path, ["auth", "showTryAnotherWayLink"])> + <#attempt> + <#return auth.showTryAnotherWayLink()?c> + <#recover> + <#return "ABORT: Couldn't evaluate auth.showTryAnotherWayLink()"> + + + + <#if areSamePath(path, ["url", "getLogoutUrl"])> + <#local returnValue = -1> + <#attempt> + <#local returnValue = url.getLogoutUrl()> + <#recover> + <#return "ABORT: Couldn't evaluate url.getLogoutUrl()"> + + <#return 'function(){ return "' + returnValue + '"; }'> + + + <#if areSamePath(path, ["totp", "policy", "getAlgorithmKey"])> + <#local returnValue = "error"> + <#if mode?? && mode = "manual"> <#attempt> - <#if !object[key]??> + <#local returnValue = totp.policy.getAlgorithmKey()> + <#recover> + <#return "ABORT: Couldn't evaluate totp.policy.getAlgorithmKey()"> + + + <#return 'function(){ return "' + returnValue + '"; }'> + + + <#assign fieldNames = [{{fieldNames}}]> + <#if profile?? && profile.attributes??> + <#list profile.attributes as attribute> + <#if fieldNames?seq_contains(attribute.name)> + <#continue> + + <#assign fieldNames += [attribute.name]> + + + + <#if areSamePath(path, ["messagesPerField", "get"])> + + <#local jsFunctionCode = "function (fieldName) { "> + + <#list fieldNames as fieldName> + + <#-- See: https://github.com/keycloakify/keycloakify/issues/217 --> + <#if xKeycloakify.pageId == "login.ftl" > + + <#if fieldName == "username"> + + <#local jsFunctionCode += "if(fieldName === 'username' || fieldName === 'password' ){ "> + + <#if messagesPerField.exists('username') || messagesPerField.exists('password')> + <#local jsFunctionCode += "return kcContext.message && kcContext.message.summary ? kcContext.message.summary : 'error'; "> + <#else> + <#local jsFunctionCode += "return ''; "> + + + <#local jsFunctionCode += "} "> + <#continue> - <#recover> - <#local out_seq += ["/*Couldn't test if '" + key + "' is available on this object*/"]> - <#continue> - - <#local propertyValue = ""> - - <#attempt> - <#local propertyValue = object[key]> - <#recover> - <#local out_seq += ["/*Couldn't dereference '" + key + "' on this object*/"]> - <#continue> - - - <#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 fieldName == "password"> + <#continue> - <#continue> - <#local out_seq += ['"' + key + '": ' + rec_out + ","]> + <#local jsFunctionCode += "if(fieldName === '" + fieldName + "'){ "> + + <#if messagesPerField.exists('${fieldName}')> + <#local jsFunctionCode += 'return decodeHtmlEntities("' + messagesPerField.get('${fieldName}')?js_string + '"); '> + <#else> + <#local jsFunctionCode += "return ''; "> + + + <#local jsFunctionCode += "} "> - <#return (["{"] + out_seq?map(str -> ""?right_pad(4 * (path?size + 1)) + str) + [ ""?right_pad(4 * path?size) + "}"])?join("\n")> + <#local jsFunctionCode += "}"> + + <#return jsFunctionCode> - <#local isMethod = ""> - <#attempt> - <#local isMethod = object?is_method> - <#recover> - <#return "ABORT: Can't test if it'sa method."> - + <#if areSamePath(path, ["messagesPerField", "existsError"])> - <#if isMethod> + <#local jsFunctionCode = "function (fieldName) { "> - <#if are_same_path(path, ["auth", "showUsername"])> - <#attempt> - <#return auth.showUsername()?c> - <#recover> - <#return "ABORT: Couldn't evaluate auth.showUsername()"> - - + <#list fieldNames as fieldName> - <#if are_same_path(path, ["auth", "showResetCredentials"])> - <#attempt> - <#return auth.showResetCredentials()?c> - <#recover> - <#return "ABORT: Couldn't evaluate auth.showResetCredentials()"> - - + <#-- See: https://github.com/keycloakify/keycloakify/issues/217 --> + <#if xKeycloakify.pageId == "login.ftl" > + <#if fieldName == "username"> - <#if are_same_path(path, ["auth", "showTryAnotherWayLink"])> - <#attempt> - <#return auth.showTryAnotherWayLink()?c> - <#recover> - <#return "ABORT: Couldn't evaluate auth.showTryAnotherWayLink()"> - - + <#local jsFunctionCode += "if(fieldName === 'username' || fieldName === 'password' ){ "> - <#if are_same_path(path, ["url", "getLogoutUrl"])> - <#local returnValue = ""> - <#attempt> - <#local returnValue = url.getLogoutUrl()> - <#recover> - <#return "ABORT: Couldn't evaluate url.getLogoutUrl()"> - - <#return 'function(){ return "' + returnValue + '"; }'> - + <#if messagesPerField.existsError('username') || messagesPerField.existsError('password')> + <#local jsFunctionCode += "return true; "> + <#else> + <#local jsFunctionCode += "return false; "> + - <#if are_same_path(path, ["totp", "policy", "getAlgorithmKey"])> - <#local returnValue = "error"> - <#if mode?? && mode = "manual"> - <#attempt> - <#local returnValue = totp.policy.getAlgorithmKey()> - <#recover> - <#return "ABORT: Couldn't evaluate totp.policy.getAlgorithmKey()"> - - - <#return 'function(){ return "' + returnValue + '"; }'> - + <#local jsFunctionCode += "} "> - <#assign fieldNames = [ FIELD_NAMES_eKsIY4ZsZ4xeM ]> - <#if profile?? && profile.attributes??> - <#list profile.attributes as attribute> - <#if fieldNames?seq_contains(attribute.name)> <#continue> - <#assign fieldNames += [attribute.name]> - - - - <#if are_same_path(path, ["messagesPerField", "get"])> - - <#local jsFunctionCode = "function (fieldName) { "> - - <#list fieldNames as fieldName> - - <#-- See: https://github.com/keycloakify/keycloakify/issues/217 --> - <#if pageId == "login.ftl" > - - <#if fieldName == "username"> - - <#local jsFunctionCode += "if(fieldName === 'username' || fieldName === 'password' ){ "> - - <#if messagesPerField.exists('username') || messagesPerField.exists('password')> - <#local jsFunctionCode += "return kcContext.message && kcContext.message.summary ? kcContext.message.summary : 'error'; "> - <#else> - <#local jsFunctionCode += "return ''; "> - - - <#local jsFunctionCode += "} "> - - <#continue> - - - <#if fieldName == "password"> - <#continue> - + <#if fieldName == "password"> + <#continue> - - <#local jsFunctionCode += "if(fieldName === '" + fieldName + "'){ "> - - <#if messagesPerField.exists('${fieldName}')> - <#local jsFunctionCode += 'return decodeHtmlEntities("' + messagesPerField.get('${fieldName}')?js_string + '"); '> - <#else> - <#local jsFunctionCode += "return ''; "> - - - <#local jsFunctionCode += "} "> - - - - <#local jsFunctionCode += "}"> - - <#return jsFunctionCode> - - - - <#if are_same_path(path, ["messagesPerField", "existsError"])> - - <#local jsFunctionCode = "function (fieldName) { "> - - <#list fieldNames as fieldName> - - <#-- See: https://github.com/keycloakify/keycloakify/issues/217 --> - <#if pageId == "login.ftl" > - <#if fieldName == "username"> - - <#local jsFunctionCode += "if(fieldName === 'username' || fieldName === 'password' ){ "> - - <#if messagesPerField.existsError('username') || messagesPerField.existsError('password')> - <#local jsFunctionCode += "return true; "> - <#else> - <#local jsFunctionCode += "return false; "> - - - <#local jsFunctionCode += "} "> - - <#continue> - - - <#if fieldName == "password"> - <#continue> - - - - <#local jsFunctionCode += "if(fieldName === '" + fieldName + "' ){ "> - - <#if messagesPerField.existsError('${fieldName}')> - <#local jsFunctionCode += 'return true; '> - <#else> - <#local jsFunctionCode += "return false; "> - - - <#local jsFunctionCode += "}"> - - - - <#local jsFunctionCode += "}"> - - <#return jsFunctionCode> - - - - <#if themeType == "account" && are_same_path(path, ["realm", "isInternationalizationEnabled"])> - <#attempt> - <#return realm.isInternationalizationEnabled()?c> - <#recover> - <#return "ABORT: Couldn't evaluate realm.isInternationalizationEnabled()"> - - - - <#return "ABORT: It's a method"> - - - <#local isBoolean = ""> - <#attempt> - <#local isBoolean = object?is_boolean> - <#recover> - <#return "ABORT: Can't test if it's a boolean"> - - - <#if isBoolean> - <#return object?c> - - - <#local isEnumerable = ""> - <#attempt> - <#local isEnumerable = object?is_enumerable> - <#recover> - <#return "ABORT: Can't test if it's an enumerable"> - - - - <#if isEnumerable> - - <#local out_seq = []> - - <#local i = 0> - - <#list object as array_item> - - <#if !array_item??> - <#local out_seq += ["null,"]> - <#continue> - <#local rec_out = ftl_object_to_js_code_declaring_an_object(array_item, path + [ i ])> + <#local jsFunctionCode += "if(fieldName === '" + fieldName + "' ){ "> - <#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 + "*/"]> - - - <#continue> + <#if messagesPerField.existsError('${fieldName}')> + <#local jsFunctionCode += 'return true; '> + <#else> + <#local jsFunctionCode += "return false; "> - <#local out_seq += [rec_out + ","]> + <#local jsFunctionCode += "}"> - <#return (["["] + out_seq?map(str -> ""?right_pad(4 * (path?size + 1)) + str) + [ ""?right_pad(4 * path?size) + "]"])?join("\n")> + <#local jsFunctionCode += "}"> + + <#return jsFunctionCode> - <#local isDate = ""> - <#attempt> - <#local isDate = object?is_date_like> - <#recover> - <#return "ABORT: Can't test if it's a date"> - - - <#if isDate> - <#return '"' + object?datetime?iso_utc + '"'> + <#if xKeycloakify.themeType == "account" && areSamePath(path, ["realm", "isInternationalizationEnabled"])> + <#attempt> + <#return realm.isInternationalizationEnabled()?c> + <#recover> + <#return "ABORT: Couldn't evaluate realm.isInternationalizationEnabled()"> + - <#local isNumber = ""> - <#attempt> - <#local isNumber = object?is_number> - <#recover> - <#return "ABORT: Can't test if it's a number"> - + <#return "ABORT: It's a method"> + - <#if isNumber> - <#return object?c> - + <#local isBoolean = -1> + <#attempt> + <#local isBoolean = object?is_boolean> + <#recover> + <#return "ABORT: Can't test if it's a boolean"> + - <#local isString = ""> - <#attempt> - <#local isString = object?is_string> - <#recover> - <#return "ABORT: Can't test if it's a string"> - + <#if isBoolean> + <#return object?c> + - <#if isString> - <@addToXKeycloakifyMessagesIfMessageKey str=object /> - + <#local isEnumerable = -1> + <#attempt> + <#local isEnumerable = object?is_enumerable> + <#recover> + <#return "ABORT: Can't test if it's an enumerable"> + - <#attempt> - <#return '"' + object?js_string + '"'>; - <#recover> - - <#return "ABORT: Couldn't convert into string non hash, non method, non boolean, non number, non enumerable object"> + <#if isEnumerable> + + <#local outSeq = []> + + <#local i = 0> + + <#list object as array_item> + + <#if !array_item??> + <#local outSeq += ["null,"]> + <#continue> + + + <#local recOut = toJsDeclarationString(array_item, path + [ i ])> + + <#local i = i + 1> + + <#if recOut?starts_with("ABORT:")> + + <#local errorMessage = recOut?remove_beginning("ABORT:")> + + <#if errorMessage != " It's a method" > + <#local outSeq += ["/*" + i?string + ": " + errorMessage + "*/"]> + + + <#continue> + + + <#local outSeq += [recOut + ","]> + + + + <#return (["["] + outSeq?map(str -> ""?right_pad(4 * (path?size + 1)) + str) + [ ""?right_pad(4 * path?size) + "]"])?join("\n")> + + + + <#local isDate = -1> + <#attempt> + <#local isDate = object?is_date_like> + <#recover> + <#return "ABORT: Can't test if it's a date"> + + + <#if isDate> + <#return '"' + object?datetime?iso_utc + '"'> + + + <#local isNumber = -1> + <#attempt> + <#local isNumber = object?is_number> + <#recover> + <#return "ABORT: Can't test if it's a number"> + + + <#if isNumber> + <#return object?c> + + + <#local isString = -1> + <#attempt> + <#local isString = object?is_string> + <#recover> + <#return "ABORT: Can't test if it's a string"> + + + <#if isString> + <@addToXKeycloakifyMessagesIfMessageKey str=object /> + + + <#attempt> + <#return 'decodeHtmlEntities("' + object?js_string + '")'>; + <#recover> + + + <#return "ABORT: Couldn't convert into string non hash, non method, non boolean, non number, non enumerable object"> -<#function is_subpath path searchedPath> +<#function isSubpath path searchedPath> <#if path?size < searchedPath?size> <#return false> @@ -567,8 +578,8 @@ function decodeHtmlEntities(htmlStr){ -<#function are_same_path path searchedPath> - <#return path?size == searchedPath?size && is_subpath(path, searchedPath)> +<#function areSamePath path searchedPath> + <#return path?size == searchedPath?size && isSubpath(path, searchedPath)> <#macro addToXKeycloakifyMessagesIfMessageKey str> @@ -589,15 +600,17 @@ function decodeHtmlEntities(htmlStr){ <#if resolvedMsg==key> <#return> - <#assign xKeycloakifyMessages = xKeycloakifyMessages + { "${key}": resolvedMsg }> + <#local messages=xKeycloakify.messages> + <#local messages = messages + { key: resolvedMsg }> + <#assign xKeycloakify = xKeycloakify + { "messages": messages }> <#function removeBrackets str> - <#if str?starts_with("${") && str?ends_with("}")> - <#return str[2..(str?length-2)]> - <#else> - <#return str> - + <#if str?starts_with("${") && str?ends_with("}")> + <#return str[2..(str?length-2)]> + <#else> + <#return str> + <#macro addNonAutomaticallyGatherableMessagesToXKeycloakifyMessages> @@ -625,7 +638,7 @@ function decodeHtmlEntities(htmlStr){ - <#if pageId == "terms.ftl" || termsAcceptanceRequired?? && termsAcceptanceRequired> + <#if xKeycloakify.pageId == "terms.ftl" || termsAcceptanceRequired?? && termsAcceptanceRequired> <@addToXKeycloakifyMessagesIfMessageKey str="termsText" /> <#if requiredActions?? && requiredActions?is_enumerable> @@ -637,5 +650,3 @@ function decodeHtmlEntities(htmlStr){ - - diff --git a/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts b/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts index ff698d2c..057c7878 100644 --- a/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts +++ b/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts @@ -140,8 +140,7 @@ export async function generateResourcesForMainTheme(params: { const { fixedCssCode } = replaceImportsInCssCode({ cssCode: sourceCode.toString("utf8"), cssFileRelativeDirPath: pathDirname(fileRelativePath), - buildContext, - isAccountV3 + buildContext }); return { @@ -176,8 +175,7 @@ export async function generateResourcesForMainTheme(params: { fieldNames: readFieldNameUsage({ themeSrcDirPath: buildContext.themeSrcDirPath, themeType - }), - isAccountV3 + }) }); [ diff --git a/src/bin/keycloakify/generateResources/generateResourcesForThemeVariant.ts b/src/bin/keycloakify/generateResources/generateResourcesForThemeVariant.ts index 0aab4fe7..1a8c8666 100644 --- a/src/bin/keycloakify/generateResources/generateResourcesForThemeVariant.ts +++ b/src/bin/keycloakify/generateResources/generateResourcesForThemeVariant.ts @@ -31,8 +31,8 @@ export function generateResourcesForThemeVariant(params: { Buffer.from(sourceCode) .toString("utf-8") .replace( - `kcContext.themeName = "${themeName}";`, - `kcContext.themeName = "${themeVariantName}";` + `"themeName": "${themeName}"`, + `"themeName": "${themeVariantName}"` ), "utf8" ); diff --git a/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts b/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts index 7794c36b..3d753b29 100644 --- a/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +++ b/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts @@ -12,12 +12,11 @@ assert(); export function replaceImportsInCssCode(params: { cssCode: string; cssFileRelativeDirPath: string | undefined; - isAccountV3: boolean; buildContext: BuildContextLike; }): { fixedCssCode: string; } { - const { cssCode, cssFileRelativeDirPath, buildContext, isAccountV3 } = params; + const { cssCode, cssFileRelativeDirPath, buildContext } = params; const fixedCssCode = cssCode.replace( /url\(["']?(\/[^/][^)"']+)["']?\)/g, @@ -38,7 +37,7 @@ export function replaceImportsInCssCode(params: { break inline_style_in_html; } - return `url(\${${!isAccountV3 ? "url.resourcesPath" : "resourceUrl"}}/${basenameOfTheKeycloakifyResourcesDir}${assetFileAbsoluteUrlPathname})`; + return `url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}${assetFileAbsoluteUrlPathname})`; } const assetFileRelativeUrlPathname = posix.relative( diff --git a/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts b/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts index e71b677e..4cb64370 100644 --- a/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +++ b/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts @@ -31,13 +31,13 @@ export function replaceImportsInJsCode_vite(params: { let fixedJsCode = jsCode; - replace_base_javacript_import: { + replace_base_js_import: { if (buildContext.urlPathname === undefined) { - break replace_base_javacript_import; + break replace_base_js_import; } // Optimization if (!jsCode.includes(buildContext.urlPathname)) { - break replace_base_javacript_import; + break replace_base_js_import; } // Replace `Hv=function(e){return"/abcde12345/"+e}` by `Hv=function(e){return"/"+e}` @@ -85,13 +85,13 @@ export function replaceImportsInJsCode_vite(params: { fixedJsCode = replaceAll( fixedJsCode, `"${relativePathOfAssetFile}"`, - `(window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/${relativePathOfAssetFile}")` + `(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/${relativePathOfAssetFile}")` ); fixedJsCode = replaceAll( fixedJsCode, `"${buildContext.urlPathname ?? "/"}${relativePathOfAssetFile}"`, - `(window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${relativePathOfAssetFile}")` + `(window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${relativePathOfAssetFile}")` ); }); } diff --git a/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts b/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts index 31848ed9..a5e53295 100644 --- a/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +++ b/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts @@ -83,7 +83,7 @@ export function replaceImportsInJsCode_webpack(params: { var pd = Object.getOwnPropertyDescriptor(${n}, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(${n}, "p", { - get: function() { return window.kcContext.url.resourcesPath; }, + get: function() { return window.kcContext["x-keycloakify"].resourcesPath; }, set: function() {} }); } @@ -104,7 +104,7 @@ export function replaceImportsInJsCode_webpack(params: { `[a-zA-Z]+\\.[a-zA-Z]+\\+"${staticDir.replace(/\//g, "\\/")}`, "g" ), - `window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${staticDir}` + `window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/${staticDir}` ); return { fixedJsCode }; diff --git a/src/vite-plugin/vite-plugin.ts b/src/vite-plugin/vite-plugin.ts index df14b01f..a41010ae 100644 --- a/src/vite-plugin/vite-plugin.ts +++ b/src/vite-plugin/vite-plugin.ts @@ -172,7 +172,7 @@ export function keycloakify(params?: Params) { `(`, `(window.kcContext === undefined || import.meta.env.MODE === "development")?`, `"${urlPathname ?? "/"}":`, - `(window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/")`, + `(window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/")`, `)` ].join("") ); diff --git a/test/bin/replacers.spec.ts b/test/bin/replacers.spec.ts index 87a8bffc..5cfb3f83 100644 --- a/test/bin/replacers.spec.ts +++ b/test/bin/replacers.spec.ts @@ -87,13 +87,13 @@ describe("js replacer - vite", () => { }); const fixedJsCodeExpected = ` - S=(window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{ + S=(window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{ function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { __vite__mapDeps.viteFileDeps = [ - (window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/Login-dJpPRzM4.js"), - (window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/index-XwzrZ5Gu.js") + (window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/Login-dJpPRzM4.js"), + (window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/index-XwzrZ5Gu.js") ] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) @@ -146,13 +146,13 @@ describe("js replacer - vite", () => { }); const fixedJsCodeExpected = ` - S=(window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/foo/bar/keycloakify-logo-mqjydaoZ.png"),H=(()=>{ + S=(window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/foo/bar/keycloakify-logo-mqjydaoZ.png"),H=(()=>{ function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { __vite__mapDeps.viteFileDeps = [ - (window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/foo/bar/Login-dJpPRzM4.js"), - (window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/foo/bar/index-XwzrZ5Gu.js") + (window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/foo/bar/Login-dJpPRzM4.js"), + (window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/foo/bar/index-XwzrZ5Gu.js") ] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) @@ -205,13 +205,13 @@ describe("js replacer - vite", () => { }); const fixedJsCodeExpected = ` - S=(window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{ + S=(window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/assets/keycloakify-logo-mqjydaoZ.png"),H=(()=>{ function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { __vite__mapDeps.viteFileDeps = [ - (window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/Login-dJpPRzM4.js"), - (window.kcContext.url.resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/index-XwzrZ5Gu.js") + (window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/Login-dJpPRzM4.js"), + (window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${basenameOfTheKeycloakifyResourcesDir}/assets/index-XwzrZ5Gu.js") ] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) @@ -267,13 +267,13 @@ describe("js replacer - webpack", () => { const fixedJsCodeExpected = ` function f() { - return window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/static/js/" + ({}[e] || e) + "." + { + return window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/static/js/" + ({}[e] || e) + "." + { 3: "0664cdc0" }[e] + ".chunk.js" } function sameAsF() { - return window.kcContext.url.resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/static/js/" + ({}[e] || e) + "." + { + return window.kcContext["x-keycloakify"].resourcesPath + "/${basenameOfTheKeycloakifyResourcesDir}/static/js/" + ({}[e] || e) + "." + { 3: "0664cdc0" }[e] + ".chunk.js" } @@ -282,7 +282,7 @@ describe("js replacer - webpack", () => { var pd = Object.getOwnPropertyDescriptor(__webpack_require__, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(__webpack_require__, "p", { - get: function() { return window.kcContext.url.resourcesPath; }, + get: function() { return window.kcContext["x-keycloakify"].resourcesPath; }, set: function() {} }); } @@ -299,7 +299,7 @@ describe("js replacer - webpack", () => { var pd = Object.getOwnPropertyDescriptor(t, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(t, "p", { - get: function() { return window.kcContext.url.resourcesPath; }, + get: function() { return window.kcContext["x-keycloakify"].resourcesPath; }, set: function() {} }); } @@ -315,7 +315,7 @@ describe("js replacer - webpack", () => { var pd = Object.getOwnPropertyDescriptor(n, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(n, "p", { - get: function() { return window.kcContext.url.resourcesPath; }, + get: function() { return window.kcContext["x-keycloakify"].resourcesPath; }, set: function() {} }); } @@ -326,7 +326,7 @@ describe("js replacer - webpack", () => { var pd = Object.getOwnPropertyDescriptor(t, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(t, "p", { - get: function() { return window.kcContext.url.resourcesPath; }, + get: function() { return window.kcContext["x-keycloakify"].resourcesPath; }, set: function() {} }); } @@ -396,7 +396,6 @@ describe("css replacer", () => { } `, cssFileRelativeDirPath: "assets/", - isAccountV3: false, buildContext: { urlPathname: undefined } @@ -435,7 +434,6 @@ describe("css replacer", () => { } `, cssFileRelativeDirPath: "assets/", - isAccountV3: false, buildContext: { urlPathname: "/a/b/" } @@ -474,7 +472,6 @@ describe("css replacer", () => { } `, cssFileRelativeDirPath: undefined, - isAccountV3: false, buildContext: { urlPathname: "/a/b/" } @@ -482,15 +479,15 @@ describe("css replacer", () => { const fixedCssCodeExpected = ` .my-div { - background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/background.png) no-repeat center center; + background: url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/background.png) no-repeat center center; } .my-div2 { - background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/background.png) repeat center center; + background: url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/background.png) repeat center center; } .my-div3 { - background-image: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/media/something.svg); + background-image: url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/media/something.svg); } `; @@ -513,7 +510,6 @@ describe("css replacer", () => { } `, cssFileRelativeDirPath: undefined, - isAccountV3: false, buildContext: { urlPathname: undefined } @@ -521,15 +517,15 @@ describe("css replacer", () => { const fixedCssCodeExpected = ` .my-div { - background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/background.png) no-repeat center center; + background: url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/background.png) no-repeat center center; } .my-div2 { - background: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/background.png) repeat center center; + background: url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/background.png) repeat center center; } .my-div3 { - background-image: url(\${url.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/media/something.svg); + background-image: url(\${xKeycloakify.resourcesPath}/${basenameOfTheKeycloakifyResourcesDir}/assets/media/something.svg); } `;