keycloakify 10.1.0-rc.0 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/PUBLIC_URL.js +2 -2
  2. package/PUBLIC_URL.js.map +1 -1
  3. package/account/KcContext/kcContextMocks.js +3 -3
  4. package/account/KcContext/kcContextMocks.js.map +1 -1
  5. package/bin/193.index.js +198 -62
  6. package/bin/{365.index.js → 20.index.js} +302 -263
  7. package/bin/31.index.js +15 -23
  8. package/bin/{430.index.js → 33.index.js} +579 -4
  9. package/bin/{678.index.js → 36.index.js} +2 -577
  10. package/bin/{440.index.js → 499.index.js} +259 -181
  11. package/bin/526.index.js +3 -784
  12. package/bin/599.index.js +4 -1
  13. package/bin/780.index.js +1 -1
  14. package/bin/{525.index.js → 903.index.js} +4840 -97
  15. package/bin/932.index.js +115 -886
  16. package/bin/main.js +4 -4
  17. package/bin/shared/buildContext.d.ts +0 -2
  18. package/bin/shared/buildContext.js.map +1 -1
  19. package/bin/shared/constants.d.ts +5 -6
  20. package/bin/shared/constants.js +5 -6
  21. package/bin/shared/constants.js.map +1 -1
  22. package/bin/shared/copyKeycloakResourcesToPublic.d.ts +2 -4
  23. package/bin/shared/copyKeycloakResourcesToPublic.js.map +1 -1
  24. package/login/KcContext/KcContext.d.ts +9 -18
  25. package/login/KcContext/KcContext.js.map +1 -1
  26. package/login/KcContext/kcContextMocks.js +6 -10
  27. package/login/KcContext/kcContextMocks.js.map +1 -1
  28. package/login/Template.js +4 -59
  29. package/login/Template.js.map +1 -1
  30. package/login/Template.useStylesAndScripts.d.ts +17 -0
  31. package/login/Template.useStylesAndScripts.js +69 -0
  32. package/login/Template.useStylesAndScripts.js.map +1 -0
  33. package/login/pages/Login.js +1 -1
  34. package/login/pages/Login.js.map +1 -1
  35. package/login/pages/LoginIdpLinkConfirmOverride.js +0 -1
  36. package/login/pages/LoginIdpLinkConfirmOverride.js.map +1 -1
  37. package/login/pages/LoginPasskeysConditionalAuthenticate.js +6 -49
  38. package/login/pages/LoginPasskeysConditionalAuthenticate.js.map +1 -1
  39. package/login/pages/LoginPasskeysConditionalAuthenticate.useScript.d.ts +20 -0
  40. package/login/pages/LoginPasskeysConditionalAuthenticate.useScript.js +49 -0
  41. package/login/pages/LoginPasskeysConditionalAuthenticate.useScript.js.map +1 -0
  42. package/login/pages/LoginRecoveryAuthnCodeConfig.js +4 -126
  43. package/login/pages/LoginRecoveryAuthnCodeConfig.js.map +1 -1
  44. package/login/pages/LoginRecoveryAuthnCodeConfig.useScript.d.ts +9 -0
  45. package/login/pages/LoginRecoveryAuthnCodeConfig.useScript.js +133 -0
  46. package/login/pages/LoginRecoveryAuthnCodeConfig.useScript.js.map +1 -0
  47. package/login/pages/LoginUsername.js +1 -1
  48. package/login/pages/LoginUsername.js.map +1 -1
  49. package/login/pages/Register.js +6 -3
  50. package/login/pages/Register.js.map +1 -1
  51. package/login/pages/WebauthnAuthenticate.js +13 -116
  52. package/login/pages/WebauthnAuthenticate.js.map +1 -1
  53. package/login/pages/WebauthnAuthenticate.useScript.d.ts +21 -0
  54. package/login/pages/WebauthnAuthenticate.useScript.js +41 -0
  55. package/login/pages/WebauthnAuthenticate.useScript.js.map +1 -0
  56. package/login/pages/WebauthnRegister.js +8 -178
  57. package/login/pages/WebauthnRegister.js.map +1 -1
  58. package/login/pages/WebauthnRegister.useScript.d.ts +27 -0
  59. package/login/pages/WebauthnRegister.useScript.js +49 -0
  60. package/login/pages/WebauthnRegister.useScript.js.map +1 -0
  61. package/package.json +125 -15
  62. package/res/account-v1/account.ftl +70 -0
  63. package/res/account-v1/applications.ftl +76 -0
  64. package/res/account-v1/federatedIdentity.ftl +42 -0
  65. package/res/account-v1/log.ftl +35 -0
  66. package/res/account-v1/messages/messages_ar.properties +406 -0
  67. package/res/account-v1/messages/messages_ca.properties +147 -0
  68. package/res/account-v1/messages/messages_cs.properties +171 -0
  69. package/res/account-v1/messages/messages_da.properties +339 -0
  70. package/res/account-v1/messages/messages_de.properties +353 -0
  71. package/res/account-v1/messages/messages_en.properties +404 -0
  72. package/res/account-v1/messages/messages_es.properties +147 -0
  73. package/res/account-v1/messages/messages_fi.properties +400 -0
  74. package/res/account-v1/messages/messages_fr.properties +180 -0
  75. package/res/account-v1/messages/messages_hu.properties +334 -0
  76. package/res/account-v1/messages/messages_it.properties +336 -0
  77. package/res/account-v1/messages/messages_ja.properties +335 -0
  78. package/res/account-v1/messages/messages_lt.properties +154 -0
  79. package/res/account-v1/messages/messages_lv.properties +197 -0
  80. package/res/account-v1/messages/messages_nl.properties +371 -0
  81. package/res/account-v1/messages/messages_no.properties +152 -0
  82. package/res/account-v1/messages/messages_pl.properties +248 -0
  83. package/res/account-v1/messages/messages_pt_BR.properties +349 -0
  84. package/res/account-v1/messages/messages_ru.properties +235 -0
  85. package/res/account-v1/messages/messages_sk.properties +196 -0
  86. package/res/account-v1/messages/messages_sv.properties +150 -0
  87. package/res/account-v1/messages/messages_tr.properties +315 -0
  88. package/res/account-v1/messages/messages_zh_CN.properties +153 -0
  89. package/res/account-v1/password.ftl +59 -0
  90. package/res/account-v1/resource-detail.ftl +277 -0
  91. package/res/account-v1/resources/css/account.css +277 -0
  92. package/res/account-v1/resources/img/icon-sidebar-active.png +0 -0
  93. package/res/account-v1/resources/img/keycloak-logo.png +0 -0
  94. package/res/account-v1/resources/img/logo.png +0 -0
  95. package/res/account-v1/resources/resources-common/img/favicon.ico +0 -0
  96. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css +5 -0
  97. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/css/patternfly.min.css +8 -0
  98. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2 +0 -0
  99. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2 +0 -0
  100. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2 +0 -0
  101. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2 +0 -0
  102. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf +0 -0
  103. package/res/account-v1/resources/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.woff +0 -0
  104. package/res/account-v1/resources.ftl +403 -0
  105. package/res/account-v1/sessions.ftl +44 -0
  106. package/res/account-v1/template.ftl +88 -0
  107. package/res/account-v1/theme.properties +14 -0
  108. package/res/account-v1/totp.ftl +141 -0
  109. package/res/public/.keycloakify/account/css/account.css +277 -0
  110. package/res/public/.keycloakify/account/img/icon-sidebar-active.png +0 -0
  111. package/res/public/.keycloakify/account/img/keycloak-logo.png +0 -0
  112. package/res/public/.keycloakify/account/img/logo.png +0 -0
  113. package/res/public/.keycloakify/account/resources-common/img/favicon.ico +0 -0
  114. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css +5 -0
  115. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/css/patternfly.min.css +8 -0
  116. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2 +0 -0
  117. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2 +0 -0
  118. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2 +0 -0
  119. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2 +0 -0
  120. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf +0 -0
  121. package/res/public/.keycloakify/account/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.woff +0 -0
  122. package/res/public/.keycloakify/login/css/login.css +629 -0
  123. package/res/public/.keycloakify/login/img/feedback-error-arrow-down.png +0 -0
  124. package/res/public/.keycloakify/login/img/feedback-error-sign.png +0 -0
  125. package/res/public/.keycloakify/login/img/feedback-success-arrow-down.png +0 -0
  126. package/res/public/.keycloakify/login/img/feedback-success-sign.png +0 -0
  127. package/res/public/.keycloakify/login/img/feedback-warning-arrow-down.png +0 -0
  128. package/res/public/.keycloakify/login/img/feedback-warning-sign.png +0 -0
  129. package/res/public/.keycloakify/login/img/keycloak-bg.png +0 -0
  130. package/res/public/.keycloakify/login/img/keycloak-logo-text.png +0 -0
  131. package/res/public/.keycloakify/login/img/keycloak-logo.png +0 -0
  132. package/res/public/.keycloakify/login/js/authChecker.js +49 -0
  133. package/res/public/.keycloakify/login/js/common.js +48 -0
  134. package/res/public/.keycloakify/login/js/kcMultivalued.js +106 -0
  135. package/res/public/.keycloakify/login/js/kcNumberFormat.js +21 -0
  136. package/res/public/.keycloakify/login/js/kcNumberUnFormat.js +19 -0
  137. package/res/public/.keycloakify/login/js/menu-button-links.js +315 -0
  138. package/{src/bin/shared/downloadKeycloakDefaultTheme/extra-assets → res/public/.keycloakify/login/js}/passkeysConditionalAuth.js +1 -1
  139. package/res/public/.keycloakify/login/js/passwordVisibility.js +15 -0
  140. package/res/public/.keycloakify/login/js/userProfile.js +71 -0
  141. package/res/public/.keycloakify/login/js/webauthnRegister.js +140 -0
  142. package/res/public/.keycloakify/login/resources-common/img/favicon.ico +0 -0
  143. package/res/public/.keycloakify/login/resources-common/lib/pficon/pficon.css +22 -0
  144. package/res/public/.keycloakify/login/resources-common/lib/pficon/pficon.woff2 +0 -0
  145. package/res/public/.keycloakify/login/resources-common/node_modules/@patternfly/patternfly/patternfly.min.css +2 -0
  146. package/res/public/.keycloakify/login/resources-common/node_modules/jquery/dist/jquery.min.js +2 -0
  147. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css +5 -0
  148. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/css/patternfly.min.css +8 -0
  149. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.ttf +0 -0
  150. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff +0 -0
  151. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Bold-webfont.woff2 +0 -0
  152. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Light-webfont.woff2 +0 -0
  153. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Regular-webfont.woff2 +0 -0
  154. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/OpenSans-Semibold-webfont.woff2 +0 -0
  155. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.ttf +0 -0
  156. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/PatternFlyIcons-webfont.woff +0 -0
  157. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/fonts/fontawesome-webfont.woff2 +0 -0
  158. package/res/public/.keycloakify/login/resources-common/node_modules/patternfly/dist/img/bg-login.jpg +0 -0
  159. package/res/public/.keycloakify/login/resources-common/node_modules/rfc4648/lib/rfc4648.js +178 -0
  160. package/src/PUBLIC_URL.ts +5 -3
  161. package/src/account/KcContext/kcContextMocks.ts +3 -3
  162. package/src/bin/copy-keycloak-resources-to-public.ts +1 -1
  163. package/src/bin/initialize-account-theme/initializeAccountTheme_singlePage.ts +4 -1
  164. package/src/bin/initialize-email-theme.ts +28 -8
  165. package/src/bin/keycloakify/buildJars/buildJar.ts +3 -7
  166. package/src/bin/keycloakify/generateFtl/generateFtl.ts +3 -7
  167. package/src/bin/keycloakify/generateResources/generateResourcesForMainTheme.ts +65 -90
  168. package/src/bin/keycloakify/keycloakify.ts +38 -21
  169. package/src/bin/keycloakify/replacers/replaceImportsInCssCode.ts +2 -2
  170. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/vite.ts +3 -3
  171. package/src/bin/keycloakify/replacers/replaceImportsInJsCode/webpack.ts +3 -3
  172. package/src/bin/shared/buildContext.ts +1 -8
  173. package/src/bin/shared/constants.ts +5 -7
  174. package/src/bin/shared/copyKeycloakResourcesToPublic.ts +30 -40
  175. package/src/bin/start-keycloak/start-keycloak.ts +3 -7
  176. package/src/login/KcContext/KcContext.ts +9 -18
  177. package/src/login/KcContext/kcContextMocks.ts +5 -13
  178. package/src/login/Template.tsx +4 -67
  179. package/src/login/Template.useStylesAndScripts.ts +94 -0
  180. package/src/login/pages/Login.tsx +1 -1
  181. package/src/login/pages/LoginIdpLinkConfirmOverride.tsx +0 -1
  182. package/src/login/pages/LoginPasskeysConditionalAuthenticate.tsx +6 -81
  183. package/src/login/pages/LoginPasskeysConditionalAuthenticate.useScript.tsx +72 -0
  184. package/src/login/pages/LoginRecoveryAuthnCodeConfig.tsx +4 -126
  185. package/src/login/pages/LoginRecoveryAuthnCodeConfig.useScript.tsx +142 -0
  186. package/src/login/pages/LoginUsername.tsx +1 -1
  187. package/src/login/pages/Register.tsx +35 -13
  188. package/src/login/pages/WebauthnAuthenticate.tsx +20 -133
  189. package/src/login/pages/WebauthnAuthenticate.useScript.tsx +64 -0
  190. package/src/login/pages/WebauthnRegister.tsx +8 -195
  191. package/src/login/pages/WebauthnRegister.useScript.tsx +93 -0
  192. package/src/tools/useInsertScriptTags.ts +14 -4
  193. package/src/vite-plugin/vite-plugin.ts +11 -15
  194. package/tools/useInsertScriptTags.d.ts +2 -2
  195. package/tools/useInsertScriptTags.js +8 -2
  196. package/tools/useInsertScriptTags.js.map +1 -1
  197. package/vite-plugin/index.js +3357 -47132
  198. package/bin/697.index.js +0 -4749
  199. package/bin/shared/downloadKeycloakStaticResources.d.ts +0 -9
  200. package/bin/shared/downloadKeycloakStaticResources.js.map +0 -1
  201. package/src/bin/keycloakify/generateResources/bringInAccountV1.ts +0 -89
  202. package/src/bin/shared/downloadKeycloakDefaultTheme/downloadKeycloakDefaultTheme.ts +0 -337
  203. package/src/bin/shared/downloadKeycloakDefaultTheme/index.ts +0 -1
  204. package/src/bin/shared/downloadKeycloakStaticResources.ts +0 -53
  205. /package/{src/bin/shared/downloadKeycloakDefaultTheme/extra-assets → res/public/.keycloakify/login/js}/webauthnAuthenticate.js +0 -0
