keycloakify 10.0.4 → 10.1.0-rc.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.
- package/README.md +1 -1
- package/account/i18n/i18n.d.ts +2 -2
- package/account/i18n/messages_defaultSet/ar.d.ts +0 -1
- package/account/i18n/messages_defaultSet/ar.js +1 -2
- package/account/i18n/messages_defaultSet/ar.js.map +1 -1
- package/account/i18n/messages_defaultSet/ca.d.ts +1 -230
- package/account/i18n/messages_defaultSet/ca.js +76 -305
- package/account/i18n/messages_defaultSet/ca.js.map +1 -1
- package/account/i18n/messages_defaultSet/cs.d.ts +0 -1
- package/account/i18n/messages_defaultSet/cs.js +0 -1
- package/account/i18n/messages_defaultSet/cs.js.map +1 -1
- package/account/i18n/messages_defaultSet/da.d.ts +0 -1
- package/account/i18n/messages_defaultSet/da.js +0 -1
- package/account/i18n/messages_defaultSet/da.js.map +1 -1
- package/account/i18n/messages_defaultSet/de.d.ts +1 -2
- package/account/i18n/messages_defaultSet/de.js +38 -39
- package/account/i18n/messages_defaultSet/de.js.map +1 -1
- package/account/i18n/messages_defaultSet/en.d.ts +0 -4
- package/account/i18n/messages_defaultSet/en.js +0 -4
- package/account/i18n/messages_defaultSet/en.js.map +1 -1
- package/account/i18n/messages_defaultSet/es.d.ts +0 -231
- package/account/i18n/messages_defaultSet/es.js +0 -231
- package/account/i18n/messages_defaultSet/es.js.map +1 -1
- package/account/i18n/messages_defaultSet/fi.d.ts +0 -1
- package/account/i18n/messages_defaultSet/fi.js +0 -1
- package/account/i18n/messages_defaultSet/fi.js.map +1 -1
- package/account/i18n/messages_defaultSet/fr.d.ts +0 -6
- package/account/i18n/messages_defaultSet/fr.js +1 -7
- package/account/i18n/messages_defaultSet/fr.js.map +1 -1
- package/account/i18n/messages_defaultSet/hu.d.ts +0 -69
- package/account/i18n/messages_defaultSet/hu.js +24 -93
- package/account/i18n/messages_defaultSet/hu.js.map +1 -1
- package/account/i18n/messages_defaultSet/index.d.ts +134 -428
- package/account/i18n/messages_defaultSet/index.js +0 -4
- package/account/i18n/messages_defaultSet/index.js.map +1 -1
- package/account/i18n/messages_defaultSet/it.d.ts +0 -6
- package/account/i18n/messages_defaultSet/it.js +0 -6
- package/account/i18n/messages_defaultSet/it.js.map +1 -1
- package/account/i18n/messages_defaultSet/ja.d.ts +0 -1
- package/account/i18n/messages_defaultSet/ja.js +0 -1
- package/account/i18n/messages_defaultSet/ja.js.map +1 -1
- package/account/i18n/messages_defaultSet/lt.d.ts +0 -1
- package/account/i18n/messages_defaultSet/lt.js +0 -1
- package/account/i18n/messages_defaultSet/lt.js.map +1 -1
- package/account/i18n/messages_defaultSet/lv.d.ts +0 -1
- package/account/i18n/messages_defaultSet/lv.js +0 -1
- package/account/i18n/messages_defaultSet/lv.js.map +1 -1
- package/account/i18n/messages_defaultSet/nl.d.ts +0 -1
- package/account/i18n/messages_defaultSet/nl.js +0 -1
- package/account/i18n/messages_defaultSet/nl.js.map +1 -1
- package/account/i18n/messages_defaultSet/no.d.ts +0 -1
- package/account/i18n/messages_defaultSet/no.js +0 -1
- package/account/i18n/messages_defaultSet/no.js.map +1 -1
- package/account/i18n/messages_defaultSet/pl.d.ts +0 -115
- package/account/i18n/messages_defaultSet/pl.js +0 -115
- package/account/i18n/messages_defaultSet/pl.js.map +1 -1
- package/account/i18n/messages_defaultSet/pt-BR.d.ts +0 -1
- package/account/i18n/messages_defaultSet/pt-BR.js +0 -1
- package/account/i18n/messages_defaultSet/pt-BR.js.map +1 -1
- package/account/i18n/messages_defaultSet/ru.d.ts +0 -1
- package/account/i18n/messages_defaultSet/ru.js +0 -1
- package/account/i18n/messages_defaultSet/ru.js.map +1 -1
- package/account/i18n/messages_defaultSet/sk.d.ts +0 -1
- package/account/i18n/messages_defaultSet/sk.js +0 -1
- package/account/i18n/messages_defaultSet/sk.js.map +1 -1
- package/account/i18n/messages_defaultSet/sv.d.ts +0 -1
- package/account/i18n/messages_defaultSet/sv.js +0 -1
- package/account/i18n/messages_defaultSet/sv.js.map +1 -1
- package/account/i18n/messages_defaultSet/tr.d.ts +1 -2
- package/account/i18n/messages_defaultSet/tr.js +1 -2
- package/account/i18n/messages_defaultSet/tr.js.map +1 -1
- package/account/i18n/messages_defaultSet/zh-CN.d.ts +0 -11
- package/account/i18n/messages_defaultSet/zh-CN.js +0 -11
- package/account/i18n/messages_defaultSet/zh-CN.js.map +1 -1
- package/account/i18n/useI18n.d.ts +2 -2
- package/bin/193.index.js +1 -1
- package/bin/31.index.js +6 -4
- package/bin/{622.index.js → 365.index.js} +76 -47
- package/bin/440.index.js +3 -20
- package/bin/932.index.js +1 -1
- package/bin/main.js +3 -3
- package/bin/shared/buildContext.js.map +1 -1
- package/bin/shared/constants.d.ts +2 -2
- package/bin/shared/constants.js +4 -2
- package/bin/shared/constants.js.map +1 -1
- package/login/DefaultPage.js +6 -0
- package/login/DefaultPage.js.map +1 -1
- package/login/KcContext/KcContext.d.ts +32 -1
- package/login/KcContext/KcContext.js.map +1 -1
- package/login/KcContext/getKcContextMock.d.ts +1 -1
- package/login/KcContext/kcContextMocks.d.ts +1 -1
- package/login/KcContext/kcContextMocks.js +5 -1
- package/login/KcContext/kcContextMocks.js.map +1 -1
- package/login/i18n/i18n.d.ts +2 -2
- package/login/i18n/messages_defaultSet/ca.d.ts +0 -23
- package/login/i18n/messages_defaultSet/ca.js +0 -23
- package/login/i18n/messages_defaultSet/ca.js.map +1 -1
- package/login/i18n/messages_defaultSet/cs.d.ts +1 -0
- package/login/i18n/messages_defaultSet/cs.js +16 -15
- package/login/i18n/messages_defaultSet/cs.js.map +1 -1
- package/login/i18n/messages_defaultSet/da.d.ts +0 -2
- package/login/i18n/messages_defaultSet/da.js +0 -2
- package/login/i18n/messages_defaultSet/da.js.map +1 -1
- package/login/i18n/messages_defaultSet/de.d.ts +83 -2
- package/login/i18n/messages_defaultSet/de.js +107 -26
- package/login/i18n/messages_defaultSet/de.js.map +1 -1
- package/login/i18n/messages_defaultSet/el.d.ts +0 -23
- package/login/i18n/messages_defaultSet/el.js +0 -23
- package/login/i18n/messages_defaultSet/el.js.map +1 -1
- package/login/i18n/messages_defaultSet/en.d.ts +19 -25
- package/login/i18n/messages_defaultSet/en.js +19 -25
- package/login/i18n/messages_defaultSet/en.js.map +1 -1
- package/login/i18n/messages_defaultSet/es.d.ts +0 -24
- package/login/i18n/messages_defaultSet/es.js +0 -24
- package/login/i18n/messages_defaultSet/es.js.map +1 -1
- package/login/i18n/messages_defaultSet/fa.d.ts +0 -23
- package/login/i18n/messages_defaultSet/fa.js +0 -23
- package/login/i18n/messages_defaultSet/fa.js.map +1 -1
- package/login/i18n/messages_defaultSet/hu.d.ts +0 -23
- package/login/i18n/messages_defaultSet/hu.js +0 -23
- package/login/i18n/messages_defaultSet/hu.js.map +1 -1
- package/login/i18n/messages_defaultSet/index.d.ts +96 -941
- package/login/i18n/messages_defaultSet/index.js +3 -0
- package/login/i18n/messages_defaultSet/index.js.map +1 -1
- package/login/i18n/messages_defaultSet/it.d.ts +0 -1
- package/login/i18n/messages_defaultSet/it.js +0 -1
- package/login/i18n/messages_defaultSet/it.js.map +1 -1
- package/login/i18n/messages_defaultSet/ka.d.ts +468 -0
- package/login/i18n/messages_defaultSet/ka.js +473 -0
- package/login/i18n/messages_defaultSet/ka.js.map +1 -0
- package/login/i18n/messages_defaultSet/pt-BR.d.ts +1 -0
- package/login/i18n/messages_defaultSet/pt-BR.js +3 -2
- package/login/i18n/messages_defaultSet/pt-BR.js.map +1 -1
- package/login/i18n/messages_defaultSet/pt.d.ts +448 -0
- package/login/i18n/messages_defaultSet/pt.js +453 -0
- package/login/i18n/messages_defaultSet/pt.js.map +1 -0
- package/login/i18n/messages_defaultSet/sk.d.ts +1 -0
- package/login/i18n/messages_defaultSet/sk.js +16 -15
- package/login/i18n/messages_defaultSet/sk.js.map +1 -1
- package/login/i18n/messages_defaultSet/zh-CN.d.ts +0 -24
- package/login/i18n/messages_defaultSet/zh-CN.js +0 -24
- package/login/i18n/messages_defaultSet/zh-CN.js.map +1 -1
- package/login/i18n/messages_defaultSet/zh-TW.d.ts +453 -0
- package/login/i18n/messages_defaultSet/zh-TW.js +458 -0
- package/login/i18n/messages_defaultSet/zh-TW.js.map +1 -0
- package/login/i18n/useI18n.d.ts +2 -2
- package/login/pages/Login.js +3 -3
- package/login/pages/Login.js.map +1 -1
- package/login/pages/LoginIdpLinkConfirmOverride.d.ts +7 -0
- package/login/pages/LoginIdpLinkConfirmOverride.js +14 -0
- package/login/pages/LoginIdpLinkConfirmOverride.js.map +1 -0
- package/login/pages/LoginPasskeysConditionalAuthenticate.d.ts +7 -0
- package/login/pages/LoginPasskeysConditionalAuthenticate.js +80 -0
- package/login/pages/LoginPasskeysConditionalAuthenticate.js.map +1 -0
- package/login/pages/LoginUsername.js +3 -3
- package/login/pages/LoginUsername.js.map +1 -1
- package/package.json +28 -21
- package/src/account/i18n/messages_defaultSet/ar.ts +1 -2
- package/src/account/i18n/messages_defaultSet/ca.ts +76 -305
- package/src/account/i18n/messages_defaultSet/cs.ts +0 -1
- package/src/account/i18n/messages_defaultSet/da.ts +0 -1
- package/src/account/i18n/messages_defaultSet/de.ts +38 -39
- package/src/account/i18n/messages_defaultSet/en.ts +0 -4
- package/src/account/i18n/messages_defaultSet/es.ts +0 -231
- package/src/account/i18n/messages_defaultSet/fi.ts +0 -1
- package/src/account/i18n/messages_defaultSet/fr.ts +1 -7
- package/src/account/i18n/messages_defaultSet/hu.ts +24 -93
- package/src/account/i18n/messages_defaultSet/index.ts +0 -4
- package/src/account/i18n/messages_defaultSet/it.ts +0 -6
- package/src/account/i18n/messages_defaultSet/ja.ts +0 -1
- package/src/account/i18n/messages_defaultSet/lt.ts +0 -1
- package/src/account/i18n/messages_defaultSet/lv.ts +0 -1
- package/src/account/i18n/messages_defaultSet/nl.ts +0 -1
- package/src/account/i18n/messages_defaultSet/no.ts +0 -1
- package/src/account/i18n/messages_defaultSet/pl.ts +0 -115
- package/src/account/i18n/messages_defaultSet/pt-BR.ts +0 -1
- package/src/account/i18n/messages_defaultSet/ru.ts +0 -1
- package/src/account/i18n/messages_defaultSet/sk.ts +0 -1
- package/src/account/i18n/messages_defaultSet/sv.ts +0 -1
- package/src/account/i18n/messages_defaultSet/tr.ts +1 -2
- package/src/account/i18n/messages_defaultSet/zh-CN.ts +0 -11
- package/src/bin/keycloakify/buildJars/buildJar.ts +0 -19
- package/src/bin/shared/buildContext.ts +2 -2
- package/src/bin/shared/constants.ts +4 -2
- package/src/bin/shared/{downloadKeycloakDefaultTheme.ts → downloadKeycloakDefaultTheme/downloadKeycloakDefaultTheme.ts} +46 -6
- package/src/bin/shared/downloadKeycloakDefaultTheme/extra-assets/passkeysConditionalAuth.js +79 -0
- package/src/bin/shared/downloadKeycloakDefaultTheme/extra-assets/webauthnAuthenticate.js +82 -0
- package/src/bin/shared/downloadKeycloakDefaultTheme/index.ts +1 -0
- package/src/login/DefaultPage.tsx +6 -0
- package/src/login/KcContext/KcContext.ts +37 -1
- package/src/login/KcContext/kcContextMocks.ts +33 -0
- package/src/login/i18n/messages_defaultSet/ca.ts +0 -23
- package/src/login/i18n/messages_defaultSet/cs.ts +16 -15
- package/src/login/i18n/messages_defaultSet/da.ts +0 -2
- package/src/login/i18n/messages_defaultSet/de.ts +107 -26
- package/src/login/i18n/messages_defaultSet/el.ts +0 -23
- package/src/login/i18n/messages_defaultSet/en.ts +19 -25
- package/src/login/i18n/messages_defaultSet/es.ts +0 -24
- package/src/login/i18n/messages_defaultSet/fa.ts +0 -23
- package/src/login/i18n/messages_defaultSet/hu.ts +0 -23
- package/src/login/i18n/messages_defaultSet/index.ts +3 -0
- package/src/login/i18n/messages_defaultSet/it.ts +0 -1
- package/src/login/i18n/messages_defaultSet/ka.ts +474 -0
- package/src/login/i18n/messages_defaultSet/pt-BR.ts +3 -2
- package/src/login/i18n/messages_defaultSet/pt.ts +454 -0
- package/src/login/i18n/messages_defaultSet/sk.ts +16 -15
- package/src/login/i18n/messages_defaultSet/zh-CN.ts +0 -24
- package/src/login/i18n/messages_defaultSet/zh-TW.ts +459 -0
- package/src/login/pages/Login.tsx +1 -1
- package/src/login/pages/LoginIdpLinkConfirmOverride.tsx +40 -0
- package/src/login/pages/LoginPasskeysConditionalAuthenticate.tsx +252 -0
- package/src/login/pages/LoginUsername.tsx +1 -1
- package/stories/login/pages/LoginIdpLinkConfirmOverride.stories.tsx +18 -0
- package/stories/login/pages/LoginPasskeysConditionalAuthenticate.stories.tsx +18 -0
- package/vite-plugin/index.js +46 -25
- package/account/i18n/messages_defaultSet/el.d.ts +0 -360
- package/account/i18n/messages_defaultSet/el.js +0 -365
- package/account/i18n/messages_defaultSet/el.js.map +0 -1
- package/account/i18n/messages_defaultSet/fa.d.ts +0 -361
- package/account/i18n/messages_defaultSet/fa.js +0 -366
- package/account/i18n/messages_defaultSet/fa.js.map +0 -1
- package/account/i18n/messages_defaultSet/th.d.ts +0 -339
- package/account/i18n/messages_defaultSet/th.js +0 -344
- package/account/i18n/messages_defaultSet/th.js.map +0 -1
- package/account/i18n/messages_defaultSet/uk.d.ts +0 -339
- package/account/i18n/messages_defaultSet/uk.js +0 -344
- package/account/i18n/messages_defaultSet/uk.js.map +0 -1
- package/bin/shared/downloadKeycloakDefaultTheme.d.ts +0 -11
- package/bin/shared/downloadKeycloakDefaultTheme.js.map +0 -1
- package/src/account/i18n/messages_defaultSet/el.ts +0 -366
- package/src/account/i18n/messages_defaultSet/fa.ts +0 -367
- package/src/account/i18n/messages_defaultSet/th.ts +0 -345
- package/src/account/i18n/messages_defaultSet/uk.ts +0 -345
@@ -1,8 +1,10 @@
|
|
1
|
-
import { join as pathJoin, relative as pathRelative } from "path";
|
2
|
-
import { type BuildContext } from "
|
1
|
+
import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path";
|
2
|
+
import { type BuildContext } from "../buildContext";
|
3
3
|
import { assert } from "tsafe/assert";
|
4
|
-
import { LAST_KEYCLOAK_VERSION_WITH_ACCOUNT_V1 } from "
|
5
|
-
import { downloadAndExtractArchive } from "
|
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,42 @@ 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
|
+
__dirname.split(`${pathSep}bin${pathSep}`)[1],
|
189
|
+
"extra-assets"
|
190
|
+
);
|
191
|
+
|
192
|
+
await Promise.all(
|
193
|
+
["webauthnAuthenticate.js", "passkeysConditionalAuth.js"].map(
|
194
|
+
async fileBasename =>
|
195
|
+
writeFile({
|
196
|
+
fileRelativePath: pathJoin(
|
197
|
+
"base",
|
198
|
+
"login",
|
199
|
+
"resources",
|
200
|
+
"js",
|
201
|
+
fileBasename
|
202
|
+
),
|
203
|
+
modifiedData: await fsPr.readFile(
|
204
|
+
pathJoin(extraAssetsDirPath, fileBasename)
|
205
|
+
)
|
206
|
+
})
|
207
|
+
)
|
208
|
+
);
|
209
|
+
}
|
210
|
+
|
171
211
|
skip_unused_resources: {
|
172
212
|
if (keycloakVersion !== "24.0.4") {
|
173
213
|
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": "« 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": "
|
400
|
-
"webauthn-help-text": "Použijte k přihlášení
|
401
|
-
"webauthn-passwordless-display-name": "
|
402
|
-
"webauthn-passwordless-help-text": "Použijte
|
403
|
-
"webauthn-login-title": "Přihlášení
|
404
|
-
"webauthn-registration-title": "Registrace
|
405
|
-
"webauthn-available-authenticators": "Dostupné
|
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í
|
407
|
+
"webauthn-doAuthenticate": "Přihlášení přístupovým klíčem",
|
408
408
|
"webauthn-createdAt-label": "Vytvořeno",
|
409
|
-
"webauthn-error-title": "Chyba
|
410
|
-
"webauthn-error-registration": "Selhala registrace vašeho
|
411
|
-
"webauthn-error-api-get": "Selhalo přihlášení pomocí
|
412
|
-
"webauthn-error-different-user": "První přihlášený uživatel není totožný s uživatelem přihlášeným pomocí
|
413
|
-
"webauthn-error-auth-verification": "Nevalidní výsledek přihlášení pomocí
|
414
|
-
"webauthn-error-register-verification": "Nevalidní výsledek registrace
|
415
|
-
"webauthn-error-user-not-found": "Neznámý uživatel přihlášen pomocí
|
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",
|