keycloakify 10.0.5 → 10.1.0-rc.1

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 (226) hide show
  1. package/account/i18n/i18n.d.ts +2 -2
  2. package/account/i18n/messages_defaultSet/ar.d.ts +0 -1
  3. package/account/i18n/messages_defaultSet/ar.js +1 -2
  4. package/account/i18n/messages_defaultSet/ar.js.map +1 -1
  5. package/account/i18n/messages_defaultSet/ca.d.ts +1 -230
  6. package/account/i18n/messages_defaultSet/ca.js +76 -305
  7. package/account/i18n/messages_defaultSet/ca.js.map +1 -1
  8. package/account/i18n/messages_defaultSet/cs.d.ts +0 -1
  9. package/account/i18n/messages_defaultSet/cs.js +0 -1
  10. package/account/i18n/messages_defaultSet/cs.js.map +1 -1
  11. package/account/i18n/messages_defaultSet/da.d.ts +0 -1
  12. package/account/i18n/messages_defaultSet/da.js +0 -1
  13. package/account/i18n/messages_defaultSet/da.js.map +1 -1
  14. package/account/i18n/messages_defaultSet/de.d.ts +1 -2
  15. package/account/i18n/messages_defaultSet/de.js +38 -39
  16. package/account/i18n/messages_defaultSet/de.js.map +1 -1
  17. package/account/i18n/messages_defaultSet/en.d.ts +0 -4
  18. package/account/i18n/messages_defaultSet/en.js +0 -4
  19. package/account/i18n/messages_defaultSet/en.js.map +1 -1
  20. package/account/i18n/messages_defaultSet/es.d.ts +0 -231
  21. package/account/i18n/messages_defaultSet/es.js +0 -231
  22. package/account/i18n/messages_defaultSet/es.js.map +1 -1
  23. package/account/i18n/messages_defaultSet/fi.d.ts +0 -1
  24. package/account/i18n/messages_defaultSet/fi.js +0 -1
  25. package/account/i18n/messages_defaultSet/fi.js.map +1 -1
  26. package/account/i18n/messages_defaultSet/fr.d.ts +0 -6
  27. package/account/i18n/messages_defaultSet/fr.js +1 -7
  28. package/account/i18n/messages_defaultSet/fr.js.map +1 -1
  29. package/account/i18n/messages_defaultSet/hu.d.ts +0 -69
  30. package/account/i18n/messages_defaultSet/hu.js +24 -93
  31. package/account/i18n/messages_defaultSet/hu.js.map +1 -1
  32. package/account/i18n/messages_defaultSet/index.d.ts +134 -428
  33. package/account/i18n/messages_defaultSet/index.js +0 -4
  34. package/account/i18n/messages_defaultSet/index.js.map +1 -1
  35. package/account/i18n/messages_defaultSet/it.d.ts +0 -6
  36. package/account/i18n/messages_defaultSet/it.js +0 -6
  37. package/account/i18n/messages_defaultSet/it.js.map +1 -1
  38. package/account/i18n/messages_defaultSet/ja.d.ts +0 -1
  39. package/account/i18n/messages_defaultSet/ja.js +0 -1
  40. package/account/i18n/messages_defaultSet/ja.js.map +1 -1
  41. package/account/i18n/messages_defaultSet/lt.d.ts +0 -1
  42. package/account/i18n/messages_defaultSet/lt.js +0 -1
  43. package/account/i18n/messages_defaultSet/lt.js.map +1 -1
  44. package/account/i18n/messages_defaultSet/lv.d.ts +0 -1
  45. package/account/i18n/messages_defaultSet/lv.js +0 -1
  46. package/account/i18n/messages_defaultSet/lv.js.map +1 -1
  47. package/account/i18n/messages_defaultSet/nl.d.ts +0 -1
  48. package/account/i18n/messages_defaultSet/nl.js +0 -1
  49. package/account/i18n/messages_defaultSet/nl.js.map +1 -1
  50. package/account/i18n/messages_defaultSet/no.d.ts +0 -1
  51. package/account/i18n/messages_defaultSet/no.js +0 -1
  52. package/account/i18n/messages_defaultSet/no.js.map +1 -1
  53. package/account/i18n/messages_defaultSet/pl.d.ts +0 -115
  54. package/account/i18n/messages_defaultSet/pl.js +0 -115
  55. package/account/i18n/messages_defaultSet/pl.js.map +1 -1
  56. package/account/i18n/messages_defaultSet/pt-BR.d.ts +0 -1
  57. package/account/i18n/messages_defaultSet/pt-BR.js +0 -1
  58. package/account/i18n/messages_defaultSet/pt-BR.js.map +1 -1
  59. package/account/i18n/messages_defaultSet/ru.d.ts +0 -1
  60. package/account/i18n/messages_defaultSet/ru.js +0 -1
  61. package/account/i18n/messages_defaultSet/ru.js.map +1 -1
  62. package/account/i18n/messages_defaultSet/sk.d.ts +0 -1
  63. package/account/i18n/messages_defaultSet/sk.js +0 -1
  64. package/account/i18n/messages_defaultSet/sk.js.map +1 -1
  65. package/account/i18n/messages_defaultSet/sv.d.ts +0 -1
  66. package/account/i18n/messages_defaultSet/sv.js +0 -1
  67. package/account/i18n/messages_defaultSet/sv.js.map +1 -1
  68. package/account/i18n/messages_defaultSet/tr.d.ts +1 -2
  69. package/account/i18n/messages_defaultSet/tr.js +1 -2
  70. package/account/i18n/messages_defaultSet/tr.js.map +1 -1
  71. package/account/i18n/messages_defaultSet/zh-CN.d.ts +0 -11
  72. package/account/i18n/messages_defaultSet/zh-CN.js +0 -11
  73. package/account/i18n/messages_defaultSet/zh-CN.js.map +1 -1
  74. package/account/i18n/useI18n.d.ts +2 -2
  75. package/bin/193.index.js +1 -1
  76. package/bin/31.index.js +6 -4
  77. package/bin/{622.index.js → 365.index.js} +76 -47
  78. package/bin/440.index.js +3 -20
  79. package/bin/932.index.js +1 -1
  80. package/bin/main.js +3 -3
  81. package/bin/shared/buildContext.js.map +1 -1
  82. package/bin/shared/constants.d.ts +2 -2
  83. package/bin/shared/constants.js +4 -2
  84. package/bin/shared/constants.js.map +1 -1
  85. package/login/DefaultPage.js +6 -0
  86. package/login/DefaultPage.js.map +1 -1
  87. package/login/KcContext/KcContext.d.ts +32 -1
  88. package/login/KcContext/KcContext.js.map +1 -1
  89. package/login/KcContext/getKcContextMock.d.ts +1 -1
  90. package/login/KcContext/kcContextMocks.d.ts +1 -1
  91. package/login/KcContext/kcContextMocks.js +5 -1
  92. package/login/KcContext/kcContextMocks.js.map +1 -1
  93. package/login/i18n/i18n.d.ts +2 -2
  94. package/login/i18n/messages_defaultSet/ca.d.ts +0 -23
  95. package/login/i18n/messages_defaultSet/ca.js +0 -23
  96. package/login/i18n/messages_defaultSet/ca.js.map +1 -1
  97. package/login/i18n/messages_defaultSet/cs.d.ts +1 -0
  98. package/login/i18n/messages_defaultSet/cs.js +16 -15
  99. package/login/i18n/messages_defaultSet/cs.js.map +1 -1
  100. package/login/i18n/messages_defaultSet/da.d.ts +0 -2
  101. package/login/i18n/messages_defaultSet/da.js +0 -2
  102. package/login/i18n/messages_defaultSet/da.js.map +1 -1
  103. package/login/i18n/messages_defaultSet/de.d.ts +83 -2
  104. package/login/i18n/messages_defaultSet/de.js +107 -26
  105. package/login/i18n/messages_defaultSet/de.js.map +1 -1
  106. package/login/i18n/messages_defaultSet/el.d.ts +0 -23
  107. package/login/i18n/messages_defaultSet/el.js +0 -23
  108. package/login/i18n/messages_defaultSet/el.js.map +1 -1
  109. package/login/i18n/messages_defaultSet/en.d.ts +19 -25
  110. package/login/i18n/messages_defaultSet/en.js +19 -25
  111. package/login/i18n/messages_defaultSet/en.js.map +1 -1
  112. package/login/i18n/messages_defaultSet/es.d.ts +0 -24
  113. package/login/i18n/messages_defaultSet/es.js +0 -24
  114. package/login/i18n/messages_defaultSet/es.js.map +1 -1
  115. package/login/i18n/messages_defaultSet/fa.d.ts +0 -23
  116. package/login/i18n/messages_defaultSet/fa.js +0 -23
  117. package/login/i18n/messages_defaultSet/fa.js.map +1 -1
  118. package/login/i18n/messages_defaultSet/hu.d.ts +0 -23
  119. package/login/i18n/messages_defaultSet/hu.js +0 -23
  120. package/login/i18n/messages_defaultSet/hu.js.map +1 -1
  121. package/login/i18n/messages_defaultSet/index.d.ts +96 -941
  122. package/login/i18n/messages_defaultSet/index.js +3 -0
  123. package/login/i18n/messages_defaultSet/index.js.map +1 -1
  124. package/login/i18n/messages_defaultSet/it.d.ts +0 -1
  125. package/login/i18n/messages_defaultSet/it.js +0 -1
  126. package/login/i18n/messages_defaultSet/it.js.map +1 -1
  127. package/login/i18n/messages_defaultSet/ka.d.ts +468 -0
  128. package/login/i18n/messages_defaultSet/ka.js +473 -0
  129. package/login/i18n/messages_defaultSet/ka.js.map +1 -0
  130. package/login/i18n/messages_defaultSet/pt-BR.d.ts +1 -0
  131. package/login/i18n/messages_defaultSet/pt-BR.js +3 -2
  132. package/login/i18n/messages_defaultSet/pt-BR.js.map +1 -1
  133. package/login/i18n/messages_defaultSet/pt.d.ts +448 -0
  134. package/login/i18n/messages_defaultSet/pt.js +453 -0
  135. package/login/i18n/messages_defaultSet/pt.js.map +1 -0
  136. package/login/i18n/messages_defaultSet/sk.d.ts +1 -0
  137. package/login/i18n/messages_defaultSet/sk.js +16 -15
  138. package/login/i18n/messages_defaultSet/sk.js.map +1 -1
  139. package/login/i18n/messages_defaultSet/zh-CN.d.ts +0 -24
  140. package/login/i18n/messages_defaultSet/zh-CN.js +0 -24
  141. package/login/i18n/messages_defaultSet/zh-CN.js.map +1 -1
  142. package/login/i18n/messages_defaultSet/zh-TW.d.ts +453 -0
  143. package/login/i18n/messages_defaultSet/zh-TW.js +458 -0
  144. package/login/i18n/messages_defaultSet/zh-TW.js.map +1 -0
  145. package/login/i18n/useI18n.d.ts +2 -2
  146. package/login/pages/LoginIdpLinkConfirmOverride.d.ts +7 -0
  147. package/login/pages/LoginIdpLinkConfirmOverride.js +14 -0
  148. package/login/pages/LoginIdpLinkConfirmOverride.js.map +1 -0
  149. package/login/pages/LoginPasskeysConditionalAuthenticate.d.ts +7 -0
  150. package/login/pages/LoginPasskeysConditionalAuthenticate.js +80 -0
  151. package/login/pages/LoginPasskeysConditionalAuthenticate.js.map +1 -0
  152. package/package.json +28 -21
  153. package/src/account/i18n/messages_defaultSet/ar.ts +1 -2
  154. package/src/account/i18n/messages_defaultSet/ca.ts +76 -305
  155. package/src/account/i18n/messages_defaultSet/cs.ts +0 -1
  156. package/src/account/i18n/messages_defaultSet/da.ts +0 -1
  157. package/src/account/i18n/messages_defaultSet/de.ts +38 -39
  158. package/src/account/i18n/messages_defaultSet/en.ts +0 -4
  159. package/src/account/i18n/messages_defaultSet/es.ts +0 -231
  160. package/src/account/i18n/messages_defaultSet/fi.ts +0 -1
  161. package/src/account/i18n/messages_defaultSet/fr.ts +1 -7
  162. package/src/account/i18n/messages_defaultSet/hu.ts +24 -93
  163. package/src/account/i18n/messages_defaultSet/index.ts +0 -4
  164. package/src/account/i18n/messages_defaultSet/it.ts +0 -6
  165. package/src/account/i18n/messages_defaultSet/ja.ts +0 -1
  166. package/src/account/i18n/messages_defaultSet/lt.ts +0 -1
  167. package/src/account/i18n/messages_defaultSet/lv.ts +0 -1
  168. package/src/account/i18n/messages_defaultSet/nl.ts +0 -1
  169. package/src/account/i18n/messages_defaultSet/no.ts +0 -1
  170. package/src/account/i18n/messages_defaultSet/pl.ts +0 -115
  171. package/src/account/i18n/messages_defaultSet/pt-BR.ts +0 -1
  172. package/src/account/i18n/messages_defaultSet/ru.ts +0 -1
  173. package/src/account/i18n/messages_defaultSet/sk.ts +0 -1
  174. package/src/account/i18n/messages_defaultSet/sv.ts +0 -1
  175. package/src/account/i18n/messages_defaultSet/tr.ts +1 -2
  176. package/src/account/i18n/messages_defaultSet/zh-CN.ts +0 -11
  177. package/src/bin/keycloakify/buildJars/buildJar.ts +0 -19
  178. package/src/bin/shared/buildContext.ts +2 -2
  179. package/src/bin/shared/constants.ts +4 -2
  180. package/src/bin/shared/{downloadKeycloakDefaultTheme.ts → downloadKeycloakDefaultTheme/downloadKeycloakDefaultTheme.ts} +46 -5
  181. package/src/bin/shared/downloadKeycloakDefaultTheme/extra-assets/passkeysConditionalAuth.js +79 -0
  182. package/src/bin/shared/downloadKeycloakDefaultTheme/extra-assets/webauthnAuthenticate.js +82 -0
  183. package/src/bin/shared/downloadKeycloakDefaultTheme/index.ts +1 -0
  184. package/src/login/DefaultPage.tsx +6 -0
  185. package/src/login/KcContext/KcContext.ts +37 -1
  186. package/src/login/KcContext/kcContextMocks.ts +33 -0
  187. package/src/login/i18n/messages_defaultSet/ca.ts +0 -23
  188. package/src/login/i18n/messages_defaultSet/cs.ts +16 -15
  189. package/src/login/i18n/messages_defaultSet/da.ts +0 -2
  190. package/src/login/i18n/messages_defaultSet/de.ts +107 -26
  191. package/src/login/i18n/messages_defaultSet/el.ts +0 -23
  192. package/src/login/i18n/messages_defaultSet/en.ts +19 -25
  193. package/src/login/i18n/messages_defaultSet/es.ts +0 -24
  194. package/src/login/i18n/messages_defaultSet/fa.ts +0 -23
  195. package/src/login/i18n/messages_defaultSet/hu.ts +0 -23
  196. package/src/login/i18n/messages_defaultSet/index.ts +3 -0
  197. package/src/login/i18n/messages_defaultSet/it.ts +0 -1
  198. package/src/login/i18n/messages_defaultSet/ka.ts +474 -0
  199. package/src/login/i18n/messages_defaultSet/pt-BR.ts +3 -2
  200. package/src/login/i18n/messages_defaultSet/pt.ts +454 -0
  201. package/src/login/i18n/messages_defaultSet/sk.ts +16 -15
  202. package/src/login/i18n/messages_defaultSet/zh-CN.ts +0 -24
  203. package/src/login/i18n/messages_defaultSet/zh-TW.ts +459 -0
  204. package/src/login/pages/LoginIdpLinkConfirmOverride.tsx +40 -0
  205. package/src/login/pages/LoginPasskeysConditionalAuthenticate.tsx +252 -0
  206. package/stories/login/pages/LoginIdpLinkConfirmOverride.stories.tsx +18 -0
  207. package/stories/login/pages/LoginPasskeysConditionalAuthenticate.stories.tsx +18 -0
  208. package/vite-plugin/index.js +46 -25
  209. package/account/i18n/messages_defaultSet/el.d.ts +0 -360
  210. package/account/i18n/messages_defaultSet/el.js +0 -365
  211. package/account/i18n/messages_defaultSet/el.js.map +0 -1
  212. package/account/i18n/messages_defaultSet/fa.d.ts +0 -361
  213. package/account/i18n/messages_defaultSet/fa.js +0 -366
  214. package/account/i18n/messages_defaultSet/fa.js.map +0 -1
  215. package/account/i18n/messages_defaultSet/th.d.ts +0 -339
  216. package/account/i18n/messages_defaultSet/th.js +0 -344
  217. package/account/i18n/messages_defaultSet/th.js.map +0 -1
  218. package/account/i18n/messages_defaultSet/uk.d.ts +0 -339
  219. package/account/i18n/messages_defaultSet/uk.js +0 -344
  220. package/account/i18n/messages_defaultSet/uk.js.map +0 -1
  221. package/bin/shared/downloadKeycloakDefaultTheme.d.ts +0 -11
  222. package/bin/shared/downloadKeycloakDefaultTheme.js.map +0 -1
  223. package/src/account/i18n/messages_defaultSet/el.ts +0 -366
  224. package/src/account/i18n/messages_defaultSet/fa.ts +0 -367
  225. package/src/account/i18n/messages_defaultSet/th.ts +0 -345
  226. package/src/account/i18n/messages_defaultSet/uk.ts +0 -345