@@ -12,6 +12,10 @@ import * as os from "os";
12
12
  import { rmSync } from "../tools/fs.rmSync";
13
13
 
14
14
  export async function command(params: { cliCommandOptions: CliCommandOptions }) {
15
+ const { cliCommandOptions } = params;
16
+
17
+ const buildContext = getBuildContext({ cliCommandOptions });
18
+
15
19
  exit_if_maven_not_installed: {
16
20
  let commandOutput: Buffer | undefined = undefined;
17
21
 
@@ -25,31 +29,44 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
25
29
  break exit_if_maven_not_installed;
26
30
  }
27
31
 
28
- const installationCommand = (() => {
29
- switch (os.platform()) {
30
- case "darwin":
31
- return "brew install mvn";
32
- case "win32":
33
- return "choco install mvn";
34
- case "linux":
35
- default:
36
- return "sudo apt-get install mvn";
37
- }
38
- })();
39
-
40
- console.log(
41
- `${chalk.red("Apache Maven required.")} Install it with \`${chalk.bold(
42
- installationCommand
43
- )}\` (for example)`
44
- );
32
+ if (
33
+ fs
34
+ .readFileSync(buildContext.packageJsonFilePath)
35
+ .toString("utf8")
36
+ .includes(`"mvn"`)
37
+ ) {
38
+ console.log(
39
+ chalk.red(
40
+ [
41
+ "Please remove the 'mvn' package from your package.json'dependencies list,",
42
+ "reinstall your dependencies and try again.",
43
+ "We need the Apache Maven CLI, not this: https://www.npmjs.com/package/mvn"
44
+ ].join(" ")
45
+ )
46
+ );
47
+ } else {
48
+ const installationCommand = (() => {
49
+ switch (os.platform()) {
50
+ case "darwin":
51
+ return "brew install mvn";
52
+ case "win32":
53
+ return "choco install mvn";
54
+ case "linux":
55
+ default:
56
+ return "sudo apt-get install mvn";
57
+ }
58
+ })();
59
+
60
+ console.log(
61
+ `${chalk.red("Apache Maven required.")} Install it with \`${chalk.bold(
62
+ installationCommand
63
+ )}\` (for example)`
64
+ );
65
+ }
45
66
 
46
67
  process.exit(1);
47
68
  }
