-
+ )}
+
- )}
-
-
- }
- />
- );
-});
+
+ }
+ />
+ );
+ }
+);
export default Register;
diff --git a/src/lib/components/RegisterUserProfile.tsx b/src/lib/components/RegisterUserProfile.tsx
index 4951dd51..50485cae 100644
--- a/src/lib/components/RegisterUserProfile.tsx
+++ b/src/lib/components/RegisterUserProfile.tsx
@@ -6,62 +6,73 @@ import { useCssAndCx } from "../tools/useCssAndCx";
import type { I18n } from "../i18n";
import { UserProfileFormFields } from "./shared/UserProfileCommons";
-const RegisterUserProfile = memo(({ kcContext, i18n, ...props_ }: { kcContext: KcContextBase.RegisterUserProfile; i18n: I18n } & KcProps) => {
- const { url, messagesPerField, recaptchaRequired, recaptchaSiteKey } = kcContext;
+const RegisterUserProfile = memo(
+ ({
+ kcContext,
+ i18n,
+ doFetchDefaultThemeResources = true,
+ ...props_
+ }: { kcContext: KcContextBase.RegisterUserProfile; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
+ const { url, messagesPerField, recaptchaRequired, recaptchaSiteKey } = kcContext;
- const { msg, msgStr } = i18n;
+ const { msg, msgStr } = i18n;
- const { cx, css } = useCssAndCx();
+ const { cx, css } = useCssAndCx();
- const props = useMemo(
- () => ({
- ...props_,
- "kcFormGroupClass": cx(props_.kcFormGroupClass, css({ "marginBottom": 20 }))
- }),
- [cx, css]
- );
+ const props = useMemo(
+ () => ({
+ ...props_,
+ "kcFormGroupClass": cx(props_.kcFormGroupClass, css({ "marginBottom": 20 }))
+ }),
+ [cx, css]
+ );
- const [isFomSubmittable, setIsFomSubmittable] = useState(false);
+ const [isFomSubmittable, setIsFomSubmittable] = useState(false);
- return (
-
-
- {recaptchaRequired && (
-
-
-
+ return (
+
+
+ {recaptchaRequired && (
+
+ )}
+
- )}
-
-
- }
- />
- );
-});
+
+ }
+ />
+ );
+ }
+);
export default RegisterUserProfile;
diff --git a/src/lib/components/Terms.tsx b/src/lib/components/Terms.tsx
index 8c3dd523..53eb0214 100644
--- a/src/lib/components/Terms.tsx
+++ b/src/lib/components/Terms.tsx
@@ -54,55 +54,61 @@ export function useDownloadTerms(params: {
}, []);
}
-const Terms = memo(({ kcContext, i18n, ...props }: { kcContext: KcContextBase.Terms; i18n: I18n } & KcProps) => {
- const { msg, msgStr } = i18n;
+const Terms = memo(
+ ({
+ kcContext,
+ i18n,
+ doFetchDefaultThemeResources = true,
+ ...props
+ }: { kcContext: KcContextBase.Terms; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
+ const { msg, msgStr } = i18n;
- useRerenderOnStateChange(evtTermMarkdown);
+ useRerenderOnStateChange(evtTermMarkdown);
- const { cx } = useCssAndCx();
+ const { cx } = useCssAndCx();
- const { url } = kcContext;
+ const { url } = kcContext;
- if (evtTermMarkdown.state === undefined) {
- return null;
+ if (evtTermMarkdown.state === undefined) {
+ return null;
+ }
+
+ return (
+
+ {evtTermMarkdown.state && {evtTermMarkdown.state}}
+
+
+ >
+ }
+ />
+ );
}
-
- return (
-
- {evtTermMarkdown.state && {evtTermMarkdown.state}}
-
-
- >
- }
- />
- );
-});
+);
export default Terms;
diff --git a/src/lib/components/UpdateUserProfile.tsx b/src/lib/components/UpdateUserProfile.tsx
index 1be663e3..ca02dc4e 100644
--- a/src/lib/components/UpdateUserProfile.tsx
+++ b/src/lib/components/UpdateUserProfile.tsx
@@ -6,66 +6,72 @@ import { useCssAndCx } from "../tools/useCssAndCx";
import type { I18n } from "../i18n";
import { UserProfileFormFields } from "./shared/UserProfileCommons";
-const UpdateUserProfile = memo(({ kcContext, i18n, ...props }: { kcContext: KcContextBase.UpdateUserProfile; i18n: I18n } & KcProps) => {
- const { cx } = useCssAndCx();
+const UpdateUserProfile = memo(
+ ({
+ kcContext,
+ i18n,
+ doFetchDefaultThemeResources = true,
+ ...props
+ }: { kcContext: KcContextBase.UpdateUserProfile; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
+ const { cx } = useCssAndCx();
- const { msg, msgStr } = i18n;
+ const { msg, msgStr } = i18n;
- const { url, isAppInitiatedAction } = kcContext;
+ const { url, isAppInitiatedAction } = kcContext;
- const [isFomSubmittable, setIsFomSubmittable] = useState(false);
+ const [isFomSubmittable, setIsFomSubmittable] = useState(false);
- return (
-
-
+ return (
+
+
-
-
+
-
- }
- />
- );
-});
+
+ }
+ />
+ );
+ }
+);
export default UpdateUserProfile;
From 213224942f6c82b6aa2f27e3719032d1965ea5e4 Mon Sep 17 00:00:00 2001
From: garronej
Date: Tue, 27 Sep 2022 21:35:16 +0200
Subject: [PATCH 40/77] Bump version
---
README.md | 6 ++++++
package.json | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 38eb42c8..1a55c3e0 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,12 @@
# Changelog highlights
+## 6.4.0
+
+- You can now optionally pass a `doFetchDefaultThemeResources: boolean` prop to every page component and the default ``
+ This enables you to prevent the default CSS and JS that comes with the builtin Keycloak theme to be downloaded.
+ You'll get [a black slate](https://user-images.githubusercontent.com/6702424/192619083-4baa5df4-4a21-4ec7-8e28-d200d1208299.png).
+
## 6.0.0
- Bundle size drastically reduced, locals and component dynamically loaded.
diff --git a/package.json b/package.json
index 3f8d7513..eead31d7 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.3.5",
+ "version": "6.4.0",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
From 1ff79ecf0780b9421bc9f6acfc3d7325e995a45f Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 28 Sep 2022 04:32:39 +0000
Subject: [PATCH 41/77] Update garronej_modules_update
---
package.json | 10 +++++-----
yarn.lock | 38 +++++++++++++++++++-------------------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/package.json b/package.json
index 9a96239d..4c51e99f 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.4.0",
+ "version": "6.4.1",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -77,16 +77,16 @@
"@octokit/rest": "^18.12.0",
"cheerio": "^1.0.0-rc.5",
"cli-select": "^1.1.2",
- "evt": "^2.4.2",
+ "evt": "^2.4.3",
"memoizee": "^0.4.15",
"minimal-polyfills": "^2.2.2",
"minimist": "^1.2.6",
"path-browserify": "^1.0.1",
- "powerhooks": "^0.20.17",
+ "powerhooks": "^0.20.18",
"react-markdown": "^5.0.3",
"scripting-tools": "^0.19.13",
- "tsafe": "^1.0.1",
- "tss-react": "^4.1.3",
+ "tsafe": "^1.1.0",
+ "tss-react": "^4.1.4",
"zod": "^3.17.10"
}
}
diff --git a/yarn.lock b/yarn.lock
index 09d1190d..306fc84d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -748,14 +748,14 @@ event-emitter@^0.3.5:
d "1"
es5-ext "~0.10.14"
-evt@^2.4.2:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/evt/-/evt-2.4.2.tgz#8f29f53a71609f1f5ad09ba313ad8cc0b9c63077"
- integrity sha512-wPGX4eGgxh5NRff+1VkRfdTRaJA5vbr9rC9CRUIgprVDGDFtI0/vF9I0Yp3HAEGuFbUO978QAsaH6lIgpRCFAg==
+evt@^2.4.3:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/evt/-/evt-2.4.3.tgz#c70dab423135ade17de8152ea988fc8ef81f4513"
+ integrity sha512-mjvab7nRg3NnioKh9MKs5ajPlBjvrQ+dOTkDPzExpZFnzC9sebVOu7NsRj8xd1WfL02iih1rIYUVz6+Hr2F/Lg==
dependencies:
minimal-polyfills "^2.2.2"
run-exclusive "^2.2.16"
- tsafe "^1.0.1"
+ tsafe "^1.1.0"
execa@^5.1.1:
version "5.1.1"
@@ -1385,15 +1385,15 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
-powerhooks@^0.20.17:
- version "0.20.17"
- resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.17.tgz#bf9fd0c4a7f21a61aabbfc249a6d631cd1c06006"
- integrity sha512-c65WYqmSmjFQBLIgHN5nHDryVSU3ARII2C8nNX2cOYFsvzp+MvQJSAP1i1159U9RvuP1iayuUiQRk4nVwZYSlg==
+powerhooks@^0.20.18:
+ version "0.20.18"
+ resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.18.tgz#8d0fe7527d7f43ab8e83587dc6a1e192e3269a52"
+ integrity sha512-oI+WTQu4obdrB8Yjb2Nvcuh4Dyj0ParA8Iq14QCO9VpGGPg1CSl7Zb/Yi5IOpfPis3TZHHMwCUcSIhHNnAkqjQ==
dependencies:
- evt "^2.4.2"
+ evt "^2.4.3"
memoizee "^0.4.15"
resize-observer-polyfill "^1.5.1"
- tsafe "^1.0.1"
+ tsafe "^1.1.0"
prettier@^2.3.0:
version "2.7.1"
@@ -1733,20 +1733,20 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
-tsafe@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.0.1.tgz#c8c4eb2d75d1478418a4941307c5dd667fd76d23"
- integrity sha512-FgJ1a4rE7YbmW5QIzpsfFl4tsAp0x74FH2bVE6qODb2U8jSrwTr5/ckIazeylme5zXndVbtgKm4BZdqmoGhiPw==
+tsafe@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.0.tgz#3fa2f5a902803fccc8d3a0e28ff8154e0380cffa"
+ integrity sha512-u+dbgaG/D3ej1AGZYOe6pb7eDLhn+cmuw1Vx2pnj62PklH/yj+RN1DOxe18ncbZSu91IXmE8LrrGbwByNmuGvw==
tslib@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
-tss-react@^4.1.3:
- version "4.1.3"
- resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.1.3.tgz#170a2edd85e32ba3b752416eeb45438c35e90243"
- integrity sha512-Ul99aVoVngHY2nwFC87jZlGP+K3LfG9ZRakimOzRwgJz77f/zXWuY2FVzwaSc+OW804twNaxZZRtLlpagex8sg==
+tss-react@^4.1.4:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.1.4.tgz#de049875e0fb3b0a28ec09a1faf8b326d621df15"
+ integrity sha512-/dg3SrbvIZX6pjzVYhsvMBxEKe1W3TFmbzxR0y4X3J2xA1tc5DOsenQHNodWVZ6cE3EHUjb3dLm4tVvkVe/SNw==
dependencies:
"@emotion/cache" "*"
"@emotion/serialize" "*"
From a4ac9fb0f3f7eb0a667c1bd7dddf2a8af592bd95 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 30 Sep 2022 14:04:34 +0000
Subject: [PATCH 42/77] Update garronej_modules_update
---
package.json | 10 +++++-----
yarn.lock | 38 +++++++++++++++++++-------------------
2 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/package.json b/package.json
index 4c51e99f..d6a3f7c2 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.4.1",
+ "version": "6.4.2",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -77,16 +77,16 @@
"@octokit/rest": "^18.12.0",
"cheerio": "^1.0.0-rc.5",
"cli-select": "^1.1.2",
- "evt": "^2.4.3",
+ "evt": "^2.4.4",
"memoizee": "^0.4.15",
"minimal-polyfills": "^2.2.2",
"minimist": "^1.2.6",
"path-browserify": "^1.0.1",
- "powerhooks": "^0.20.18",
+ "powerhooks": "^0.20.20",
"react-markdown": "^5.0.3",
"scripting-tools": "^0.19.13",
- "tsafe": "^1.1.0",
- "tss-react": "^4.1.4",
+ "tsafe": "^1.1.1",
+ "tss-react": "^4.2.0",
"zod": "^3.17.10"
}
}
diff --git a/yarn.lock b/yarn.lock
index 306fc84d..caf55db6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -748,14 +748,14 @@ event-emitter@^0.3.5:
d "1"
es5-ext "~0.10.14"
-evt@^2.4.3:
- version "2.4.3"
- resolved "https://registry.yarnpkg.com/evt/-/evt-2.4.3.tgz#c70dab423135ade17de8152ea988fc8ef81f4513"
- integrity sha512-mjvab7nRg3NnioKh9MKs5ajPlBjvrQ+dOTkDPzExpZFnzC9sebVOu7NsRj8xd1WfL02iih1rIYUVz6+Hr2F/Lg==
+evt@^2.4.4:
+ version "2.4.4"
+ resolved "https://registry.yarnpkg.com/evt/-/evt-2.4.4.tgz#37d6e28ccb5b1bc91162fc3d5bcfbeb1ef3191cf"
+ integrity sha512-w/ZYdPCRdSfslOhcQHq7DuYoaU04YZKkFPyBwF8pYmOkRizivpbI0jZ8ffY/jITzbLo7RZ0wxN2dqyi62kyGwg==
dependencies:
minimal-polyfills "^2.2.2"
run-exclusive "^2.2.16"
- tsafe "^1.1.0"
+ tsafe "^1.1.1"
execa@^5.1.1:
version "5.1.1"
@@ -1385,15 +1385,15 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
-powerhooks@^0.20.18:
- version "0.20.18"
- resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.18.tgz#8d0fe7527d7f43ab8e83587dc6a1e192e3269a52"
- integrity sha512-oI+WTQu4obdrB8Yjb2Nvcuh4Dyj0ParA8Iq14QCO9VpGGPg1CSl7Zb/Yi5IOpfPis3TZHHMwCUcSIhHNnAkqjQ==
+powerhooks@^0.20.20:
+ version "0.20.20"
+ resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.20.tgz#f9b2549710f5166f63d80e07c46c16d6da4c6f78"
+ integrity sha512-98Ymz0bjo5Ds9u273wYz1tdJ51sB1jcyjqGa08mRY5dKumewydA/+71zrFelfgkOLRRhVZ+mWynG6DZ7zOVjrQ==
dependencies:
- evt "^2.4.3"
+ evt "^2.4.4"
memoizee "^0.4.15"
resize-observer-polyfill "^1.5.1"
- tsafe "^1.1.0"
+ tsafe "^1.1.1"
prettier@^2.3.0:
version "2.7.1"
@@ -1733,20 +1733,20 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
-tsafe@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.0.tgz#3fa2f5a902803fccc8d3a0e28ff8154e0380cffa"
- integrity sha512-u+dbgaG/D3ej1AGZYOe6pb7eDLhn+cmuw1Vx2pnj62PklH/yj+RN1DOxe18ncbZSu91IXmE8LrrGbwByNmuGvw==
+tsafe@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.1.tgz#8d6998c726f8c63c518e1d1e283bbcd282a2b9a9"
+ integrity sha512-Ogblm3uh0dVupcCcC4IT641rnSQ7CW9IO0q8yIncG8OBe4DDXEqGtUE8LWf7+0MK1qZGeWPWEqSxlLzY2xzREA==
tslib@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
-tss-react@^4.1.4:
- version "4.1.4"
- resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.1.4.tgz#de049875e0fb3b0a28ec09a1faf8b326d621df15"
- integrity sha512-/dg3SrbvIZX6pjzVYhsvMBxEKe1W3TFmbzxR0y4X3J2xA1tc5DOsenQHNodWVZ6cE3EHUjb3dLm4tVvkVe/SNw==
+tss-react@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.2.0.tgz#6738d07177a2782553ee25a758aeafa20378ca91"
+ integrity sha512-f0ov6IG8voaJpQ2j31leaOBIwZ1eRz2LOmWhdrMm4ERLTuyQm1Lw8VlVrqcqrpa+fP3UuFrwkLnWUARKZp20lg==
dependencies:
"@emotion/cache" "*"
"@emotion/serialize" "*"
From 4d3220820b414552167effcbc2ffad59cf77f9f7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 3 Oct 2022 00:16:38 +0000
Subject: [PATCH 43/77] Update dependency tss-react to ^4.3.3
---
package.json | 4 ++--
yarn.lock | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index d6a3f7c2..a3ac40b3 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.4.2",
+ "version": "6.4.3",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -86,7 +86,7 @@
"react-markdown": "^5.0.3",
"scripting-tools": "^0.19.13",
"tsafe": "^1.1.1",
- "tss-react": "^4.2.0",
+ "tss-react": "^4.3.3",
"zod": "^3.17.10"
}
}
diff --git a/yarn.lock b/yarn.lock
index caf55db6..b2e3cdc2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1743,10 +1743,10 @@ tslib@^2.1.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
-tss-react@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.2.0.tgz#6738d07177a2782553ee25a758aeafa20378ca91"
- integrity sha512-f0ov6IG8voaJpQ2j31leaOBIwZ1eRz2LOmWhdrMm4ERLTuyQm1Lw8VlVrqcqrpa+fP3UuFrwkLnWUARKZp20lg==
+tss-react@^4.3.3:
+ version "4.3.3"
+ resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.3.3.tgz#fca93e91b93a2e52c40dc904c7067a2b1905a160"
+ integrity sha512-gXCocAaCDkLpMy0yYdr6AB9/FAetkiRsFnkoDYhjngMBni6ELyZStUwOmZ/LFdBGzKRFlrtext63J+UaaavgZg==
dependencies:
"@emotion/cache" "*"
"@emotion/serialize" "*"
From e3a0639a0ca07a8cec21835a35b8899c4d44c35b Mon Sep 17 00:00:00 2001
From: Mary Strodl
Date: Tue, 4 Oct 2022 00:35:04 -0400
Subject: [PATCH 44/77] Add `login-username` support
Shown for the "Username Form" login step.
I would also like to work on:
- `login-password.ftl`
- `webauthn-authenticate.ftl`
But first want to see opinions on this!
---
package.json | 1 +
.../keycloakify/generateFtl/generateFtl.ts | 1 +
src/lib/components/KcApp.tsx | 3 +
src/lib/components/LoginUsername.tsx | 168 +++++++++++
src/lib/getKcContext/KcContextBase.ts | 31 ++
.../kcContextMocks/kcContextMocks.ts | 21 ++
yarn.lock | 270 +++++++++++++++++-
7 files changed, 491 insertions(+), 4 deletions(-)
create mode 100644 src/lib/components/LoginUsername.tsx
diff --git a/package.json b/package.json
index d6a3f7c2..75b92642 100755
--- a/package.json
+++ b/package.json
@@ -59,6 +59,7 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"devDependencies": {
+ "@babel/core": "^7.0.0",
"@emotion/react": "^11.4.1",
"@types/memoizee": "^0.4.7",
"@types/minimist": "^1.2.2",
diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts
index 3674f5d8..e1bfb3b9 100644
--- a/src/bin/keycloakify/generateFtl/generateFtl.ts
+++ b/src/bin/keycloakify/generateFtl/generateFtl.ts
@@ -13,6 +13,7 @@ import { Reflect } from "tsafe/Reflect";
// https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/login/freemarker/Templates.java
export const pageIds = [
"login.ftl",
+ "login-username.ftl",
"register.ftl",
"register-user-profile.ftl",
"info.ftl",
diff --git a/src/lib/components/KcApp.tsx b/src/lib/components/KcApp.tsx
index 51f7a662..f18f64cb 100644
--- a/src/lib/components/KcApp.tsx
+++ b/src/lib/components/KcApp.tsx
@@ -13,6 +13,7 @@ const LoginResetPassword = lazy(() => import("./LoginResetPassword"));
const LoginVerifyEmail = lazy(() => import("./LoginVerifyEmail"));
const Terms = lazy(() => import("./Terms"));
const LoginOtp = lazy(() => import("./LoginOtp"));
+const LoginUsername = lazy(() => import("./LoginUsername"));
const LoginUpdatePassword = lazy(() => import("./LoginUpdatePassword"));
const LoginUpdateProfile = lazy(() => import("./LoginUpdateProfile"));
const LoginIdpLinkConfirm = lazy(() => import("./LoginIdpLinkConfirm"));
@@ -67,6 +68,8 @@ const KcApp = memo(
return ;
case "login-otp.ftl":
return ;
+ case "login-username.ftl":
+ return ;
case "login-update-password.ftl":
return ;
case "login-update-profile.ftl":
diff --git a/src/lib/components/LoginUsername.tsx b/src/lib/components/LoginUsername.tsx
new file mode 100644
index 00000000..4c8415a0
--- /dev/null
+++ b/src/lib/components/LoginUsername.tsx
@@ -0,0 +1,168 @@
+import React, { useState, memo } from "react";
+import Template from "./Template";
+import type { KcProps } from "./KcProps";
+import type { KcContextBase } from "../getKcContext/KcContextBase";
+import { useCssAndCx } from "../tools/useCssAndCx";
+import { useConstCallback } from "powerhooks/useConstCallback";
+import type { FormEventHandler } from "react";
+import type { I18n } from "../i18n";
+
+const LoginUsername = memo(
+ ({
+ kcContext,
+ i18n,
+ doFetchDefaultThemeResources = true,
+ ...props
+ }: { kcContext: KcContextBase.LoginUsername; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
+ const { social, realm, url, usernameHidden, login, registrationDisabled } = kcContext;
+
+ const { msg, msgStr } = i18n;
+
+ const { cx } = useCssAndCx();
+
+ const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
+
+ const onSubmit = useConstCallback>(e => {
+ e.preventDefault();
+
+ setIsLoginButtonDisabled(true);
+
+ const formElement = e.target as HTMLFormElement;
+
+ //NOTE: Even if we login with email Keycloak expect username and password in
+ //the POST request.
+ formElement.querySelector("input[name='email']")?.setAttribute("name", "username");
+
+ formElement.submit();
+ });
+
+ return (
+
+
+ {realm.password && social.providers !== undefined && (
+
+
4 && props.kcFormSocialAccountDoubleListClass
+ )}
+ >
+ {social.providers.map(p => (
+ -
+
+ {p.displayName}
+
+
+ ))}
+
+
+ )}
+
+ }
+ infoNode={
+ realm.password &&
+ realm.registrationAllowed &&
+ !registrationDisabled && (
+
+ )
+ }
+ />
+ );
+ }
+);
+
+export default LoginUsername;
diff --git a/src/lib/getKcContext/KcContextBase.ts b/src/lib/getKcContext/KcContextBase.ts
index 0c0f93b3..13c9bdb4 100644
--- a/src/lib/getKcContext/KcContextBase.ts
+++ b/src/lib/getKcContext/KcContextBase.ts
@@ -19,6 +19,7 @@ export type KcContextBase =
| KcContextBase.LoginVerifyEmail
| KcContextBase.Terms
| KcContextBase.LoginOtp
+ | KcContextBase.LoginUsername
| KcContextBase.LoginUpdatePassword
| KcContextBase.LoginUpdateProfile
| KcContextBase.LoginIdpLinkConfirm
@@ -198,6 +199,36 @@ export declare namespace KcContextBase {
};
};
+ export type LoginUsername = Common & {
+ pageId: "login-username.ftl";
+ url: {
+ loginResetCredentialsUrl: string;
+ registrationUrl: string;
+ };
+ realm: {
+ loginWithEmailAllowed: boolean;
+ rememberMe: boolean;
+ password: boolean;
+ resetPasswordAllowed: boolean;
+ registrationAllowed: boolean;
+ };
+ registrationDisabled: boolean;
+ login: {
+ username?: string;
+ rememberMe?: boolean;
+ };
+ usernameHidden?: boolean;
+ social: {
+ displayInfo: boolean;
+ providers?: {
+ loginUrl: string;
+ alias: string;
+ providerId: string;
+ displayName: string;
+ }[];
+ };
+ };
+
export type LoginUpdatePassword = Common & {
pageId: "login-update-password.ftl";
username: string;
diff --git a/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts b/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
index 98db5287..c1bb1749 100644
--- a/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
+++ b/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
@@ -359,6 +359,27 @@ export const kcContextMocks: KcContextBase[] = [
]
}
}),
+ id({
+ ...kcContextCommonMock,
+ "pageId": "login-username.ftl",
+ "url": loginUrl,
+ "realm": {
+ ...kcContextCommonMock.realm,
+ "loginWithEmailAllowed": true,
+ "rememberMe": true,
+ "password": true,
+ "resetPasswordAllowed": true,
+ "registrationAllowed": true
+ },
+ "social": {
+ "displayInfo": true
+ },
+ "usernameHidden": false,
+ "login": {
+ "rememberMe": false
+ },
+ "registrationDisabled": false
+ }),
id({
...kcContextCommonMock,
"pageId": "login-update-password.ftl",
diff --git a/yarn.lock b/yarn.lock
index caf55db6..90782967 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,25 +2,126 @@
# yarn lockfile v1
-"@babel/code-frame@^7.0.0":
+"@ampproject/remapping@^2.1.0":
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
+ integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.1.0"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
dependencies:
"@babel/highlight" "^7.18.6"
-"@babel/helper-module-imports@^7.16.7":
+"@babel/compat-data@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.3.tgz#707b939793f867f5a73b2666e6d9a3396eb03151"
+ integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==
+
+"@babel/core@^7.0.0":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c"
+ integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==
+ dependencies:
+ "@ampproject/remapping" "^2.1.0"
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.19.3"
+ "@babel/helper-compilation-targets" "^7.19.3"
+ "@babel/helper-module-transforms" "^7.19.0"
+ "@babel/helpers" "^7.19.0"
+ "@babel/parser" "^7.19.3"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.3"
+ "@babel/types" "^7.19.3"
+ convert-source-map "^1.7.0"
+ debug "^4.1.0"
+ gensync "^1.0.0-beta.2"
+ json5 "^2.2.1"
+ semver "^6.3.0"
+
+"@babel/generator@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.3.tgz#d7f4d1300485b4547cb6f94b27d10d237b42bf59"
+ integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==
+ dependencies:
+ "@babel/types" "^7.19.3"
+ "@jridgewell/gen-mapping" "^0.3.2"
+ jsesc "^2.5.1"
+
+"@babel/helper-compilation-targets@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca"
+ integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==
+ dependencies:
+ "@babel/compat-data" "^7.19.3"
+ "@babel/helper-validator-option" "^7.18.6"
+ browserslist "^4.21.3"
+ semver "^6.3.0"
+
+"@babel/helper-environment-visitor@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
+ integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
+
+"@babel/helper-function-name@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+ integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
+ dependencies:
+ "@babel/template" "^7.18.10"
+ "@babel/types" "^7.19.0"
+
+"@babel/helper-hoist-variables@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
+ integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
dependencies:
"@babel/types" "^7.18.6"
+"@babel/helper-module-transforms@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
+ integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
+ dependencies:
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-module-imports" "^7.18.6"
+ "@babel/helper-simple-access" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/helper-validator-identifier" "^7.18.6"
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
+
"@babel/helper-plugin-utils@^7.18.6":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f"
integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==
+"@babel/helper-simple-access@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea"
+ integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
+"@babel/helper-split-export-declaration@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
+ integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
+ dependencies:
+ "@babel/types" "^7.18.6"
+
"@babel/helper-string-parser@^7.18.10":
version "7.18.10"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56"
@@ -31,6 +132,25 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
+"@babel/helper-validator-identifier@^7.19.1":
+ version "7.19.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
+ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
+
+"@babel/helper-validator-option@^7.18.6":
+ version "7.18.6"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
+ integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
+
+"@babel/helpers@^7.19.0":
+ version "7.19.0"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18"
+ integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==
+ dependencies:
+ "@babel/template" "^7.18.10"
+ "@babel/traverse" "^7.19.0"
+ "@babel/types" "^7.19.0"
+
"@babel/highlight@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
@@ -40,6 +160,11 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@babel/parser@^7.18.10", "@babel/parser@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a"
+ integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==
+
"@babel/plugin-syntax-jsx@^7.17.12":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0"
@@ -54,6 +179,40 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/template@^7.18.10":
+ version "7.18.10"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
+ integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/parser" "^7.18.10"
+ "@babel/types" "^7.18.10"
+
+"@babel/traverse@^7.19.0", "@babel/traverse@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.3.tgz#3a3c5348d4988ba60884e8494b0592b2f15a04b4"
+ integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==
+ dependencies:
+ "@babel/code-frame" "^7.18.6"
+ "@babel/generator" "^7.19.3"
+ "@babel/helper-environment-visitor" "^7.18.9"
+ "@babel/helper-function-name" "^7.19.0"
+ "@babel/helper-hoist-variables" "^7.18.6"
+ "@babel/helper-split-export-declaration" "^7.18.6"
+ "@babel/parser" "^7.19.3"
+ "@babel/types" "^7.19.3"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
+"@babel/types@^7.18.10", "@babel/types@^7.19.0", "@babel/types@^7.19.3":
+ version "7.19.3"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.3.tgz#fc420e6bbe54880bce6779ffaf315f5e43ec9624"
+ integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==
+ dependencies:
+ "@babel/helper-string-parser" "^7.18.10"
+ "@babel/helper-validator-identifier" "^7.19.1"
+ to-fast-properties "^2.0.0"
+
"@babel/types@^7.18.6":
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.13.tgz#30aeb9e514f4100f7c1cb6e5ba472b30e48f519a"
@@ -152,6 +311,46 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb"
integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==
+"@jridgewell/gen-mapping@^0.1.0":
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
+ integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.0"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+
+"@jridgewell/gen-mapping@^0.3.2":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
+ integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
+ dependencies:
+ "@jridgewell/set-array" "^1.0.1"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+ "@jridgewell/trace-mapping" "^0.3.9"
+
+"@jridgewell/resolve-uri@^3.0.3":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
+ integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
+
+"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
+ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
+
+"@jridgewell/sourcemap-codec@^1.4.10":
+ version "1.4.14"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
+ integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
+
+"@jridgewell/trace-mapping@^0.3.9":
+ version "0.3.15"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774"
+ integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.0.3"
+ "@jridgewell/sourcemap-codec" "^1.4.10"
+
"@octokit/auth-token@^2.4.4":
version "2.5.0"
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.5.0.tgz#27c37ea26c205f28443402477ffd261311f21e36"
@@ -397,11 +596,26 @@ braces@^3.0.2:
dependencies:
fill-range "^7.0.1"
+browserslist@^4.21.3:
+ version "4.21.4"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
+ integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==
+ dependencies:
+ caniuse-lite "^1.0.30001400"
+ electron-to-chromium "^1.4.251"
+ node-releases "^2.0.6"
+ update-browserslist-db "^1.0.9"
+
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+caniuse-lite@^1.0.30001400:
+ version "1.0.30001415"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001415.tgz#fd7ea96e9e94c181a7f56e7571efb43d92b860cc"
+ integrity sha512-ER+PfgCJUe8BqunLGWd/1EY4g8AzQcsDAVzdtMGKVtQEmKAwaFfU6vb7EAVIqTMYsqxBorYZi2+22Iouj/y7GQ==
+
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -549,7 +763,7 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
-convert-source-map@^1.5.0:
+convert-source-map@^1.5.0, convert-source-map@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
@@ -623,7 +837,7 @@ d@1, d@^1.0.1:
es5-ext "^0.10.50"
type "^1.0.1"
-debug@^4.0.0, debug@^4.3.2:
+debug@^4.0.0, debug@^4.1.0, debug@^4.3.2:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -665,6 +879,11 @@ domutils@^3.0.1:
domelementtype "^2.3.0"
domhandler "^5.0.1"
+electron-to-chromium@^1.4.251:
+ version "1.4.271"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.271.tgz#2d9f04f6a53c70e1bb1acfaae9c39f07ca40d290"
+ integrity sha512-BCPBtK07xR1/uY2HFDtl3wK2De66AW4MSiPlLrnPNxKC/Qhccxd59W73654S3y6Rb/k3hmuGJOBnhjfoutetXA==
+
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
@@ -821,6 +1040,11 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+gensync@^1.0.0-beta.2:
+ version "1.0.0-beta.2"
+ resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
+ integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
+
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
@@ -848,6 +1072,11 @@ glob@^7.0.5, glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
+globals@^11.1.0:
+ version "11.12.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
+ integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -1038,11 +1267,21 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+jsesc@^2.5.1:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
+ integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+
json-parse-even-better-errors@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+json5@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
+ integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
+
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -1220,6 +1459,11 @@ node-fetch@^2.6.7:
dependencies:
whatwg-url "^5.0.0"
+node-releases@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
+ integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
+
noms@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859"
@@ -1366,6 +1610,11 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+picocolors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
+ integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+
picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
@@ -1562,6 +1811,11 @@ semver-regex@^3.1.2:
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-3.1.4.tgz#13053c0d4aa11d070a2f2872b6b1e3ae1e1971b4"
integrity sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==
+semver@^6.3.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
@@ -1828,6 +2082,14 @@ untildify@^4.0.0:
resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
+update-browserslist-db@^1.0.9:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18"
+ integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==
+ dependencies:
+ escalade "^3.1.1"
+ picocolors "^1.0.0"
+
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
From 4dde5b6e458b7b0b6c07a6e5067b72841744ceea Mon Sep 17 00:00:00 2001
From: Joseph Garrone
Date: Tue, 4 Oct 2022 18:48:22 +0200
Subject: [PATCH 45/77] Bump version
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 660d8a83..1ab19552 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.4.3",
+ "version": "6.5.0",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
From 6a0a170b17024291b04e760811b4e8c225a1d035 Mon Sep 17 00:00:00 2001
From: Mary Strodl
Date: Tue, 4 Oct 2022 15:01:08 -0400
Subject: [PATCH 46/77] Add support for `login-password.ftl`
---
.../keycloakify/generateFtl/generateFtl.ts | 1 +
src/lib/components/KcApp.tsx | 3 +
src/lib/components/LoginPassword.tsx | 96 +++++++++++++++++++
src/lib/getKcContext/KcContextBase.ts | 24 +++++
.../kcContextMocks/kcContextMocks.ts | 13 +++
5 files changed, 137 insertions(+)
create mode 100644 src/lib/components/LoginPassword.tsx
diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts
index e1bfb3b9..5f7b3263 100644
--- a/src/bin/keycloakify/generateFtl/generateFtl.ts
+++ b/src/bin/keycloakify/generateFtl/generateFtl.ts
@@ -14,6 +14,7 @@ import { Reflect } from "tsafe/Reflect";
export const pageIds = [
"login.ftl",
"login-username.ftl",
+ "login-password.ftl",
"register.ftl",
"register-user-profile.ftl",
"info.ftl",
diff --git a/src/lib/components/KcApp.tsx b/src/lib/components/KcApp.tsx
index f18f64cb..f8be458d 100644
--- a/src/lib/components/KcApp.tsx
+++ b/src/lib/components/KcApp.tsx
@@ -13,6 +13,7 @@ const LoginResetPassword = lazy(() => import("./LoginResetPassword"));
const LoginVerifyEmail = lazy(() => import("./LoginVerifyEmail"));
const Terms = lazy(() => import("./Terms"));
const LoginOtp = lazy(() => import("./LoginOtp"));
+const LoginPassword = lazy(() => import("./LoginPassword"));
const LoginUsername = lazy(() => import("./LoginUsername"));
const LoginUpdatePassword = lazy(() => import("./LoginUpdatePassword"));
const LoginUpdateProfile = lazy(() => import("./LoginUpdateProfile"));
@@ -70,6 +71,8 @@ const KcApp = memo(
return ;
case "login-username.ftl":
return ;
+ case "login-password.ftl":
+ return ;
case "login-update-password.ftl":
return ;
case "login-update-profile.ftl":
diff --git a/src/lib/components/LoginPassword.tsx b/src/lib/components/LoginPassword.tsx
new file mode 100644
index 00000000..2b74cdf0
--- /dev/null
+++ b/src/lib/components/LoginPassword.tsx
@@ -0,0 +1,96 @@
+import React, { useState, memo } from "react";
+import Template from "./Template";
+import type { KcProps } from "./KcProps";
+import type { KcContextBase } from "../getKcContext/KcContextBase";
+import { useCssAndCx } from "../tools/useCssAndCx";
+import { useConstCallback } from "powerhooks/useConstCallback";
+import type { FormEventHandler } from "react";
+import type { I18n } from "../i18n";
+
+const LoginPassword = memo(
+ ({
+ kcContext,
+ i18n,
+ doFetchDefaultThemeResources = true,
+ ...props
+ }: { kcContext: KcContextBase.LoginPassword; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
+ const { realm, url, login } = kcContext;
+
+ const { msg, msgStr } = i18n;
+
+ const { cx } = useCssAndCx();
+
+ const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
+
+ const onSubmit = useConstCallback>(e => {
+ e.preventDefault();
+
+ setIsLoginButtonDisabled(true);
+
+ const formElement = e.target as HTMLFormElement;
+
+ formElement.submit();
+ });
+
+ return (
+
+
+
+ }
+ />
+ );
+ }
+);
+
+export default LoginPassword;
diff --git a/src/lib/getKcContext/KcContextBase.ts b/src/lib/getKcContext/KcContextBase.ts
index 13c9bdb4..53c7a980 100644
--- a/src/lib/getKcContext/KcContextBase.ts
+++ b/src/lib/getKcContext/KcContextBase.ts
@@ -20,6 +20,7 @@ export type KcContextBase =
| KcContextBase.Terms
| KcContextBase.LoginOtp
| KcContextBase.LoginUsername
+ | KcContextBase.LoginPassword
| KcContextBase.LoginUpdatePassword
| KcContextBase.LoginUpdateProfile
| KcContextBase.LoginIdpLinkConfirm
@@ -229,6 +230,29 @@ export declare namespace KcContextBase {
};
};
+ export type LoginPassword = Common & {
+ pageId: "login-password.ftl";
+ url: {
+ loginResetCredentialsUrl: string;
+ registrationUrl: string;
+ };
+ realm: {
+ resetPasswordAllowed: boolean;
+ };
+ auth?: {
+ showUsername?: boolean;
+ showResetCredentials?: boolean;
+ showTryAnotherWayLink?: boolean;
+ attemptedUsername?: string;
+ };
+ social: {
+ displayInfo: boolean;
+ };
+ login: {
+ password?: string;
+ };
+ };
+
export type LoginUpdatePassword = Common & {
pageId: "login-update-password.ftl";
username: string;
diff --git a/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts b/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
index c1bb1749..870d51b6 100644
--- a/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
+++ b/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
@@ -380,6 +380,19 @@ export const kcContextMocks: KcContextBase[] = [
},
"registrationDisabled": false
}),
+ id
({
+ ...kcContextCommonMock,
+ "pageId": "login-password.ftl",
+ "url": loginUrl,
+ "realm": {
+ ...kcContextCommonMock.realm,
+ "resetPasswordAllowed": true
+ },
+ "social": {
+ "displayInfo": false
+ },
+ "login": {}
+ }),
id({
...kcContextCommonMock,
"pageId": "login-update-password.ftl",
From 5fa09152711c958c48455475a1f00618cf0fe3f1 Mon Sep 17 00:00:00 2001
From: garronej
Date: Tue, 4 Oct 2022 21:34:42 +0200
Subject: [PATCH 47/77] Update changelog
---
README.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/README.md b/README.md
index 1a55c3e0..b1aa5c58 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,10 @@
# Changelog highlights
+## 6.5.0
+
+- Add support for `login-username.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/InseeFrLab/keycloakify/pull/183).
+
## 6.4.0
- You can now optionally pass a `doFetchDefaultThemeResources: boolean` prop to every page component and the default ``
From 0c155a7a2e545962783a734db6c8f001e5c0df53 Mon Sep 17 00:00:00 2001
From: garronej
Date: Tue, 4 Oct 2022 21:42:47 +0200
Subject: [PATCH 48/77] Bump version
---
README.md | 4 ++++
package.json | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b1aa5c58..af7a21ac 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,10 @@
# Changelog highlights
+## 6.6.0
+
+- Add support for `login-password.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/InseeFrLab/keycloakify/pull/184).
+
## 6.5.0
- Add support for `login-username.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/InseeFrLab/keycloakify/pull/183).
diff --git a/package.json b/package.json
index 1ab19552..bd98bbac 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.5.0",
+ "version": "6.6.0",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
From ce2c68ecc9948ea58ba0736b0f5b4721e36665ce Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 4 Oct 2022 19:43:22 +0000
Subject: [PATCH 49/77] Update dependency tss-react to ^4.3.4
---
package.json | 4 ++--
yarn.lock | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index bd98bbac..137613c7 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.6.0",
+ "version": "6.6.1",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -87,7 +87,7 @@
"react-markdown": "^5.0.3",
"scripting-tools": "^0.19.13",
"tsafe": "^1.1.1",
- "tss-react": "^4.3.3",
+ "tss-react": "^4.3.4",
"zod": "^3.17.10"
}
}
diff --git a/yarn.lock b/yarn.lock
index daa44a76..c13e3f2a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1997,10 +1997,10 @@ tslib@^2.1.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
-tss-react@^4.3.3:
- version "4.3.3"
- resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.3.3.tgz#fca93e91b93a2e52c40dc904c7067a2b1905a160"
- integrity sha512-gXCocAaCDkLpMy0yYdr6AB9/FAetkiRsFnkoDYhjngMBni6ELyZStUwOmZ/LFdBGzKRFlrtext63J+UaaavgZg==
+tss-react@^4.3.4:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/tss-react/-/tss-react-4.3.4.tgz#1e6d67f963562f4c232ec28ca4d90c8aac3a728b"
+ integrity sha512-PAEB9NxGtW2nEuPDm90WISi4nb9O+bmY/XyDKp17/CoPsoaW3UqaEi+gTjBmA/P65GCRuZhpZniTOkhLcTDQqg==
dependencies:
"@emotion/cache" "*"
"@emotion/serialize" "*"
From 4b3ae58ea78d7b7c7e47625290b110dae5ca73e2 Mon Sep 17 00:00:00 2001
From: Mary Strodl
Date: Wed, 5 Oct 2022 02:40:00 -0400
Subject: [PATCH 50/77] Add support for `webauthn-authenticate.ftl`
Wow! This one sucks. Certainly more in need of review compared to
`login-username.ftl` and `login-password.ftl`...
---
package.json | 1 +
.../keycloakify/generateFtl/generateFtl.ts | 1 +
src/lib/components/KcApp.tsx | 3 +
src/lib/components/KcProps.ts | 10 +
src/lib/components/WebauthnAuthenticate.tsx | 212 ++++++++++++++++++
src/lib/getKcContext/KcContextBase.ts | 30 +++
.../kcContextMocks/kcContextMocks.ts | 21 ++
yarn.lock | 5 +
8 files changed, 283 insertions(+)
create mode 100644 src/lib/components/WebauthnAuthenticate.tsx
diff --git a/package.json b/package.json
index bd98bbac..c7f04841 100755
--- a/package.json
+++ b/package.json
@@ -85,6 +85,7 @@
"path-browserify": "^1.0.1",
"powerhooks": "^0.20.20",
"react-markdown": "^5.0.3",
+ "rfc4648": "^1.5.2",
"scripting-tools": "^0.19.13",
"tsafe": "^1.1.1",
"tss-react": "^4.3.3",
diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts
index 5f7b3263..d600bc60 100644
--- a/src/bin/keycloakify/generateFtl/generateFtl.ts
+++ b/src/bin/keycloakify/generateFtl/generateFtl.ts
@@ -15,6 +15,7 @@ export const pageIds = [
"login.ftl",
"login-username.ftl",
"login-password.ftl",
+ "webauthn-authenticate.ftl",
"register.ftl",
"register-user-profile.ftl",
"info.ftl",
diff --git a/src/lib/components/KcApp.tsx b/src/lib/components/KcApp.tsx
index f8be458d..0a3dbc09 100644
--- a/src/lib/components/KcApp.tsx
+++ b/src/lib/components/KcApp.tsx
@@ -15,6 +15,7 @@ const Terms = lazy(() => import("./Terms"));
const LoginOtp = lazy(() => import("./LoginOtp"));
const LoginPassword = lazy(() => import("./LoginPassword"));
const LoginUsername = lazy(() => import("./LoginUsername"));
+const WebauthnAuthenticate = lazy(() => import("./WebauthnAuthenticate"));
const LoginUpdatePassword = lazy(() => import("./LoginUpdatePassword"));
const LoginUpdateProfile = lazy(() => import("./LoginUpdateProfile"));
const LoginIdpLinkConfirm = lazy(() => import("./LoginIdpLinkConfirm"));
@@ -73,6 +74,8 @@ const KcApp = memo(
return ;
case "login-password.ftl":
return ;
+ case "webauthn-authenticate.ftl":
+ return ;
case "login-update-password.ftl":
return ;
case "login-update-profile.ftl":
diff --git a/src/lib/components/KcProps.ts b/src/lib/components/KcProps.ts
index c38cc5d1..03551616 100644
--- a/src/lib/components/KcProps.ts
+++ b/src/lib/components/KcProps.ts
@@ -84,6 +84,7 @@ export type KcProps = KcPropsGeneric<
| "kcFormSocialAccountDoubleListClass"
| "kcFormSocialAccountListLinkClass"
| "kcWebAuthnKeyIcon"
+ | "kcWebAuthnDefaultIcon"
| "kcFormClass"
| "kcFormGroupErrorClass"
| "kcLabelClass"
@@ -105,12 +106,16 @@ export type KcProps = KcPropsGeneric<
| "kcSrOnlyClass"
| "kcSelectAuthListClass"
| "kcSelectAuthListItemClass"
+ | "kcSelectAuthListItemFillClass"
| "kcSelectAuthListItemInfoClass"
| "kcSelectAuthListItemLeftClass"
| "kcSelectAuthListItemBodyClass"
| "kcSelectAuthListItemDescriptionClass"
| "kcSelectAuthListItemHeadingClass"
| "kcSelectAuthListItemHelpTextClass"
+ | "kcSelectAuthListItemIconPropertyClass"
+ | "kcSelectAuthListItemIconClass"
+ | "kcSelectAuthListItemTitle"
| "kcAuthenticatorDefaultClass"
| "kcAuthenticatorPasswordClass"
| "kcAuthenticatorOTPClass"
@@ -138,6 +143,7 @@ export const defaultKcProps = {
"kcFormSocialAccountDoubleListClass": ["login-pf-social-double-col"],
"kcFormSocialAccountListLinkClass": ["login-pf-social-link"],
"kcWebAuthnKeyIcon": ["pficon", "pficon-key"],
+ "kcWebAuthnDefaultIcon": ["pficon", "pficon-key"],
"kcFormClass": ["form-horizontal"],
"kcFormGroupErrorClass": ["has-error"],
@@ -173,6 +179,10 @@ export const defaultKcProps = {
// css classes for select-authenticator form
"kcSelectAuthListClass": ["list-group", "list-view-pf"],
"kcSelectAuthListItemClass": ["list-group-item", "list-view-pf-stacked"],
+ "kcSelectAuthListItemFillClass": ["pf-l-split__item", "pf-m-fill"],
+ "kcSelectAuthListItemIconPropertyClass": ["fa-2x", "select-auth-box-icon-properties"],
+ "kcSelectAuthListItemIconClass": ["pf-l-split__item", "select-auth-box-icon"],
+ "kcSelectAuthListItemTitle": ["select-auth-box-paragraph"],
"kcSelectAuthListItemInfoClass": ["list-view-pf-main-info"],
"kcSelectAuthListItemLeftClass": ["list-view-pf-left"],
"kcSelectAuthListItemBodyClass": ["list-view-pf-body"],
diff --git a/src/lib/components/WebauthnAuthenticate.tsx b/src/lib/components/WebauthnAuthenticate.tsx
new file mode 100644
index 00000000..b8908d9c
--- /dev/null
+++ b/src/lib/components/WebauthnAuthenticate.tsx
@@ -0,0 +1,212 @@
+import React, { useCallback, useRef, useState, memo } from "react";
+import Template from "./Template";
+import type { KcProps } from "./KcProps";
+import type { KcContextBase } from "../getKcContext/KcContextBase";
+import { useCssAndCx } from "../tools/useCssAndCx";
+import type { I18n, MessageKeyBase } from "../i18n";
+import { base64url } from "rfc4648";
+
+const WebauthnAuthenticate = memo(
+ ({
+ kcContext,
+ i18n,
+ doFetchDefaultThemeResources = true,
+ ...props
+ }: { kcContext: KcContextBase.WebauthnAuthenticate; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
+ const { url } = kcContext;
+
+ const { msg, msgStr } = i18n;
+
+ const { authenticators, challenge, shouldDisplayAuthenticators, userVerification, rpId } = kcContext;
+ const createTimeout = Number(kcContext.createTimeout);
+ const isUserIdentified = kcContext.isUserIdentified == "true";
+
+ const { cx } = useCssAndCx();
+
+ const webAuthnAuthenticate = useCallback(() => {
+ if (!isUserIdentified) {
+ return;
+ }
+ checkAllowCredentials();
+
+ function checkAllowCredentials() {
+ const allowCredentials = authenticators.authenticators.map(
+ authenticator =>
+ ({
+ id: base64url.parse(authenticator.credentialId, { loose: true }),
+ type: "public-key"
+ } as PublicKeyCredentialDescriptor)
+ );
+ doAuthenticate(allowCredentials);
+ }
+ function doAuthenticate(allowCredentials: PublicKeyCredentialDescriptor[]) {
+ // Check if WebAuthn is supported by this browser
+ if (!window.PublicKeyCredential) {
+ setError(msgStr("webauthn-unsupported-browser-text"));
+ submitForm();
+ return;
+ }
+
+ const publicKey: PublicKeyCredentialRequestOptions = {
+ rpId,
+ challenge: base64url.parse(challenge, { loose: true })
+ };
+
+ if (createTimeout !== 0) {
+ publicKey.timeout = createTimeout * 1000;
+ }
+
+ if (allowCredentials.length) {
+ publicKey.allowCredentials = allowCredentials;
+ }
+
+ if (userVerification !== "not specified") {
+ publicKey.userVerification = userVerification;
+ }
+
+ navigator.credentials
+ .get({ publicKey })
+ .then(resultRaw => {
+ if (!resultRaw || resultRaw.type != "public-key") return;
+ const result = resultRaw as PublicKeyCredential;
+ if (!("authenticatorData" in result.response)) return;
+ const response = result.response as AuthenticatorAssertionResponse;
+ let clientDataJSON = response.clientDataJSON;
+ let authenticatorData = response.authenticatorData;
+ let signature = response.signature;
+
+ setClientDataJSON(base64url.stringify(new Uint8Array(clientDataJSON), { pad: false }));
+ setAuthenticatorData(base64url.stringify(new Uint8Array(authenticatorData), { pad: false }));
+ setSignature(base64url.stringify(new Uint8Array(signature), { pad: false }));
+ setCredentialId(result.id);
+ setUserHandle(base64url.stringify(new Uint8Array(response.userHandle!), { pad: false }));
+ submitForm();
+ })
+ .catch(err => {
+ setError(err);
+ submitForm();
+ });
+ }
+ }, [kcContext]);
+
+ const webAuthForm = useRef(null);
+ const submitForm = useCallback(() => {
+ webAuthForm.current!.submit();
+ }, [webAuthForm.current]);
+
+ const [clientDataJSON, setClientDataJSON] = useState("");
+ const [authenticatorData, setAuthenticatorData] = useState("");
+ const [signature, setSignature] = useState("");
+ const [credentialId, setCredentialId] = useState("");
+ const [userHandle, setUserHandle] = useState("");
+ const [error, setError] = useState("");
+
+ return (
+
+
+
+ {authenticators &&
+ (() => (
+
+ ))()}
+ {authenticators &&
+ shouldDisplayAuthenticators &&
+ (() => (
+ <>
+ {authenticators.authenticators.length > 1 && (
+
{msg("webauthn-available-authenticators")}
+ )}
+
+ {authenticators.authenticators.map(authenticator => (
+
+
+
+
+
+
+ {authenticator.label}
+
+
+ {authenticator.transports && authenticator.transports.displayNameProperties.length && (
+
+ {authenticator.transports.displayNameProperties.map(
+ (transport: MessageKeyBase, index: number) => (
+ <>
+ {msg(transport)}
+ {index < authenticator.transports.displayNameProperties.length - 1 && (
+ {", "}
+ )}
+ >
+ )
+ )}
+
+ )}
+
+
+
+ {msg("webauthn-createdAt-label")}
+
+ {authenticator.createdAt}
+
+
+
+
+ ))}
+
+ >
+ ))()}
+
+
+
+
+
+ }
+ />
+ );
+ }
+);
+
+export default WebauthnAuthenticate;
diff --git a/src/lib/getKcContext/KcContextBase.ts b/src/lib/getKcContext/KcContextBase.ts
index 53c7a980..e2290847 100644
--- a/src/lib/getKcContext/KcContextBase.ts
+++ b/src/lib/getKcContext/KcContextBase.ts
@@ -2,6 +2,7 @@ import type { PageId } from "../../bin/keycloakify/generateFtl";
import { assert } from "tsafe/assert";
import type { Equals } from "tsafe";
import type { MessageKeyBase } from "../i18n";
+import type { KcTemplateClassKey } from "../components/KcProps";
type ExtractAfterStartingWith = StrEnum extends `${Prefix}${infer U}` ? U : never;
@@ -20,6 +21,7 @@ export type KcContextBase =
| KcContextBase.Terms
| KcContextBase.LoginOtp
| KcContextBase.LoginUsername
+ | KcContextBase.WebauthnAuthenticate
| KcContextBase.LoginPassword
| KcContextBase.LoginUpdatePassword
| KcContextBase.LoginUpdateProfile
@@ -31,6 +33,16 @@ export type KcContextBase =
| KcContextBase.UpdateUserProfile
| KcContextBase.IdpReviewUserProfile;
+export type WebauthnAuthenticator = {
+ credentialId: string;
+ transports: {
+ iconClass: KcTemplateClassKey;
+ displayNameProperties: MessageKeyBase[];
+ };
+ label: string;
+ createdAt: string;
+};
+
export declare namespace KcContextBase {
export type Common = {
url: {
@@ -253,6 +265,24 @@ export declare namespace KcContextBase {
};
};
+ export type WebauthnAuthenticate = Common & {
+ pageId: "webauthn-authenticate.ftl";
+ authenticators: {
+ authenticators: WebauthnAuthenticator[];
+ };
+ challenge: string;
+ // I hate this:
+ userVerification: UserVerificationRequirement | "not specified";
+ rpId: string;
+ createTimeout: string;
+ isUserIdentified: "true" | "false";
+ shouldDisplayAuthenticators: boolean;
+ social: {
+ displayInfo: boolean;
+ };
+ login: {};
+ };
+
export type LoginUpdatePassword = Common & {
pageId: "login-update-password.ftl";
username: string;
diff --git a/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts b/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
index 870d51b6..8c1271a5 100644
--- a/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
+++ b/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts
@@ -393,6 +393,27 @@ export const kcContextMocks: KcContextBase[] = [
},
"login": {}
}),
+ id({
+ ...kcContextCommonMock,
+ "pageId": "webauthn-authenticate.ftl",
+ "url": loginUrl,
+ "authenticators": {
+ "authenticators": []
+ },
+ "realm": {
+ ...kcContextCommonMock.realm
+ },
+ "challenge": "",
+ "userVerification": "not specified",
+ "rpId": "",
+ "createTimeout": "0",
+ "isUserIdentified": "false",
+ "shouldDisplayAuthenticators": false,
+ "social": {
+ "displayInfo": false
+ },
+ "login": {}
+ }),
id({
...kcContextCommonMock,
"pageId": "login-update-password.ftl",
diff --git a/yarn.lock b/yarn.lock
index daa44a76..73729c49 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1765,6 +1765,11 @@ restore-cursor@^3.1.0:
onetime "^5.1.0"
signal-exit "^3.0.2"
+rfc4648@^1.5.2:
+ version "1.5.2"
+ resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.5.2.tgz#cf5dac417dd83e7f4debf52e3797a723c1373383"
+ integrity sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg==
+
rfdc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
From 8807743dafbc8193c77c663b01127d5138c80c56 Mon Sep 17 00:00:00 2001
From: garronej
Date: Thu, 6 Oct 2022 00:36:46 +0200
Subject: [PATCH 51/77] Ignore mock when in Keycloak:
https://github.com/InseeFrLab/keycloakify/discussions/186#discussioncomment-3809320
---
src/lib/getKcContext/getKcContext.ts | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/lib/getKcContext/getKcContext.ts b/src/lib/getKcContext/getKcContext.ts
index ae85fcd9..55970525 100644
--- a/src/lib/getKcContext/getKcContext.ts
+++ b/src/lib/getKcContext/getKcContext.ts
@@ -17,7 +17,9 @@ export function getKcContext | undefined } {
const { mockPageId, mockData } = params ?? {};
- if (mockPageId !== undefined) {
+ const realKcContext = getKcContextFromWindow();
+
+ if (mockPageId !== undefined && realKcContext === undefined) {
//TODO maybe trow if no mock fo custom page
const kcContextDefaultMock = kcContextMocks.find(({ pageId }) => pageId === mockPageId);
@@ -106,13 +108,15 @@ export function getKcContext();
+ if (realKcContext === undefined) {
+ return { "kcContext": undefined };
+ }
- if (kcContext !== undefined) {
- const { url } = kcContext;
+ {
+ const { url } = realKcContext;
url.resourcesCommonPath = pathJoin(url.resourcesPath, pathBasename(mockTestingResourcesCommonPath));
}
- return { kcContext };
+ return { "kcContext": realKcContext };
}
From 18ab7cd22f40ecfccffd8bc8821806c7d2406268 Mon Sep 17 00:00:00 2001
From: garronej
Date: Thu, 6 Oct 2022 00:37:51 +0200
Subject: [PATCH 52/77] Bump version
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 137613c7..264740fc 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.6.1",
+ "version": "6.6.2",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
From ce4ea554385799a1ab2e5b1ccdc0daf6033223fd Mon Sep 17 00:00:00 2001
From: garronej
Date: Thu, 6 Oct 2022 00:59:46 +0200
Subject: [PATCH 53/77] Add a big red warning when kcContext mock is enabled
---
src/lib/getKcContext/getKcContext.ts | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/lib/getKcContext/getKcContext.ts b/src/lib/getKcContext/getKcContext.ts
index 55970525..cc3af84b 100644
--- a/src/lib/getKcContext/getKcContext.ts
+++ b/src/lib/getKcContext/getKcContext.ts
@@ -10,6 +10,7 @@ import { getKcContextFromWindow } from "./getKcContextFromWindow";
import { pathJoin } from "../../bin/tools/pathJoin";
import { pathBasename } from "../tools/pathBasename";
import { mockTestingResourcesCommonPath } from "../../bin/mockTestingResourcesPath";
+import { symToStr } from "tsafe/symToStr";
export function getKcContext(params?: {
mockPageId?: ExtendsKcContextBase["pageId"];
@@ -22,6 +23,14 @@ export function getKcContext pageId === mockPageId);
const partialKcContextCustomMock = mockData?.find(({ pageId }) => pageId === mockPageId);
From b1e740f02691c0b957d9bf1ab09383d1796fa73e Mon Sep 17 00:00:00 2001
From: garronej
Date: Thu, 6 Oct 2022 01:09:00 +0200
Subject: [PATCH 54/77] Bump version
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 264740fc..7118ff4c 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.6.2",
+ "version": "6.6.3",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
From 9e63183f4bde5e8a907b8640410d705b45419f4a Mon Sep 17 00:00:00 2001
From: Mary Strodl
Date: Thu, 6 Oct 2022 14:25:04 -0400
Subject: [PATCH 55/77] WebauthnAuthenticate: refactor authentication flow
Lots of weird syntax here, and we were using `useCallback` rather than
`useConstCallback`.
---
src/lib/components/WebauthnAuthenticate.tsx | 114 +++++++++-----------
1 file changed, 53 insertions(+), 61 deletions(-)
diff --git a/src/lib/components/WebauthnAuthenticate.tsx b/src/lib/components/WebauthnAuthenticate.tsx
index b8908d9c..08d7ea3d 100644
--- a/src/lib/components/WebauthnAuthenticate.tsx
+++ b/src/lib/components/WebauthnAuthenticate.tsx
@@ -1,10 +1,11 @@
-import React, { useCallback, useRef, useState, memo } from "react";
+import React, { useRef, useState, memo } from "react";
import Template from "./Template";
import type { KcProps } from "./KcProps";
import type { KcContextBase } from "../getKcContext/KcContextBase";
import { useCssAndCx } from "../tools/useCssAndCx";
import type { I18n, MessageKeyBase } from "../i18n";
import { base64url } from "rfc4648";
+import { useConstCallback } from "powerhooks/useConstCallback";
const WebauthnAuthenticate = memo(
({
@@ -23,76 +24,67 @@ const WebauthnAuthenticate = memo(
const { cx } = useCssAndCx();
- const webAuthnAuthenticate = useCallback(() => {
+ const webAuthnAuthenticate = useConstCallback(async () => {
if (!isUserIdentified) {
return;
}
- checkAllowCredentials();
-
- function checkAllowCredentials() {
- const allowCredentials = authenticators.authenticators.map(
- authenticator =>
- ({
- id: base64url.parse(authenticator.credentialId, { loose: true }),
- type: "public-key"
- } as PublicKeyCredentialDescriptor)
- );
- doAuthenticate(allowCredentials);
+ const allowCredentials = authenticators.authenticators.map(
+ authenticator =>
+ ({
+ id: base64url.parse(authenticator.credentialId, { loose: true }),
+ type: "public-key"
+ } as PublicKeyCredentialDescriptor)
+ );
+ // Check if WebAuthn is supported by this browser
+ if (!window.PublicKeyCredential) {
+ setError(msgStr("webauthn-unsupported-browser-text"));
+ submitForm();
+ return;
}
- function doAuthenticate(allowCredentials: PublicKeyCredentialDescriptor[]) {
- // Check if WebAuthn is supported by this browser
- if (!window.PublicKeyCredential) {
- setError(msgStr("webauthn-unsupported-browser-text"));
- submitForm();
- return;
- }
- const publicKey: PublicKeyCredentialRequestOptions = {
- rpId,
- challenge: base64url.parse(challenge, { loose: true })
- };
+ const publicKey: PublicKeyCredentialRequestOptions = {
+ rpId,
+ challenge: base64url.parse(challenge, { loose: true })
+ };
- if (createTimeout !== 0) {
- publicKey.timeout = createTimeout * 1000;
- }
-
- if (allowCredentials.length) {
- publicKey.allowCredentials = allowCredentials;
- }
-
- if (userVerification !== "not specified") {
- publicKey.userVerification = userVerification;
- }
-
- navigator.credentials
- .get({ publicKey })
- .then(resultRaw => {
- if (!resultRaw || resultRaw.type != "public-key") return;
- const result = resultRaw as PublicKeyCredential;
- if (!("authenticatorData" in result.response)) return;
- const response = result.response as AuthenticatorAssertionResponse;
- let clientDataJSON = response.clientDataJSON;
- let authenticatorData = response.authenticatorData;
- let signature = response.signature;
-
- setClientDataJSON(base64url.stringify(new Uint8Array(clientDataJSON), { pad: false }));
- setAuthenticatorData(base64url.stringify(new Uint8Array(authenticatorData), { pad: false }));
- setSignature(base64url.stringify(new Uint8Array(signature), { pad: false }));
- setCredentialId(result.id);
- setUserHandle(base64url.stringify(new Uint8Array(response.userHandle!), { pad: false }));
- submitForm();
- })
- .catch(err => {
- setError(err);
- submitForm();
- });
+ if (createTimeout !== 0) {
+ publicKey.timeout = createTimeout * 1000;
}
- }, [kcContext]);
+
+ if (allowCredentials.length) {
+ publicKey.allowCredentials = allowCredentials;
+ }
+
+ if (userVerification !== "not specified") {
+ publicKey.userVerification = userVerification;
+ }
+
+ try {
+ const resultRaw = await navigator.credentials.get({ publicKey });
+ if (!resultRaw || resultRaw.type != "public-key") return;
+ const result = resultRaw as PublicKeyCredential;
+ if (!("authenticatorData" in result.response)) return;
+ const response = result.response as AuthenticatorAssertionResponse;
+ const clientDataJSON = response.clientDataJSON;
+ const authenticatorData = response.authenticatorData;
+ const signature = response.signature;
+
+ setClientDataJSON(base64url.stringify(new Uint8Array(clientDataJSON), { pad: false }));
+ setAuthenticatorData(base64url.stringify(new Uint8Array(authenticatorData), { pad: false }));
+ setSignature(base64url.stringify(new Uint8Array(signature), { pad: false }));
+ setCredentialId(result.id);
+ setUserHandle(base64url.stringify(new Uint8Array(response.userHandle!), { pad: false }));
+ submitForm();
+ } catch (err) {
+ setError(String(err));
+ submitForm();
+ }
+ });
const webAuthForm = useRef(null);
- const submitForm = useCallback(() => {
+ const submitForm = useConstCallback(() => {
webAuthForm.current!.submit();
- }, [webAuthForm.current]);
+ });
const [clientDataJSON, setClientDataJSON] = useState("");
const [authenticatorData, setAuthenticatorData] = useState("");
From a429ad5dcffcbcaddea421600ed8db02dd35becd Mon Sep 17 00:00:00 2001
From: garronej
Date: Thu, 6 Oct 2022 20:43:42 +0200
Subject: [PATCH 56/77] Bump version
---
README.md | 4 ++++
package.json | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index af7a21ac..29e572b2 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,10 @@
# Changelog highlights
+## 6.7.0
+
+- Add support for `webauthn-authenticate.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/InseeFrLab/keycloakify/pull/185).
+
## 6.6.0
- Add support for `login-password.ftl` thanks to [@mstrodl](https://github.com/Mstrodl)'s hacktoberfest [PR](https://github.com/InseeFrLab/keycloakify/pull/184).
diff --git a/package.json b/package.json
index 706984c7..8bc8ee81 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.6.3",
+ "version": "6.7.0",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
From ab81481e5a363362be5ecb59cc4309f1bebdceb5 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 10 Oct 2022 01:07:57 +0000
Subject: [PATCH 57/77] Update garronej_modules_update
---
package.json | 8 ++++----
yarn.lock | 30 +++++++++++++++---------------
2 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/package.json b/package.json
index 8bc8ee81..eb1721c5 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.7.0",
+ "version": "6.7.1",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -78,16 +78,16 @@
"@octokit/rest": "^18.12.0",
"cheerio": "^1.0.0-rc.5",
"cli-select": "^1.1.2",
- "evt": "^2.4.4",
+ "evt": "^2.4.5",
"memoizee": "^0.4.15",
"minimal-polyfills": "^2.2.2",
"minimist": "^1.2.6",
"path-browserify": "^1.0.1",
- "powerhooks": "^0.20.20",
+ "powerhooks": "^0.20.21",
"react-markdown": "^5.0.3",
"rfc4648": "^1.5.2",
"scripting-tools": "^0.19.13",
- "tsafe": "^1.1.1",
+ "tsafe": "^1.1.2",
"tss-react": "^4.3.4",
"zod": "^3.17.10"
}
diff --git a/yarn.lock b/yarn.lock
index e4f4576d..3ad8a861 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -967,14 +967,14 @@ event-emitter@^0.3.5:
d "1"
es5-ext "~0.10.14"
-evt@^2.4.4:
- version "2.4.4"
- resolved "https://registry.yarnpkg.com/evt/-/evt-2.4.4.tgz#37d6e28ccb5b1bc91162fc3d5bcfbeb1ef3191cf"
- integrity sha512-w/ZYdPCRdSfslOhcQHq7DuYoaU04YZKkFPyBwF8pYmOkRizivpbI0jZ8ffY/jITzbLo7RZ0wxN2dqyi62kyGwg==
+evt@^2.4.5:
+ version "2.4.5"
+ resolved "https://registry.yarnpkg.com/evt/-/evt-2.4.5.tgz#9e383c20a7917977e26b9fbad178585916ea8142"
+ integrity sha512-shiXMrEhTHqTl5PacT3vdA1U9i3usnInuxt77Lj0Ph9igNM982b1Uf/3L24OSzI0SqLx/XIRVIJcgzUZ2Ij8AA==
dependencies:
minimal-polyfills "^2.2.2"
run-exclusive "^2.2.16"
- tsafe "^1.1.1"
+ tsafe "^1.1.2"
execa@^5.1.1:
version "5.1.1"
@@ -1634,15 +1634,15 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
-powerhooks@^0.20.20:
- version "0.20.20"
- resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.20.tgz#f9b2549710f5166f63d80e07c46c16d6da4c6f78"
- integrity sha512-98Ymz0bjo5Ds9u273wYz1tdJ51sB1jcyjqGa08mRY5dKumewydA/+71zrFelfgkOLRRhVZ+mWynG6DZ7zOVjrQ==
+powerhooks@^0.20.21:
+ version "0.20.21"
+ resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.21.tgz#5520ffbba99b582354660fad0592759c8202016b"
+ integrity sha512-U5J2F252tmyycndAVaFripXtinDn36ZrqU/eRAzqFKnJiXh+pHijNJ2cwnquBvo/gi/m1bsH4v3gXYUQI6nrqg==
dependencies:
- evt "^2.4.4"
+ evt "^2.4.5"
memoizee "^0.4.15"
resize-observer-polyfill "^1.5.1"
- tsafe "^1.1.1"
+ tsafe "^1.1.2"
prettier@^2.3.0:
version "2.7.1"
@@ -1992,10 +1992,10 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
-tsafe@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.1.tgz#8d6998c726f8c63c518e1d1e283bbcd282a2b9a9"
- integrity sha512-Ogblm3uh0dVupcCcC4IT641rnSQ7CW9IO0q8yIncG8OBe4DDXEqGtUE8LWf7+0MK1qZGeWPWEqSxlLzY2xzREA==
+tsafe@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.2.tgz#cece1900bca89e25a84a65e7087f00dff3664b2e"
+ integrity sha512-jom5KsB9vpvOE9dLx2yTrPAJzzwU9CRPgoatoD7m2Zb7FCqo6ueEdZ+AZk+OysM4N+m8EUnIa1s9Pq3IMRDYLA==
tslib@^2.1.0:
version "2.4.0"
From 3c96d2ea428b5c47201ebf8dcf9e53761e9723d9 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 11 Oct 2022 19:52:29 +0000
Subject: [PATCH 58/77] Update garronej_modules_update
---
package.json | 6 +++---
yarn.lock | 15 ++++++++++-----
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/package.json b/package.json
index eb1721c5..cebf3916 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "6.7.1",
+ "version": "6.7.2",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -83,11 +83,11 @@
"minimal-polyfills": "^2.2.2",
"minimist": "^1.2.6",
"path-browserify": "^1.0.1",
- "powerhooks": "^0.20.21",
+ "powerhooks": "^0.20.22",
"react-markdown": "^5.0.3",
"rfc4648": "^1.5.2",
"scripting-tools": "^0.19.13",
- "tsafe": "^1.1.2",
+ "tsafe": "^1.1.3",
"tss-react": "^4.3.4",
"zod": "^3.17.10"
}
diff --git a/yarn.lock b/yarn.lock
index 3ad8a861..f833778d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1634,15 +1634,15 @@ please-upgrade-node@^3.2.0:
dependencies:
semver-compare "^1.0.0"
-powerhooks@^0.20.21:
- version "0.20.21"
- resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.21.tgz#5520ffbba99b582354660fad0592759c8202016b"
- integrity sha512-U5J2F252tmyycndAVaFripXtinDn36ZrqU/eRAzqFKnJiXh+pHijNJ2cwnquBvo/gi/m1bsH4v3gXYUQI6nrqg==
+powerhooks@^0.20.22:
+ version "0.20.22"
+ resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.20.22.tgz#469ba048dfa9c1d549325c73a091f8f3b96895b3"
+ integrity sha512-xFv5s7JTkwQh+lDVR1yLgGXPYfpbmdmdg6qT4VTF4EArieaImhCXFp7arSul55FvYoCuD5+gR9ooctDG53LeLg==
dependencies:
evt "^2.4.5"
memoizee "^0.4.15"
resize-observer-polyfill "^1.5.1"
- tsafe "^1.1.2"
+ tsafe "^1.1.3"
prettier@^2.3.0:
version "2.7.1"
@@ -1997,6 +1997,11 @@ tsafe@^1.1.2:
resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.2.tgz#cece1900bca89e25a84a65e7087f00dff3664b2e"
integrity sha512-jom5KsB9vpvOE9dLx2yTrPAJzzwU9CRPgoatoD7m2Zb7FCqo6ueEdZ+AZk+OysM4N+m8EUnIa1s9Pq3IMRDYLA==
+tsafe@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.1.3.tgz#fa7c2ae7da689884292b70ee30febbca5c665d03"
+ integrity sha512-QQQoed5Acb7Qe/sjMwE/qg57mxD5MXqY5HcGN4i3QyhJiplpo79ABEZiOBvL1cRTOYIzeryWvWQ3xsotTA49MQ==
+
tslib@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
From 688455d0aa8d8f54dfc21cbb28464cb7b79440b8 Mon Sep 17 00:00:00 2001
From: garronej
Date: Thu, 13 Oct 2022 11:58:31 +0200
Subject: [PATCH 59/77] #191: Enable to only customize the Template
---
src/lib/components/Error.tsx | 65 ++--
src/lib/components/IdpReviewUserProfile.tsx | 87 ++---
src/lib/components/Info.tsx | 91 ++---
src/lib/components/KcApp.tsx | 143 ++++----
src/lib/components/Login.tsx | 353 ++++++++++----------
src/lib/components/LoginConfigTotp.tsx | 325 +++++++++---------
src/lib/components/LoginIdpLinkConfirm.tsx | 99 +++---
src/lib/components/LoginIdpLinkEmail.tsx | 65 ++--
src/lib/components/LoginOtp.tsx | 161 ++++-----
src/lib/components/LoginPageExpired.tsx | 73 ++--
src/lib/components/LoginPassword.tsx | 155 ++++-----
src/lib/components/LoginResetPassword.tsx | 131 ++++----
src/lib/components/LoginUpdatePassword.tsx | 215 ++++++------
src/lib/components/LoginUpdateProfile.tsx | 217 ++++++------
src/lib/components/LoginUsername.tsx | 287 ++++++++--------
src/lib/components/LoginVerifyEmail.tsx | 65 ++--
src/lib/components/LogoutConfirm.tsx | 111 +++---
src/lib/components/Register.tsx | 281 ++++++++--------
src/lib/components/RegisterUserProfile.tsx | 125 +++----
src/lib/components/Terms.tsx | 108 +++---
src/lib/components/UpdateUserProfile.tsx | 125 +++----
src/lib/components/WebauthnAuthenticate.tsx | 353 ++++++++++----------
22 files changed, 1856 insertions(+), 1779 deletions(-)
diff --git a/src/lib/components/Error.tsx b/src/lib/components/Error.tsx
index 298bff06..06fcee6b 100644
--- a/src/lib/components/Error.tsx
+++ b/src/lib/components/Error.tsx
@@ -1,40 +1,43 @@
import React, { memo } from "react";
-import Template from "./Template";
+import DefaultTemplate from "./Template";
+import type { TemplateProps } from "./Template";
import type { KcProps } from "./KcProps";
import type { KcContextBase } from "../getKcContext/KcContextBase";
import type { I18n } from "../i18n";
-const Error = memo(
- ({
- kcContext,
- i18n,
- doFetchDefaultThemeResources = true,
- ...props
- }: { kcContext: KcContextBase.Error; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
- const { message, client } = kcContext;
+export type ErrorProps = KcProps & {
+ kcContext: KcContextBase.Error;
+ i18n: I18n;
+ doFetchDefaultThemeResources?: boolean;
+ Template?: (props: TemplateProps) => JSX.Element | null;
+};
- const { msg } = i18n;
+const Error = memo((props: ErrorProps) => {
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
- return (
-
- {message.summary}
- {client !== undefined && client.baseUrl !== undefined && (
-
-
- {msg("backToApplication")}
-
-
- )}
-
- }
- />
- );
- }
-);
+ const { message, client } = kcContext;
+
+ const { msg } = i18n;
+
+ return (
+