@@ -1,8 +1,10 @@
1
1
  import { join as pathJoin, relative as pathRelative } from "path";
2
- import { type BuildContext } from "./buildContext";
2
+ import { type BuildContext } from "../buildContext";
3
3
  import { assert } from "tsafe/assert";
4
- import { LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 } from "./constants";
5
- import { downloadAndExtractArchive } from "../tools/downloadAndExtractArchive";
4
+ import { LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 } from "../constants";
5
+ import { downloadAndExtractArchive } from "../../tools/downloadAndExtractArchive";
6
+ import { getThisCodebaseRootDirPath } from "../../tools/getThisCodebaseRootDirPath";
7
+ import * as fsPr from "fs/promises";
6
8
 
7
9
  export type BuildContextLike = {
8
10
  cacheDirPath: string;
@@ -20,6 +22,8 @@ export async function downloadKeycloakDefaultTheme(params: {
20
22
  let kcNodeModulesKeepFilePaths: Set<string> | undefined = undefined;
21
23
  let kcNodeModulesKeepFilePaths_lastAccountV1: Set<string> | undefined = undefined;
22
24
 
25
+ let areExtraAssetsFor24Copied = false;
26
+
23
27
  const { extractedDirPath } = await downloadAndExtractArchive({
24
28
  url: `https://repo1.maven.org/maven2/org/keycloak/keycloak-themes/${keycloakVersion}/keycloak-themes-${keycloakVersion}.jar`,
25
29
  cacheDirPath: buildContext.cacheDirPath,
@@ -32,8 +36,6 @@ export async function downloadKeycloakDefaultTheme(params: {
32
36
  return;
33
37
  }
34
38
 
35
- const { readFile, writeFile } = params;
36
-
37
39
  skip_keycloak_v2: {
38
40
  if (!fileRelativePath.startsWith(pathJoin("keycloak.v2"))) {
39
41
  break skip_keycloak_v2;
@@ -42,6 +44,8 @@ export async function downloadKeycloakDefaultTheme(params: {
42
44
  return;
43
45
  }
44
46
 
47
+ const { readFile, writeFile } = params;
48
+
45
49
  last_account_v1_transformations: {
46
50
  if (LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 !== keycloakVersion) {
47
51
  break last_account_v1_transformations;
@@ -168,6 +172,43 @@ export async function downloadKeycloakDefaultTheme(params: {
168
172
  }
169
173
  }
170
174
 
175
+ copy_extra_assets: {
176
+ if (keycloakVersion !== "24.0.4") {
177
+ break copy_extra_assets;
178
+ }
179
+
180
+ if (areExtraAssetsFor24Copied) {
181
+ break copy_extra_assets;
182
+ }
183
+
184
+ const extraAssetsDirPath = pathJoin(
185
+ getThisCodebaseRootDirPath(),
186
+ "src",
187
+ "bin",
188
+ "shared",
189
+ "downloadKeycloakDefaultTheme",
190
+ "extra-assets"
191
+ );
192
+
193
+ await Promise.all(
194
+ ["webauthnAuthenticate.js", "passkeysConditionalAuth.js"].map(
195
+ async fileBasename =>
196
+ writeFile({
197
+ fileRelativePath: pathJoin(
198
+ "base",
199
+ "login",
200
+ "resources",
201
+ "js",
202
+ fileBasename
203
+ ),
204
+ modifiedData: await fsPr.readFile(
205
+ pathJoin(extraAssetsDirPath, fileBasename)
206
+ )
207
+ })
208
+ )
209
+ );
210
+ }
211
+
171
212
  skip_unused_resources: {
172
213
  if (keycloakVersion !== "24.0.4") {
173
214
  break skip_unused_resources;
@@ -0,0 +1,79 @@
1
+ import { base64url } from "rfc4648";
2
+ import { returnSuccess, returnFailure } from "./webauthnAuthenticate.js";
3
+
4
+ export function initAuthenticate(input) {
5
+ // Check if WebAuthn is supported by this browser
6
+ if (!window.PublicKeyCredential) {
7
+ returnFailure(input.errmsg);
8
+ return;
9
+ }
10
+ if (input.isUserIdentified || typeof PublicKeyCredential.isConditionalMediationAvailable === "undefined") {
11
+ document.getElementById("kc-form-passkey-button").style.display = 'block';
12
+ } else {
13
+ tryAutoFillUI(input);
14
+ }
15
+ }
16
+
17
+ function doAuthenticate(input) {
18
+ // Check if WebAuthn is supported by this browser
19
+ if (!window.PublicKeyCredential) {
20
+ returnFailure(input.errmsg);
21
+ return;
22
+ }
23
+
24
+ const publicKey = {
25
+ rpId : input.rpId,
26
+ challenge: base64url.parse(input.challenge, { loose: true })
27
+ };
28
+
29
+ publicKey.allowCredentials = !input.isUserIdentified ? [] : getAllowCredentials();
30
+
31
+ if (input.createTimeout !== 0) {
32
+ publicKey.timeout = input.createTimeout * 1000;
33
+ }
34
+
35
+ if (input.userVerification !== 'not specified') {
36
+ publicKey.userVerification = input.userVerification;
37
+ }
38
+
39
+ return navigator.credentials.get({
40
+ publicKey: publicKey,
41
+ ...input.additionalOptions
42
+ });
43
+ }
44
+
45
+ async function tryAutoFillUI(input) {
46
+ const isConditionalMediationAvailable = await PublicKeyCredential.isConditionalMediationAvailable();
47
+ if (isConditionalMediationAvailable) {
48
+ document.getElementById("kc-form-login").style.display = "block";
49
+ input.additionalOptions = { mediation: 'conditional'};
50
+ try {
51
+ const result = await doAuthenticate(input);
52
+ returnSuccess(result);
53
+ } catch (error) {
54
+ returnFailure(error);
55
+ }
56
+ } else {
57
+ document.getElementById("kc-form-passkey-button").style.display = 'block';
58
+ }
59
+ }
60
+
61
+ function getAllowCredentials() {
62
+ const allowCredentials = [];
63
+ const authnUse = document.forms['authn_select'].authn_use_chk;
64
+ if (authnUse !== undefined) {
65
+ if (authnUse.length === undefined) {
66
+ allowCredentials.push({
67
+ id: base64url.parse(authnUse.value, {loose: true}),
68
+ type: 'public-key',
69
+ });
70
+ } else {
71
+ authnUse.forEach((entry) =>
72
+ allowCredentials.push({
73
+ id: base64url.parse(entry.value, {loose: true}),
74
+ type: 'public-key',
75
+ }));
76
+ }
77
+ }
78
+ return allowCredentials;
79
+ }
@@ -0,0 +1,82 @@
1
+ import { base64url } from "rfc4648";
2
+
3
+ export async function authenticateByWebAuthn(input) {
4
+ if (!input.isUserIdentified) {
5
+ try {
6
+ const result = await doAuthenticate([], input.challenge, input.userVerification, input.rpId, input.createTimeout, input.errmsg);
7
+ returnSuccess(result);
8
+ } catch (error) {
9
+ returnFailure(error);
10
+ }
11
+ return;
12
+ }
13
+ checkAllowCredentials(input.challenge, input.userVerification, input.rpId, input.createTimeout, input.errmsg);
14
+ }
15
+
16
+ async function checkAllowCredentials(challenge, userVerification, rpId, createTimeout, errmsg) {
17
+ const allowCredentials = [];
18
+ const authnUse = document.forms['authn_select'].authn_use_chk;
19
+ if (authnUse !== undefined) {
20
+ if (authnUse.length === undefined) {
21
+ allowCredentials.push({
22
+ id: base64url.parse(authnUse.value, {loose: true}),
23
+ type: 'public-key',
24
+ });
25
+ } else {
26
+ authnUse.forEach((entry) =>
27
+ allowCredentials.push({
28
+ id: base64url.parse(entry.value, {loose: true}),
29
+ type: 'public-key',
30
+ }));
31
+ }
32
+ }
33
+ try {
34
+ const result = await doAuthenticate(allowCredentials, challenge, userVerification, rpId, createTimeout, errmsg);
35
+ returnSuccess(result);
36
+ } catch (error) {
37
+ returnFailure(error);
38
+ }
39
+ }
40
+
41
+ function doAuthenticate(allowCredentials, challenge, userVerification, rpId, createTimeout, errmsg) {
42
+ // Check if WebAuthn is supported by this browser
43
+ if (!window.PublicKeyCredential) {
44
+ returnFailure(errmsg);
45
+ return;
46
+ }
47
+
48
+ const publicKey = {
49
+ rpId : rpId,
50
+ challenge: base64url.parse(challenge, { loose: true })
51
+ };
52
+
53
+ if (createTimeout !== 0) {
54
+ publicKey.timeout = createTimeout * 1000;
55
+ }
56
+
57
+ if (allowCredentials.length) {
58
+ publicKey.allowCredentials = allowCredentials;
59
+ }
60
+
61
+ if (userVerification !== 'not specified') {
62
+ publicKey.userVerification = userVerification;
63
+ }
64
+
65
+ return navigator.credentials.get({publicKey});
66
+ }
67
+
68
+ export function returnSuccess(result) {
69
+ document.getElementById("clientDataJSON").value = base64url.stringify(new Uint8Array(result.response.clientDataJSON), { pad: false });
70
+ document.getElementById("authenticatorData").value = base64url.stringify(new Uint8Array(result.response.authenticatorData), { pad: false });
71
+ document.getElementById("signature").value = base64url.stringify(new Uint8Array(result.response.signature), { pad: false });
72
+ document.getElementById("credentialId").value = result.id;
73
+ if (result.response.userHandle) {
74
+ document.getElementById("userHandle").value = base64url.stringify(new Uint8Array(result.response.userHandle), { pad: false });
75
+ }
76
+ document.getElementById("webauth").submit();
77
+ }
78
+
79
+ export function returnFailure(err) {
80
+ document.getElementById("error").value = err;
81
+ document.getElementById("webauth").submit();
82
+ }
@@ -0,0 +1 @@
1
+ export * from "./downloadKeycloakDefaultTheme";
@@ -40,6 +40,8 @@ const LoginRecoveryAuthnCodeInput = lazy(() => import("keycloakify/login/pages/L
40
40
  const LoginResetOtp = lazy(() => import("keycloakify/login/pages/LoginResetOtp"));
41
41
  const LoginX509Info = lazy(() => import("keycloakify/login/pages/LoginX509Info"));
42
42
  const WebauthnError = lazy(() => import("keycloakify/login/pages/WebauthnError"));
43
+ const LoginPasskeysConditionalAuthenticate = lazy(() => import("keycloakify/login/pages/LoginPasskeysConditionalAuthenticate"));
44
+ const LoginIdpLinkConfirmOverride = lazy(() => import("keycloakify/login/pages/LoginIdpLinkConfirmOverride"));
43
45
 
44
46
  type DefaultPageProps = PageProps<KcContext, I18n> & {
45
47
  UserProfileFormFields: LazyOrNot<(props: UserProfileFormFieldsProps) => JSX.Element>;
@@ -121,6 +123,10 @@ export default function DefaultPage(props: DefaultPageProps) {
121
123
  return <LoginX509Info kcContext={kcContext} {...rest} />;
122
124
  case "webauthn-error.ftl":
123
125
  return <WebauthnError kcContext={kcContext} {...rest} />;
126
+ case "login-passkeys-conditional-authenticate.ftl":
127
+ return <LoginPasskeysConditionalAuthenticate kcContext={kcContext} {...rest} />;
128
+ case "login-idp-link-confirm-override.ftl":
129
+ return <LoginIdpLinkConfirmOverride kcContext={kcContext} {...rest} />;
124
130
  }
125
131
  assert<Equals<typeof kcContext, never>>(false);
126
132
  })()}
@@ -59,7 +59,9 @@ export type KcContext =
59
59
  | KcContext.LoginRecoveryAuthnCodeInput
60
60
  | KcContext.LoginResetOtp
61
61
  | KcContext.LoginX509Info
62
- | KcContext.WebauthnError;
62
+ | KcContext.WebauthnError
63
+ | KcContext.LoginPasskeysConditionalAuthenticate
64
+ | KcContext.LoginIdpLinkConfirmOverride;
63
65
 
64
66
  assert<KcContext["themeType"] extends ThemeType ? true : false>();
65
67
 
@@ -577,6 +579,40 @@ export declare namespace KcContext {
577
579
  pageId: "webauthn-error.ftl";
578
580
  isAppInitiatedAction?: boolean;
579
581
  };
582
+
583
+ export type LoginPasskeysConditionalAuthenticate = Common & {
584
+ pageId: "login-passkeys-conditional-authenticate.ftl";
585
+ realm: {
586
+ registrationAllowed: boolean;
587
+ password: boolean;
588
+ };
589
+ url: {
590
+ registrationUrl: string;
591
+ };
592
+ registrationDisabled: boolean;
593
+ isUserIdentified: boolean | "true" | "false";
594
+ challenge: string;
595
+ userVerification: string;
596
+ rpId: string;
597
+ createTimeout: number | string;
598
+
599
+ authenticators?: {
600
+ authenticators: WebauthnAuthenticate.WebauthnAuthenticator[];
601
+ };
602
+ shouldDisplayAuthenticators?: boolean;
603
+ usernameHidden?: boolean;
604
+ login: {
605
+ username?: string;
606
+ };
607
+ };
608
+
609
+ export type LoginIdpLinkConfirmOverride = Common & {
610
+ pageId: "login-idp-link-confirm-override.ftl";
611
+ url: {
612
+ loginRestartFlowUrl: string;
613
+ };
614
+ idpDisplayName: string;
615
+ };
580
616
  }
581
617
 
582
618
  export type UserProfile = {
@@ -567,6 +567,39 @@ export const kcContextMocks = [
567
567
  pageId: "webauthn-error.ftl",
568
568
  ...kcContextCommonMock,
569
569
  isAppInitiatedAction: true
570
+ }),
571
+ id<KcContext.LoginPasskeysConditionalAuthenticate>({
572
+ pageId: "login-passkeys-conditional-authenticate.ftl",
573
+ ...kcContextCommonMock,
574
+ url: {
575
+ ...kcContextCommonMock.url,
576
+ registrationUrl: "#"
577
+ },
578
+ realm: {
579
+ ...kcContextCommonMock.realm,
580
+ password: true,
581
+ registrationAllowed: true
582
+ },
583
+ registrationDisabled: false,
584
+ isUserIdentified: "false",
585
+ challenge: "",
586
+ userVerification: "not specified",
587
+ rpId: "",
588
+ createTimeout: "0",
589
+ authenticators: {
590
+ authenticators: []
591
+ },
592
+ shouldDisplayAuthenticators: false,
593
+ login: {}
594
+ }),
595
+ id<KcContext.LoginIdpLinkConfirmOverride>({
596
+ pageId: "login-idp-link-confirm-override.ftl",
597
+ ...kcContextCommonMock,
598
+ url: {
599
+ ...kcContextCommonMock.url,
600
+ loginRestartFlowUrl: "#"
601
+ },
602
+ idpDisplayName: "Google"
570
603
  })
571
604
  ];
572
605
 
@@ -325,29 +325,6 @@ const messages= {
325
325
  "confirmAccountLinking": "Confirmeu l'enllaçat del compte {0} del proveïdor d'identitat {1} amb el vostre compte.",
326
326
  "confirmEmailAddressVerification": "Confirmeu la validesa de l'adreça de correu electrònic {0}.",
327
327
  "confirmExecutionOfActions": "Completeu les accions següents",
328
- "locale_ar": "àrab",
329
- "locale_ca": "català",
330
- "locale_cs": "txec",
331
- "locale_da": "danès",
332
- "locale_de": "alemany",
333
- "locale_en": "anglès",
334
- "locale_es": "castellà",
335
- "locale_fi": "finès",
336
- "locale_fr": "francès",
337
- "locale_hu": "hongarès",
338
- "locale_it": "italià",
339
- "locale_ja": "japonès",
340
- "locale_lt": "lituà",
341
- "locale_lv": "letó",
342
- "locale_nl": "neerlandès",
343
- "locale_no": "noruec",
344
- "locale_pl": "polonès",
345
- "locale_pt-BR": "portuguès (Brasil)",
346
- "locale_ru": "rus",
347
- "locale_sk": "eslovè",
348
- "locale_sv": "suec",
349
- "locale_tr": "turc",
350
- "locale_zh-CN": "xinès simplificat",
351
328
  "backToApplication": "&laquo; Torna a l'aplicació",
352
329
  "missingParameterMessage": "Manquen paràmetres\\: {0}",
353
330
  "clientNotFoundMessage": "No s'ha trobat el client.",
@@ -396,23 +396,23 @@ const messages= {
396
396
  "recovery-codes-download-file-description": "Kódy pro obnovu jsou hesla pro jednorázové použití, pomocí kterých se můžete přihlásit bez přístupu k autentikátoru.",
397
397
  "recovery-codes-download-file-date": "Tyto kódy byly generovány",
398
398
  "recovery-codes-label-default": "Kódy pro obnovu",
399
- "webauthn-display-name": "Bezpečnostní klíč",
400
- "webauthn-help-text": "Použijte k přihlášení bezpečnostní klíč.",
401
- "webauthn-passwordless-display-name": "Bezpečnostní klíč",
402
- "webauthn-passwordless-help-text": "Použijte bezpečnostní klíč k přihlášení bez hesla.",
403
- "webauthn-login-title": "Přihlášení bezpečnostním klíčem",
404
- "webauthn-registration-title": "Registrace bezpečnostního klíče",
405
- "webauthn-available-authenticators": "Dostupné bezpečnostní klíče",
399
+ "webauthn-display-name": "Přístupový klíč",
400
+ "webauthn-help-text": "Použijte k přihlášení přístupový klíč.",
401
+ "webauthn-passwordless-display-name": "Přístupový klíč",
402
+ "webauthn-passwordless-help-text": "Použijte přístupový klíč k přihlášení bez hesla.",
403
+ "webauthn-login-title": "Přihlášení přístupovým klíčem",
404
+ "webauthn-registration-title": "Registrace přístupového klíče",
405
+ "webauthn-available-authenticators": "Dostupné přístupové klíče",
406
406
  "webauthn-unsupported-browser-text": "WebAuthn není v tomto prohlížeči podporováno. Zkuste jiný prohlížeč nebo kontaktujte svého administrátora.",
407
- "webauthn-doAuthenticate": "Přihlášení bezpečnostním klíčem",
407
+ "webauthn-doAuthenticate": "Přihlášení přístupovým klíčem",
408
408
  "webauthn-createdAt-label": "Vytvořeno",
409
- "webauthn-error-title": "Chyba bezpečnostního klíče",
410
- "webauthn-error-registration": "Selhala registrace vašeho bezpečnostního klíče.<br/> {0}",
411
- "webauthn-error-api-get": "Selhalo přihlášení pomocí bezpečnostního klíče.<br/> {0}",
412
- "webauthn-error-different-user": "První přihlášený uživatel není totožný s uživatelem přihlášeným pomocí bezpečnostního klíče.",
413
- "webauthn-error-auth-verification": "Nevalidní výsledek přihlášení pomocí bezpečnostního klíče.<br/> {0}",
414
- "webauthn-error-register-verification": "Nevalidní výsledek registrace bezpečnostního klíče.<br/> {0}",
415
- "webauthn-error-user-not-found": "Neznámý uživatel přihlášen pomocí bezpečnostního klíče.",
409
+ "webauthn-error-title": "Chyba přístupového klíče",
410
+ "webauthn-error-registration": "Selhala registrace vašeho přístupového klíče.<br/> {0}",
411
+ "webauthn-error-api-get": "Selhalo přihlášení pomocí přístupového klíče.<br/> {0}",
412
+ "webauthn-error-different-user": "První přihlášený uživatel není totožný s uživatelem přihlášeným pomocí přístupového klíče.",
413
+ "webauthn-error-auth-verification": "Nevalidní výsledek přihlášení pomocí přístupového klíče.<br/> {0}",
414
+ "webauthn-error-register-verification": "Nevalidní výsledek registrace přístupového klíče.<br/> {0}",
415
+ "webauthn-error-user-not-found": "Neznámý uživatel přihlášen pomocí přístupového klíče.",
416
416
  "identity-provider-redirector": "Propojit s jiným poskytovatelem identit",
417
417
  "identity-provider-login-label": "Nebo se přihlaste pomocí",
418
418
  "idp-email-verification-display-name": "Ověření e-mailu",
@@ -435,6 +435,7 @@ const messages= {
435
435
  "logoutConfirmHeader": "Chcete se odhlásit?",
436
436
  "doLogout": "Odhlásit",
437
437
  "readOnlyUsernameMessage": "Nemůžete aktualizovat své uživatelské jméno, protože je pouze pro čtení.",
438
+ "error-invalid-multivalued-size": "Atribut {0} musí mít nejméně {1} {1,choice,0#hodnot|1#hodnotu|1<hodnoty|4<hodnot} a nejvíce {2} {2,choice,0#hodnot|1#hodnotu|1<hodnoty|4<hodnot}.",
438
439
  "shouldBeEqual": "{0} by měl být roven {1}",
439
440
  "shouldBeDifferent": "{0} by měl být odlišný od {1}",
440
441
  "shouldMatchPattern": "Vzor by měl odpovídat: `/{0}/`",
@@ -281,8 +281,6 @@ const messages= {
281
281
  "invalidPasswordMessage": "Ugyldig adangskode.",
282
282
  "missingTotpDeviceNameMessage": "Angiv venligst et udstyrsnavn.",
283
283
  "nestedFirstBrokerFlowMessage": "{0} brugeren {1} er ikke forbundet til nogen kendt bruger.",
284
- "locale_cs": "Čeština",
285
- "locale_pl": "Polish",
286
284
  "openshift.scope.user_info": "Brugerinformation",
287
285
  "openshift.scope.user_check-access": "Brugeradgangsinformation",
288
286
  "openshift.scope.user_full": "Fuld adgang",