48
69
 
49
- const { cliCommandOptions } = params;
50
-
51
- const buildContext = getBuildContext({ cliCommandOptions });
52
-
53
70
  console.log(
54
71
  [
55
72
  chalk.cyan(`keycloakify v${readThisNpmPackageVersion()}`),
@@ -1,5 +1,5 @@
1
1
  import type { BuildContext } from "../../shared/buildContext";
2
- import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "../../shared/constants";
2
+ import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../shared/constants";
3
3
  import { assert } from "tsafe/assert";
4
4
  import { posix } from "path";
5
5
 
@@ -50,7 +50,7 @@ export function replaceImportsInCssCode(params: {
50
50
  break inline_style_in_html;
51
51
  }
52
52
 
53
- return `url("\${xKeycloakify.resourcesPath}/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}${assetFileAbsoluteUrlPathname}")`;
53
+ return `url("\${xKeycloakify.resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}${assetFileAbsoluteUrlPathname}")`;
54
54
  }
55
55
 
56
56
  const assetFileRelativeUrlPathname = posix.relative(
@@ -1,4 +1,4 @@
1
- import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "../../../shared/constants";
1
+ import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../../shared/constants";
2
2
  import { assert } from "tsafe/assert";
3
3
  import type { BuildContext } from "../../../shared/buildContext";
4
4
  import * as nodePath from "path";
@@ -85,13 +85,13 @@ export function replaceImportsInJsCode_vite(params: {
85
85
  fixedJsCode = replaceAll(
86
86
  fixedJsCode,
87
87
  `"${relativePathOfAssetFile}"`,
88
- `(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${relativePathOfAssetFile}")`
88
+ `(window.kcContext["x-keycloakify"].resourcesPath.substring(1) + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${relativePathOfAssetFile}")`
89
89
  );
90
90
 
91
91
  fixedJsCode = replaceAll(
92
92
  fixedJsCode,
93
93
  `"${buildContext.urlPathname ?? "/"}${relativePathOfAssetFile}"`,
94
- `(window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${relativePathOfAssetFile}")`
94
+ `(window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${relativePathOfAssetFile}")`
95
95
  );
96
96
  });
97
97
  }
@@ -1,4 +1,4 @@
1
- import { BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR } from "../../../shared/constants";
1
+ import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../../../shared/constants";
2
2
  import { assert } from "tsafe/assert";
3
3
  import type { BuildContext } from "../../../shared/buildContext";
4
4
  import * as nodePath from "path";
@@ -90,7 +90,7 @@ export function replaceImportsInJsCode_webpack(params: {
90
90
  return "${u}";
91
91
  })()] = ${
92
92
  isArrowFunction ? `${e} =>` : `function(${e}) { return `
93
- } "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${staticDir}${language}/"`
93
+ } "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${staticDir}${language}/"`
94
94
  .replace(/\s+/g, " ")
95
95
  .trim();
96
96
  }
@@ -104,7 +104,7 @@ export function replaceImportsInJsCode_webpack(params: {
104
104
  `[a-zA-Z]+\\.[a-zA-Z]+\\+"${staticDir.replace(/\//g, "\\/")}`,
105
105
  "g"
106
106
  ),
107
- `window.kcContext["x-keycloakify"].resourcesPath + "/${BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR}/${staticDir}`
107
+ `window.kcContext["x-keycloakify"].resourcesPath + "/${WELL_KNOWN_DIRECTORY_BASE_NAME.DIST}/${staticDir}`
108
108
  );
109
109
 
110
110
  return { fixedJsCode };
@@ -14,8 +14,7 @@ import { assert, type Equals } from "tsafe/assert";
14
14
  import * as child_process from "child_process";
15
15
  import {
16
16
  VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES,
17
- BUILD_FOR_KEYCLOAK_MAJOR_VERSION_ENV_NAME,
18
- LOGIN_THEME_RESOURCES_FROM_KEYCLOAK_VERSION_DEFAULT
17
+ BUILD_FOR_KEYCLOAK_MAJOR_VERSION_ENV_NAME
19
18
  } from "./constants";
20
19
  import type { KeycloakVersionRange } from "./KeycloakVersionRange";
21
20
  import { exclude } from "tsafe";
@@ -33,7 +32,6 @@ export type BuildContext = {
33
32
  extraThemeProperties: string[] | undefined;
34
33
  groupId: string;
35
34
  artifactId: string;
36
- loginThemeResourcesFromKeycloakVersion: string;
37
35
  projectDirPath: string;
38
36
  projectBuildDirPath: string;
39
37
  /** Directory that keycloakify outputs to. Defaults to {cwd}/build_keycloak */
@@ -85,7 +83,6 @@ export type BuildOptions = {
85
83
  extraThemeProperties?: string[];
86
84
  artifactId?: string;
87
85
  groupId?: string;
88
- loginThemeResourcesFromKeycloakVersion?: string;
89
86
  keycloakifyBuildDirPath?: string;
90
87
  kcContextExclusionsFtl?: string;
91
88
  startKeycloakOptions?: {
@@ -357,7 +354,6 @@ export function getBuildContext(params: {
357
354
  extraThemeProperties: z.array(z.string()).optional(),
358
355
  artifactId: z.string().optional(),
359
356
  groupId: z.string().optional(),
360
- loginThemeResourcesFromKeycloakVersion: z.string().optional(),
361
357
  keycloakifyBuildDirPath: z.string().optional(),
362
358
  kcContextExclusionsFtl: z.string().optional(),
363
359
  startKeycloakOptions: zStartKeycloakOptions.optional()
@@ -545,9 +541,6 @@ export function getBuildContext(params: {
545
541
  process.env.KEYCLOAKIFY_ARTIFACT_ID ??
546
542
  buildOptions.artifactId ??
547
543
  `${themeNames[0]}-keycloak-theme`,
548
- loginThemeResourcesFromKeycloakVersion:
549
- buildOptions.loginThemeResourcesFromKeycloakVersion ??
550
- LOGIN_THEME_RESOURCES_FROM_KEYCLOAK_VERSION_DEFAULT,
551
544
  projectDirPath,
552
545
  projectBuildDirPath,
553
546
  keycloakifyBuildDirPath: (() => {
@@ -1,10 +1,10 @@
1
- export const KEYCLOAK_RESOURCES = "keycloak-resources";
2
- export const RESOURCES_COMMON = "resources-common";
3
- export const LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 = "21.1.2";
4
- export const BASENAME_OF_KEYCLOAKIFY_RESOURCES_DIR = "dist";
1
+ export const WELL_KNOWN_DIRECTORY_BASE_NAME = {
2
+ DOT_KEYCLOAKIFY: ".keycloakify",
3
+ RESOURCES_COMMON: "resources-common",
4
+ DIST: "dist"
5
+ } as const;
5
6
 
6
7
  export const THEME_TYPES = ["login", "account"] as const;
7
- export const ACCOUNT_V1_THEME_NAME = "account-v1";
8
8
 
9
9
  export type ThemeType = (typeof THEME_TYPES)[number];
10
10
 
@@ -71,5 +71,3 @@ export type AccountThemePageId = (typeof ACCOUNT_THEME_PAGE_IDS)[number];
71
71
  export const CONTAINER_NAME = "keycloak-keycloakify";
72
72
 
73
73
  export const FALLBACK_LANGUAGE_TAG = "en";
74
-
75
- export const LOGIN_THEME_RESOURCES_FROM_KEYCLOAK_VERSION_DEFAULT = "24.0.4";
@@ -1,44 +1,34 @@
1
- import {
2
- downloadKeycloakStaticResources,
3
- type BuildContextLike as BuildContextLike_downloadKeycloakStaticResources
4
- } from "./downloadKeycloakStaticResources";
5
- import { join as pathJoin, relative as pathRelative } from "path";
6
- import {
7
- THEME_TYPES,
8
- KEYCLOAK_RESOURCES,
9
- LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1
10
- } from "../shared/constants";
1
+ import { join as pathJoin, dirname as pathDirname } from "path";
2
+ import { WELL_KNOWN_DIRECTORY_BASE_NAME } from "../shared/constants";
11
3
  import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
12
4
  import { assert } from "tsafe/assert";
13
5
  import * as fs from "fs";
14
6
  import { rmSync } from "../tools/fs.rmSync";
15
7
  import type { BuildContext } from "./buildContext";
8
+ import { transformCodebase } from "../tools/transformCodebase";
9
+ import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
16
10
 
17
- export type BuildContextLike = BuildContextLike_downloadKeycloakStaticResources & {
18
- loginThemeResourcesFromKeycloakVersion: string;
11
+ export type BuildContextLike = {
19
12
  publicDirPath: string;
20
13
  };
21
14
 
22
15
  assert<BuildContext extends BuildContextLike ? true : false>();
23
16
 
24
- export async function copyKeycloakResourcesToPublic(params: {
17
+ export function copyKeycloakResourcesToPublic(params: {
25
18
  buildContext: BuildContextLike;
26
19
  }) {
27
20
  const { buildContext } = params;
28
21
 
29
- const destDirPath = pathJoin(buildContext.publicDirPath, KEYCLOAK_RESOURCES);
22
+ const destDirPath = pathJoin(
23
+ buildContext.publicDirPath,
24
+ WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY
25
+ );
30
26
 
31
27
  const keycloakifyBuildinfoFilePath = pathJoin(destDirPath, "keycloakify.buildinfo");
32
28
 
33
29
  const keycloakifyBuildinfoRaw = JSON.stringify(
34
30
  {
35
- destDirPath,
36
- keycloakifyVersion: readThisNpmPackageVersion(),
37
- buildContext: {
38
- loginThemeResourcesFromKeycloakVersion: readThisNpmPackageVersion(),
39
- cacheDirPath: pathRelative(destDirPath, buildContext.cacheDirPath),
40
- fetchOptions: buildContext.fetchOptions
41
- }
31
+ keycloakifyVersion: readThisNpmPackageVersion()
42
32
  },
43
33
  null,
44
34
  2
@@ -62,35 +52,35 @@ export async function copyKeycloakResourcesToPublic(params: {
62
52
 
63
53
  rmSync(destDirPath, { force: true, recursive: true });
64
54
 
55
+ // NOTE: To remove in a while, remove the legacy keycloak-resources directory
56
+ rmSync(pathJoin(pathDirname(destDirPath), "keycloak-resources"), {
57
+ force: true,
58
+ recursive: true
59
+ });
60
+
65
61
  fs.mkdirSync(destDirPath, { recursive: true });
66
62
 
67
63
  fs.writeFileSync(pathJoin(destDirPath, ".gitignore"), Buffer.from("*", "utf8"));
68
64
 
69
- for (const themeType of THEME_TYPES) {
70
- await downloadKeycloakStaticResources({
71
- keycloakVersion: (() => {
72
- switch (themeType) {
73
- case "login":
74
- return buildContext.loginThemeResourcesFromKeycloakVersion;
75
- case "account":
76
- return LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1;
77
- }
78
- })(),
79
- themeType,
80
- themeDirPath: destDirPath,
81
- buildContext
82
- });
83
- }
65
+ transformCodebase({
66
+ srcDirPath: pathJoin(
67
+ getThisCodebaseRootDirPath(),
68
+ "res",
69
+ "public",
70
+ WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY
71
+ ),
72
+ destDirPath
73
+ });
84
74
 
85
75
  fs.writeFileSync(
86
76
  pathJoin(destDirPath, "README.txt"),
87
77
  Buffer.from(
88
78
  // prettier-ignore
89
79
  [
90
- "This is just a test folder that helps develop",
91
- "the login and register page without having to run a Keycloak container\n",
92
- "This directory will be automatically excluded from the final build."
93
- ].join(" ")
80
+ "This directory is only used in dev mode by Keycloakify",
81
+ "It won't be included in your final build.",
82
+ "Do not modify anything in this directory.",
83
+ ].join("\n")
94
84
  )
95
85
  );
96
86
 
@@ -2,7 +2,7 @@ import { getBuildContext } from "../shared/buildContext";
2
2
  import { exclude } from "tsafe/exclude";
3
3
  import type { CliCommandOptions as CliCommandOptions_common } from "../main";
4
4
  import { promptKeycloakVersion } from "../shared/promptKeycloakVersion";
5
- import { ACCOUNT_V1_THEME_NAME, CONTAINER_NAME } from "../shared/constants";
5
+ import { CONTAINER_NAME } from "../shared/constants";
6
6
  import { SemVer } from "../tools/SemVer";
7
7
  import { assert, type Equals } from "tsafe/assert";
8
8
  import * as fs from "fs";
@@ -409,13 +409,9 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
409
409
  ...[
410
410
  ...buildContext.themeNames,
411
411
  ...(fs.existsSync(
412
- pathJoin(
413
- buildContext.keycloakifyBuildDirPath,
414
- "theme",
415
- ACCOUNT_V1_THEME_NAME
416
- )
412
+ pathJoin(buildContext.keycloakifyBuildDirPath, "theme", "account-v1")
417
413
  )
418
- ? [ACCOUNT_V1_THEME_NAME]
414
+ ? ["account-v1"]
419
415
  : [])
420
416
  ]
421
417
  .map(themeName => ({
@@ -149,11 +149,6 @@ export declare namespace KcContext {
149
149
 
150
150
  getFirstError: (...fieldNames: string[]) => string;
151
151
  };
152
- authenticationSession?: {
153
- authSessionId: string;
154
- tabId: string;
155
- ssoLoginInOtherTabsUrl: string;
156
- };
157
152
  properties: {};
158
153
  "x-keycloakify": {
159
154
  messages: Record<string, string>;
@@ -193,7 +188,7 @@ export declare namespace KcContext {
193
188
  password?: string;
194
189
  };
195
190
  usernameHidden?: boolean;
196
- social: {
191
+ social?: {
197
192
  displayInfo: boolean;
198
193
  providers?: {
199
194
  loginUrl: string;
@@ -213,9 +208,12 @@ export declare namespace KcContext {
213
208
  registrationAction: string;
214
209
  };
215
210
  passwordRequired: boolean;
216
- recaptchaRequired: boolean;
211
+ recaptchaRequired?: boolean;
212
+ recaptchaVisible?: boolean;
217
213
  recaptchaSiteKey?: string;
214
+ recaptchaAction?: string;
218
215
  termsAcceptanceRequired?: boolean;
216
+ messageHeader?: string;
219
217
  };
220
218
 
221
219
  export type Info = Common & {
@@ -330,7 +328,7 @@ export declare namespace KcContext {
330
328
  rememberMe?: string;
331
329
  };
332
330
  usernameHidden?: boolean;
333
- social: Login["social"];
331
+ social?: Login["social"];
334
332
  };
335
333
 
336
334
  export type LoginPassword = Common & {
@@ -348,9 +346,6 @@ export declare namespace KcContext {
348
346
  showTryAnotherWayLink?: boolean;
349
347
  attemptedUsername?: string;
350
348
  };
351
- social: {
352
- displayInfo: boolean;
353
- };
354
349
  };
355
350
 
356
351
  export type WebauthnAuthenticate = Common & {
@@ -362,13 +357,9 @@ export declare namespace KcContext {
362
357
  // I hate this:
363
358
  userVerification: UserVerificationRequirement | "not specified";
364
359
  rpId: string;
365
- createTimeout: string;
360
+ createTimeout: string | number;
366
361
  isUserIdentified: "true" | "false";
367
362
  shouldDisplayAuthenticators: boolean;
368
- social: {
369
- displayInfo: boolean;
370
- };
371
- login: {};
372
363
  realm: {
373
364
  password: boolean;
374
365
  registrationAllowed: boolean;
@@ -403,7 +394,7 @@ export declare namespace KcContext {
403
394
  authenticatorAttachment: string;
404
395
  requireResidentKey: string;
405
396
  userVerificationRequirement: string;
406
- createTimeout: number;
397
+ createTimeout: number | string;
407
398
  excludeCredentialIds: string;
408
399
  isSetRetry?: boolean;
409
400
  isAppInitiatedAction?: boolean;
@@ -589,7 +580,7 @@ export declare namespace KcContext {
589
580
  url: {
590
581
  registrationUrl: string;
591
582
  };
592
- registrationDisabled: boolean;
583
+ registrationDisabled?: boolean;
593
584
  isUserIdentified: boolean | "true" | "false";
594
585
  challenge: string;
595
586
  userVerification: string;
@@ -1,8 +1,7 @@
1
1
  import "keycloakify/tools/Object.fromEntries";
2
2
  import type { KcContext, Attribute } from "./KcContext";
3
3
  import {
4
- RESOURCES_COMMON,
5
- KEYCLOAK_RESOURCES,
4
+ WELL_KNOWN_DIRECTORY_BASE_NAME,
6
5
  type LoginThemePageId
7
6
  } from "keycloakify/bin/shared/constants";
8
7
  import { id } from "tsafe/id";
@@ -76,7 +75,7 @@ const attributesByName = Object.fromEntries(
76
75
  ]).map(attribute => [attribute.name, attribute])
77
76
  );
78
77
 
79
- const resourcesPath = `${BASE_URL}${KEYCLOAK_RESOURCES}/login/resources`;
78
+ const resourcesPath = `${BASE_URL}${WELL_KNOWN_DIRECTORY_BASE_NAME.DOT_KEYCLOAKIFY}/login`;
80
79
 
81
80
  export const kcContextCommonMock: KcContext.Common = {
82
81
  themeVersion: "0.0.0",
@@ -86,7 +85,7 @@ export const kcContextCommonMock: KcContext.Common = {
86
85
  url: {
87
86
  loginAction: "#",
88
87
  resourcesPath,
89
- resourcesCommonPath: `${resourcesPath}/${RESOURCES_COMMON}`,
88
+ resourcesCommonPath: `${resourcesPath}/${WELL_KNOWN_DIRECTORY_BASE_NAME.RESOURCES_COMMON}`,
90
89
  loginRestartFlowUrl: "#",
91
90
  loginUrl: "#",
92
91
  ssoLoginInOtherTabsUrl: "#"
@@ -327,9 +326,6 @@ export const kcContextMocks = [
327
326
  realm: {
328
327
  ...kcContextCommonMock.realm,
329
328
  resetPasswordAllowed: true
330
- },
331
- social: {
332
- displayInfo: false
333
329
  }
334
330
  }),
335
331
  id<KcContext.WebauthnAuthenticate>({
@@ -349,11 +345,7 @@ export const kcContextMocks = [
349
345
  rpId: "",
350
346
  createTimeout: "0",
351
347
  isUserIdentified: "false",
352
- shouldDisplayAuthenticators: false,
353
- social: {
354
- displayInfo: false
355
- },
356
- login: {}
348
+ shouldDisplayAuthenticators: false
357
349
  }),
358
350
  id<KcContext.LoginUpdatePassword>({
359
351
  ...kcContextCommonMock,
@@ -585,7 +577,7 @@ export const kcContextMocks = [
585
577
  challenge: "",
586
578
  userVerification: "not specified",
587
579
  rpId: "",
588
- createTimeout: "0",
580
+ createTimeout: 0,
589
581
  authenticators: {
590
582
  authenticators: []
591
583
  },
@@ -3,9 +3,8 @@ import { assert } from "keycloakify/tools/assert";
3
3
  import { clsx } from "keycloakify/tools/clsx";
4
4
  import type { TemplateProps } from "keycloakify/login/TemplateProps";
5
5
  import { getKcClsx } from "keycloakify/login/lib/kcClsx";
6
- import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
7
- import { useInsertLinkTags } from "keycloakify/tools/useInsertLinkTags";
8
6
  import { useSetClassName } from "keycloakify/tools/useSetClassName";
7
+ import { useStylesAndScripts } from "keycloakify/login/Template.useStylesAndScripts";
9
8
  import type { I18n } from "./i18n";
10
9
  import type { KcContext } from "./KcContext";
11
10
 
@@ -30,7 +29,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
30
29
 
31
30
  const { msg, msgStr, getChangeLocaleUrl, labelBySupportedLanguageTag, currentLanguageTag } = i18n;
32
31
 
33
- const { realm, locale, auth, url, message, isAppInitiatedAction, authenticationSession, scripts } = kcContext;
32
+ const { realm, locale, auth, url, message, isAppInitiatedAction } = kcContext;
34
33
 
35
34
  useEffect(() => {
36
35
  document.title = documentTitle ?? msgStr("loginTitle", kcContext.realm.displayName);
@@ -46,71 +45,9 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
46
45
  className: bodyClassName ?? kcClsx("kcBodyClass")
47
46
  });
48
47
 
49
- useEffect(() => {
50
- const { currentLanguageTag } = locale ?? {};
51
-
52
- if (currentLanguageTag === undefined) {
53
- return;
54
- }
55
-
56
- const html = document.querySelector("html");
57
- assert(html !== null);
58
- html.lang = currentLanguageTag;
59
- }, []);
60
-
61
- const { areAllStyleSheetsLoaded } = useInsertLinkTags({
62
- componentOrHookName: "Template",
63
- hrefs: !doUseDefaultCss
64
- ? []
65
- : [
66
- `${url.resourcesCommonPath}/node_modules/@patternfly/patternfly/patternfly.min.css`,
67
- `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly.min.css`,
68
- `${url.resourcesCommonPath}/node_modules/patternfly/dist/css/patternfly-additions.min.css`,
69
- `${url.resourcesCommonPath}/lib/pficon/pficon.css`,
70
- `${url.resourcesPath}/css/login.css`
71
- ]
72
- });
73
-
74
- const { insertScriptTags } = useInsertScriptTags({
75
- componentOrHookName: "Template",
76
- scriptTags: [
77
- {
78
- type: "module",
79
- src: `${url.resourcesPath}/js/menu-button-links.js`
80
- },
81
- ...(authenticationSession === undefined
82
- ? []
83
- : [
84
- {
85
- type: "module",
86
- textContent: [
87
- `import { checkCookiesAndSetTimer } from "${url.resourcesPath}/js/authChecker.js";`,
88
- ``,
89
- `checkCookiesAndSetTimer(`,
90
- ` "${authenticationSession.authSessionId}",`,
91
- ` "${authenticationSession.tabId}",`,
92
- ` "${url.ssoLoginInOtherTabsUrl}"`,
93
- `);`
94
- ].join("\n")
95
- } as const
96
- ]),
97
- ...scripts.map(
98
- script =>
99
- ({
100
- type: "text/javascript",
101
- src: script
102
- }) as const
103
- )
104
- ]
105
- });
106
-
107
- useEffect(() => {
108
- if (areAllStyleSheetsLoaded) {
109
- insertScriptTags();
110
- }
111
- }, [areAllStyleSheetsLoaded]);
48
+ const { isReadyToRender } = useStylesAndScripts({ kcContext, doUseDefaultCss });
112
49
 
113
- if (!areAllStyleSheetsLoaded) {
50
+ if (!isReadyToRender) {
114
51
  return null;
115
52
  }
116
53