keycloakify 2.2.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +156 -127
- package/bin/KeycloakVersion.js.map +1 -1
- package/bin/build-keycloak-theme/build-keycloak-theme.js +57 -54
- package/bin/build-keycloak-theme/build-keycloak-theme.js.map +1 -1
- package/bin/build-keycloak-theme/ftlValuesGlobalName.js.map +1 -1
- package/bin/build-keycloak-theme/generateDebugFiles/generateDebugFiles.js +4 -11
- package/bin/build-keycloak-theme/generateDebugFiles/generateDebugFiles.js.map +1 -1
- package/bin/build-keycloak-theme/generateFtl/common.ftl +72 -56
- package/bin/build-keycloak-theme/generateFtl/generateFtl.d.ts +1 -1
- package/bin/build-keycloak-theme/generateFtl/generateFtl.js +47 -44
- package/bin/build-keycloak-theme/generateFtl/generateFtl.js.map +1 -1
- package/bin/build-keycloak-theme/generateJavaStackFiles.js +12 -8
- package/bin/build-keycloak-theme/generateJavaStackFiles.js.map +1 -1
- package/bin/build-keycloak-theme/generateKeycloakThemeResources.js +20 -21
- package/bin/build-keycloak-theme/generateKeycloakThemeResources.js.map +1 -1
- package/bin/build-keycloak-theme/index.js.map +1 -1
- package/bin/build-keycloak-theme/replaceImportFromStatic.js +18 -30
- package/bin/build-keycloak-theme/replaceImportFromStatic.js.map +1 -1
- package/bin/download-builtin-keycloak-theme.js +2 -2
- package/bin/download-builtin-keycloak-theme.js.map +1 -1
- package/bin/generate-i18n-messages.js +9 -11
- package/bin/generate-i18n-messages.js.map +1 -1
- package/bin/link_in_test_app.js +6 -22
- package/bin/link_in_test_app.js.map +1 -1
- package/bin/tools/crawl.js.map +1 -1
- package/bin/tools/downloadAndUnzip.js +4 -5
- package/bin/tools/downloadAndUnzip.js.map +1 -1
- package/bin/tools/grant-exec-perms.js +4 -3
- package/bin/tools/grant-exec-perms.js.map +1 -1
- package/bin/tools/isInside.js.map +1 -1
- package/bin/tools/rm.js +1 -1
- package/bin/tools/rm.js.map +1 -1
- package/bin/tools/transformCodebase.js +7 -3
- package/bin/tools/transformCodebase.js.map +1 -1
- package/lib/components/Error.js +1 -2
- package/lib/components/Error.js.map +1 -1
- package/lib/components/Info.js +1 -15
- package/lib/components/Info.js.map +1 -1
- package/lib/components/KcApp.js +23 -10
- package/lib/components/KcApp.js.map +1 -1
- package/lib/components/KcProps.d.ts +4 -2
- package/lib/components/KcProps.js +10 -8
- package/lib/components/KcProps.js.map +1 -1
- package/lib/components/Login.js +20 -18
- package/lib/components/Login.js.map +1 -1
- package/lib/components/LoginIdpLinkConfirm.js.map +1 -1
- package/lib/components/LoginOtp.js +14 -15
- package/lib/components/LoginOtp.js.map +1 -1
- package/lib/components/LoginResetPassword.js +5 -7
- package/lib/components/LoginResetPassword.js.map +1 -1
- package/lib/components/LoginUpdateProfile.js +1 -5
- package/lib/components/LoginUpdateProfile.js.map +1 -1
- package/lib/components/LoginVerifyEmail.js.map +1 -1
- package/lib/components/Register.js +1 -4
- package/lib/components/Register.js.map +1 -1
- package/lib/components/RegisterUserProfile.d.ts +6 -0
- package/lib/components/RegisterUserProfile.js +78 -0
- package/lib/components/RegisterUserProfile.js.map +1 -0
- package/lib/components/Template.js +28 -43
- package/lib/components/Template.js.map +1 -1
- package/lib/components/Terms.js.map +1 -1
- package/lib/getKcContext/KcContextBase.d.ts +78 -18
- package/lib/getKcContext/KcContextBase.js +2 -3
- package/lib/getKcContext/KcContextBase.js.map +1 -1
- package/lib/getKcContext/getKcContext.d.ts +1 -3
- package/lib/getKcContext/getKcContext.js +5 -9
- package/lib/getKcContext/getKcContext.js.map +1 -1
- package/lib/getKcContext/kcContextMocks/kcContextMocks.d.ts +1 -0
- package/lib/getKcContext/kcContextMocks/kcContextMocks.js +187 -55
- package/lib/getKcContext/kcContextMocks/kcContextMocks.js.map +1 -1
- package/lib/getKcContext/kcContextMocks/urlResourcesPath.js.map +1 -1
- package/lib/i18n/KcLanguageTag.d.ts +25 -2
- package/lib/i18n/KcLanguageTag.js +27 -27
- package/lib/i18n/KcLanguageTag.js.map +1 -1
- package/lib/i18n/generated_kcMessages/11.0.3/account.js +27 -27
- package/lib/i18n/generated_kcMessages/11.0.3/account.js.map +1 -1
- package/lib/i18n/generated_kcMessages/11.0.3/admin.js +23 -23
- package/lib/i18n/generated_kcMessages/11.0.3/admin.js.map +1 -1
- package/lib/i18n/generated_kcMessages/11.0.3/email.js +97 -97
- package/lib/i18n/generated_kcMessages/11.0.3/email.js.map +1 -1
- package/lib/i18n/generated_kcMessages/11.0.3/login.js +30 -30
- package/lib/i18n/generated_kcMessages/11.0.3/login.js.map +1 -1
- package/lib/i18n/generated_kcMessages/15.0.2/account.js +29 -29
- package/lib/i18n/generated_kcMessages/15.0.2/account.js.map +1 -1
- package/lib/i18n/generated_kcMessages/15.0.2/admin.js +23 -23
- package/lib/i18n/generated_kcMessages/15.0.2/admin.js.map +1 -1
- package/lib/i18n/generated_kcMessages/15.0.2/email.js +111 -111
- package/lib/i18n/generated_kcMessages/15.0.2/email.js.map +1 -1
- package/lib/i18n/generated_kcMessages/15.0.2/login.js +32 -32
- package/lib/i18n/generated_kcMessages/15.0.2/login.js.map +1 -1
- package/lib/i18n/kcMessages/login.js +1 -1
- package/lib/i18n/kcMessages/login.js.map +1 -1
- package/lib/i18n/useKcLanguageTag.js +1 -3
- package/lib/i18n/useKcLanguageTag.js.map +1 -1
- package/lib/i18n/useKcMessage.d.ts +4 -2
- package/lib/i18n/useKcMessage.js +12 -3
- package/lib/i18n/useKcMessage.js.map +1 -1
- package/lib/keycloakJsAdapter.d.ts +6 -6
- package/lib/keycloakJsAdapter.js +10 -12
- package/lib/keycloakJsAdapter.js.map +1 -1
- package/lib/tools/ReactComponent.d.ts +2 -0
- package/lib/tools/ReactComponent.js +3 -0
- package/lib/tools/ReactComponent.js.map +1 -0
- package/lib/tools/allPropertiesValuesToUndefined.js +1 -2
- package/lib/tools/allPropertiesValuesToUndefined.js.map +1 -1
- package/lib/tools/appendHead.js +16 -12
- package/lib/tools/appendHead.js.map +1 -1
- package/lib/tools/assert.js.map +1 -1
- package/lib/tools/deepAssign.js +3 -4
- package/lib/tools/deepAssign.js.map +1 -1
- package/lib/tools/deepClone.js.map +1 -1
- package/package.json +25 -5
- package/src/bin/KeycloakVersion.ts +0 -2
- package/src/bin/build-keycloak-theme/build-keycloak-theme.ts +70 -77
- package/src/bin/build-keycloak-theme/ftlValuesGlobalName.ts +1 -2
- package/src/bin/build-keycloak-theme/generateDebugFiles/generateDebugFiles.ts +26 -37
- package/src/bin/build-keycloak-theme/generateDebugFiles/index.ts +1 -1
- package/src/bin/build-keycloak-theme/generateFtl/common.ftl +72 -56
- package/src/bin/build-keycloak-theme/generateFtl/generateFtl.ts +75 -95
- package/src/bin/build-keycloak-theme/generateFtl/index.ts +1 -1
- package/src/bin/build-keycloak-theme/generateJavaStackFiles.ts +38 -56
- package/src/bin/build-keycloak-theme/generateKeycloakThemeResources.ts +47 -85
- package/src/bin/build-keycloak-theme/index.ts +2 -4
- package/src/bin/build-keycloak-theme/replaceImportFromStatic.ts +34 -78
- package/src/bin/download-builtin-keycloak-theme.ts +5 -19
- package/src/bin/generate-i18n-messages.ts +13 -25
- package/src/bin/link_in_test_app.ts +9 -38
- package/src/bin/tools/crawl.ts +2 -12
- package/src/bin/tools/downloadAndUnzip.ts +6 -22
- package/src/bin/tools/getProjectRoot.ts +1 -1
- package/src/bin/tools/grant-exec-perms.ts +8 -7
- package/src/bin/tools/isInside.ts +2 -9
- package/src/bin/tools/rm.ts +21 -32
- package/src/bin/tools/transformCodebase.ts +20 -43
- package/src/lib/components/Error.tsx +3 -7
- package/src/lib/components/Info.tsx +23 -47
- package/src/lib/components/KcApp.tsx +25 -13
- package/src/lib/components/KcProps.ts +94 -92
- package/src/lib/components/Login.tsx +126 -116
- package/src/lib/components/LoginIdpLinkConfirm.tsx +38 -53
- package/src/lib/components/LoginOtp.tsx +39 -76
- package/src/lib/components/LoginResetPassword.tsx +9 -26
- package/src/lib/components/LoginUpdateProfile.tsx +104 -117
- package/src/lib/components/LoginVerifyEmail.tsx +3 -12
- package/src/lib/components/Register.tsx +76 -46
- package/src/lib/components/RegisterUserProfile.tsx +201 -0
- package/src/lib/components/Template.tsx +109 -161
- package/src/lib/components/Terms.tsx +4 -13
- package/src/lib/getKcContext/KcContextBase.ts +104 -53
- package/src/lib/getKcContext/getKcContext.ts +47 -78
- package/src/lib/getKcContext/index.ts +2 -2
- package/src/lib/getKcContext/kcContextMocks/index.ts +1 -1
- package/src/lib/getKcContext/kcContextMocks/kcContextMocks.ts +362 -241
- package/src/lib/getKcContext/kcContextMocks/urlResourcesPath.ts +1 -2
- package/src/lib/i18n/KcLanguageTag.ts +34 -45
- package/src/lib/i18n/generated_kcMessages/11.0.3/account.ts +3086 -3059
- package/src/lib/i18n/generated_kcMessages/11.0.3/admin.ts +248 -239
- package/src/lib/i18n/generated_kcMessages/11.0.3/email.ts +848 -633
- package/src/lib/i18n/generated_kcMessages/11.0.3/login.ts +4466 -4359
- package/src/lib/i18n/generated_kcMessages/15.0.2/account.ts +4247 -4202
- package/src/lib/i18n/generated_kcMessages/15.0.2/admin.ts +273 -264
- package/src/lib/i18n/generated_kcMessages/15.0.2/email.ts +997 -749
- package/src/lib/i18n/generated_kcMessages/15.0.2/login.ts +5352 -5212
- package/src/lib/i18n/kcMessages/login.ts +4 -9
- package/src/lib/i18n/useKcLanguageTag.ts +2 -16
- package/src/lib/i18n/useKcMessage.tsx +26 -15
- package/src/lib/index.ts +0 -1
- package/src/lib/keycloakJsAdapter.ts +23 -53
- package/src/lib/tools/AndByDiscriminatingKey.ts +16 -30
- package/src/lib/tools/DeepPartial.ts +1 -2
- package/src/lib/tools/ReactComponent.ts +4 -0
- package/src/lib/tools/allPropertiesValuesToUndefined.ts +1 -6
- package/src/lib/tools/appendHead.ts +28 -25
- package/src/lib/tools/assert.ts +1 -2
- package/src/lib/tools/deepAssign.ts +28 -46
- package/src/lib/tools/deepClone.ts +2 -3
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
### **2.5.1** (2021-10-13)
|
2
|
+
|
3
|
+
- Update tss-react
|
4
|
+
|
5
|
+
## **2.5.0** (2021-10-12)
|
6
|
+
|
7
|
+
- register-user-profile.ftl tested working
|
8
|
+
- Make kcMessage more easily hackable
|
9
|
+
- fix useKcMessage
|
10
|
+
- Implement and type validators
|
11
|
+
- Remove syntax error in ftl and make it more directly debugable
|
12
|
+
- Support register-user-profile.ftl
|
13
|
+
|
14
|
+
## **2.4.0** (2021-10-08)
|
15
|
+
|
16
|
+
- #38: Implement messagesPerField existsError and get
|
17
|
+
|
18
|
+
## **2.3.0** (2021-10-07)
|
19
|
+
|
20
|
+
- #20: Support advancedMsg
|
21
|
+
|
1
22
|
## **2.2.0** (2021-10-07)
|
2
23
|
|
3
24
|
- Feat scrip: download-builtin-keycloak-theme for downloading any version of the builtin themes
|
package/README.md
CHANGED
@@ -20,17 +20,32 @@
|
|
20
20
|
<img src="https://user-images.githubusercontent.com/6702424/110260457-a1c3d380-7fac-11eb-853a-80459b65626b.png">
|
21
21
|
</p>
|
22
22
|
|
23
|
-
**NEW in v2**
|
24
|
-
|
25
|
-
-
|
26
|
-
|
23
|
+
**NEW in v2.5**
|
24
|
+
|
25
|
+
- User Profile ([`register-user-profile.ftl`](https://github.com/InseeFrLab/keycloakify/blob/main/src/lib/components/RegisterUserProfile.tsx))
|
26
|
+
is now supported! 🎉
|
27
|
+
It enables to [define, from the admin console](https://user-images.githubusercontent.com/6702424/136872461-1f5b64ef-d2ef-4c6b-bb8d-07d4729552b3.png),
|
28
|
+
what information you want to collect on your users in the register page and to validate inputs
|
29
|
+
[**on the frontend**, in realtime](https://github.com/InseeFrLab/keycloakify/blob/6dca6a93d8cfe634ee4d8574ad0c091641220092/src/lib/getKcContext/KcContextBase.ts#L225-L261)!
|
30
|
+
NOTE: User profile is only available in Keycloak 15 and it's a beta feature that
|
31
|
+
[needs to be enabled when launching keycloak](https://github.com/InseeFrLab/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/bin/build-keycloak-theme/build-keycloak-theme.ts#L116-L117) and [enabled in the console](https://user-images.githubusercontent.com/6702424/136874428-b071d614-c7f7-440d-9b2e-670faadc0871.png).
|
32
|
+
- Feature [Use advanced message](https://github.com/InseeFrLab/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/lib/i18n/useKcMessage.tsx#L53-L66)
|
33
|
+
and [`messagesPerFields`](https://github.com/InseeFrLab/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/lib/getKcContext/KcContextBase.ts#L70-L75) (implementation [here](https://github.com/InseeFrLab/keycloakify/blob/59f106bf9e210b63b190826da2bf5f75fc8b7644/src/bin/build-keycloak-theme/generateFtl/common.ftl#L130-L189))
|
34
|
+
- Test container now uses Keycloak version `15.0.2`.
|
35
|
+
|
36
|
+
**NEW in v2**
|
37
|
+
|
38
|
+
- It's now possible to implement custom `.ftl` pages.
|
39
|
+
- Support for Keycloak plugins that introduce non standard ftl values.
|
40
|
+
(Like for example [this plugin](https://github.com/micedre/keycloak-mail-whitelisting) that define `authorizedMailDomains` in `register.ftl`).
|
41
|
+
|
27
42
|
# Motivations
|
28
43
|
|
29
44
|
Keycloak provides [theme support](https://www.keycloak.org/docs/latest/server_development/#_themes) for web pages. This allows customizing the look and feel of end-user facing pages so they can be integrated with your applications.
|
30
45
|
It involves, however, a lot of raw JS/CSS/[FTL]() hacking, and bundling the theme is not exactly straightforward.
|
31
46
|
|
32
47
|
Beyond that, if you use Keycloak for a specific app you want your login page to be tightly integrated with it.
|
33
|
-
Ideally, you don't want the user to notice when he is being redirected away.
|
48
|
+
Ideally, you don't want the user to notice when he is being redirected away.
|
34
49
|
|
35
50
|
Trying to reproduce the look and feel of a specific app in another stack is not an easy task not to mention
|
36
51
|
the cheer amount of maintenance that it involves.
|
@@ -47,69 +62,72 @@ Here is `keycloakify` for you 🍸
|
|
47
62
|
<i> <a href="https://datalab.sspcloud.fr">With keycloakify:</a> </i>
|
48
63
|
<br>
|
49
64
|
<img src="https://user-images.githubusercontent.com/6702424/114332075-c5e37900-9b45-11eb-910b-48a05b3d90d9.gif">
|
50
|
-
</p>
|
65
|
+
</p>
|
51
66
|
|
52
|
-
**TL;DR**: [Here](https://github.com/garronej/keycloakify-demo-app) is a Hello World React project with Keycloakify set up.
|
67
|
+
**TL;DR**: [Here](https://github.com/garronej/keycloakify-demo-app) is a Hello World React project with Keycloakify set up.
|
53
68
|
|
54
69
|
If you already have a Keycloak custom theme, it can be easily ported to Keycloakify.
|
55
70
|
|
56
71
|
---
|
57
72
|
|
58
|
-
|
59
|
-
-
|
60
|
-
-
|
61
|
-
|
62
|
-
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
-
|
67
|
-
|
68
|
-
-
|
69
|
-
-
|
70
|
-
-
|
71
|
-
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
-
|
77
|
-
-
|
78
|
-
-
|
79
|
-
-
|
80
|
-
|
81
|
-
# Requirements
|
82
|
-
|
83
|
-
Tested with the following Keycloak versions:
|
84
|
-
|
85
|
-
-
|
86
|
-
-
|
87
|
-
|
88
|
-
|
73
|
+
- [Motivations](#motivations)
|
74
|
+
- [Requirements](#requirements)
|
75
|
+
- [My framework doesn’t seem to be supported, what can I do?](#my-framework-doesnt-seem-to-be-supported-what-can-i-do)
|
76
|
+
- [How to use](#how-to-use)
|
77
|
+
- [Setting up the build tool](#setting-up-the-build-tool)
|
78
|
+
- [Changing just the look of the default Keycloak theme](#changing-just-the-look-of-the-default-keycloak-theme)
|
79
|
+
- [Advanced pages configuration](#advanced-pages-configuration)
|
80
|
+
- [Hot reload](#hot-reload)
|
81
|
+
- [Enable loading in a blink of an eye of login pages ⚡ (--external-assets)](#enable-loading-in-a-blink-of-an-eye-of-login-pages----external-assets)
|
82
|
+
- [Support for Terms and conditions](#support-for-terms-and-conditions)
|
83
|
+
- [Some pages still have the default theme. Why?](#some-pages-still-have-the-default-theme-why)
|
84
|
+
- [GitHub Actions](#github-actions)
|
85
|
+
- [Limitations](#limitations)
|
86
|
+
- [`process.env.PUBLIC_URL` not supported.](#processenvpublic_url-not-supported)
|
87
|
+
- [`@font-face` importing fonts from the `src/` dir](#font-face-importing-fonts-from-thesrc-dir)
|
88
|
+
- [Example of setup that **won't** work](#example-of-setup-that-wont-work)
|
89
|
+
- [Possible workarounds](#possible-workarounds)
|
90
|
+
- [Implement context persistence (optional)](#implement-context-persistence-optional)
|
91
|
+
- [Kickstart video](#kickstart-video)
|
92
|
+
- [About the errors related to `objectToJson` in Keycloak logs.](#about-the-errors-related-to-objecttojson-in-keycloak-logs)
|
93
|
+
- [Adding custom message (to `i18n/useKcMessage.tsx`)](#adding-custom-message-to-i18nusekcmessagetsx)
|
94
|
+
- [Email domain whitelist](#email-domain-whitelist)
|
95
|
+
|
96
|
+
# Requirements
|
97
|
+
|
98
|
+
Tested with the following Keycloak versions:
|
99
|
+
|
100
|
+
- [11.0.3](https://hub.docker.com/layers/jboss/keycloak/11.0.3/images/sha256-4438f1e51c1369371cb807dffa526e1208086b3ebb9cab009830a178de949782?context=explore)
|
101
|
+
- [12.0.4](https://hub.docker.com/layers/jboss/keycloak/12.0.4/images/sha256-67e0c88e69bd0c7aef972c40bdeb558a974013a28b3668ca790ed63a04d70584?context=explore)
|
102
|
+
- [15.0.2](https://hub.docker.com/layers/jboss/keycloak/15.0.2/images/sha256-d8ed1ee5df42a178c341f924377da75db49eab08ea9f058ff39a8ed7ee05ec93?context=explore)
|
103
|
+
|
104
|
+
This tool will be maintained to stay compatible with Keycloak v11 and up, however, the default pages you will get
|
89
105
|
(before you customize it) will always be the ones of Keycloak v11.
|
90
106
|
|
91
107
|
This tool assumes you are bundling your app with Webpack (tested with 4.44.2) .
|
92
108
|
It assumes there is a `build/` directory at the root of your react project directory containing a `index.html` file
|
93
|
-
and a `build/static/` directory generated by webpack.
|
109
|
+
and a `build/static/` directory generated by webpack.
|
94
110
|
For more information see [this issue](https://github.com/InseeFrLab/keycloakify/issues/5#issuecomment-832296432)
|
95
111
|
|
96
112
|
**All this is defaults with [`create-react-app`](https://create-react-app.dev)** (tested with 4.0.3)
|
97
113
|
|
98
|
-
-
|
99
|
-
-
|
114
|
+
- `mvn` ([Maven](https://maven.apache.org/)), `rm`, `mkdir`, `wget`, `unzip` are assumed to be available.
|
115
|
+
- `docker` must be up and running when running `yarn keycloak`.
|
100
116
|
|
101
117
|
On Windows you'll have to use [WSL](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
|
102
118
|
|
103
|
-
## My framework doesn’t seem to be supported, what can I do?
|
119
|
+
## My framework doesn’t seem to be supported, what can I do?
|
104
120
|
|
105
121
|
Currently Keycloakify is only compatible with `create-react-app` apps.
|
106
|
-
It doesn’t mean that you can't use Keycloakify if you are using Next.js, Express or any other
|
122
|
+
It doesn’t mean that you can't use Keycloakify if you are using Next.js, Express or any other
|
107
123
|
framework that involves SSR but your Keycloak theme will need to be a standalone project.
|
108
|
-
Find specific instructions about how to get started [**here**](https://github.com/garronej/keycloakify-demo-app#keycloak-theme-only).
|
124
|
+
Find specific instructions about how to get started [**here**](https://github.com/garronej/keycloakify-demo-app#keycloak-theme-only).
|
109
125
|
|
110
126
|
To share your styles between your main app and your login pages you will need to externalize your design system by making it a
|
111
127
|
separate module. Checkout [ts_ci](https://github.com/garronej/ts_ci), it can help with that.
|
128
|
+
|
112
129
|
# How to use
|
130
|
+
|
113
131
|
## Setting up the build tool
|
114
132
|
|
115
133
|
```bash
|
@@ -117,6 +135,7 @@ yarn add keycloakify
|
|
117
135
|
```
|
118
136
|
|
119
137
|
[`package.json`](https://github.com/garronej/keycloakify-demo-app/blob/main/package.json)
|
138
|
+
|
120
139
|
```json
|
121
140
|
"scripts": {
|
122
141
|
"keycloak": "yarn build && build-keycloak-theme",
|
@@ -135,14 +154,15 @@ The first approach is to only customize the style of the default Keycloak login
|
|
135
154
|
your own class names.
|
136
155
|
|
137
156
|
If you have created a new React project specifically to create a Keycloak theme and nothing else then
|
138
|
-
your index should look something like:
|
157
|
+
your index should look something like:
|
139
158
|
|
140
159
|
`src/index.tsx`
|
160
|
+
|
141
161
|
```tsx
|
142
162
|
import { App } from "./<wherever>/App";
|
143
|
-
import {
|
144
|
-
KcApp,
|
145
|
-
defaultKcProps,
|
163
|
+
import {
|
164
|
+
KcApp,
|
165
|
+
defaultKcProps,
|
146
166
|
getKcContext
|
147
167
|
} from "keycloakify";
|
148
168
|
import { css } from "tss-react/@emotion/css";
|
@@ -152,59 +172,57 @@ const { kcContext } = getKcContext();
|
|
152
172
|
const myClassName = css({ "color": "red" });
|
153
173
|
|
154
174
|
reactDom.render(
|
155
|
-
<KcApp
|
156
|
-
kcContext={kcContext}
|
175
|
+
<KcApp
|
176
|
+
kcContext={kcContext}
|
157
177
|
{...{
|
158
178
|
...defaultKcProps,
|
159
179
|
"kcHeaderWrapperClass": myClassName
|
160
|
-
}}
|
180
|
+
}}
|
161
181
|
/>
|
162
182
|
document.getElementById("root")
|
163
183
|
);
|
164
184
|
```
|
165
185
|
|
166
186
|
If you share a unique project for your app and the Keycloak theme, your index should look
|
167
|
-
more like this:
|
187
|
+
more like this:
|
168
188
|
|
169
189
|
`src/index.tsx`
|
190
|
+
|
170
191
|
```tsx
|
171
|
-
import {
|
172
|
-
import {
|
173
|
-
|
174
|
-
defaultKcProps,
|
175
|
-
getKcContext
|
176
|
-
} from "keycloakify";
|
177
|
-
import { css } from "tss-react/@emotion/css";
|
192
|
+
import { App } from "./<wherever>/App";
|
193
|
+
import { KcApp, defaultKcProps, getKcContext } from "keycloakify";
|
194
|
+
import { css } from "tss-react/@emotion/css";
|
178
195
|
|
179
196
|
const { kcContext } = getKcContext();
|
180
197
|
|
181
198
|
const myClassName = css({ "color": "red" });
|
182
199
|
|
183
200
|
reactDom.render(
|
184
|
-
// Unless the app is currently being served by Keycloak
|
201
|
+
// Unless the app is currently being served by Keycloak
|
185
202
|
// kcContext is undefined.
|
186
|
-
kcContext !== undefined ?
|
187
|
-
<KcApp
|
188
|
-
kcContext={kcContext}
|
203
|
+
kcContext !== undefined ? (
|
204
|
+
<KcApp
|
205
|
+
kcContext={kcContext}
|
189
206
|
{...{
|
190
207
|
...defaultKcProps,
|
191
|
-
"kcHeaderWrapperClass": myClassName
|
192
|
-
}}
|
193
|
-
/>
|
194
|
-
|
195
|
-
|
208
|
+
"kcHeaderWrapperClass": myClassName,
|
209
|
+
}}
|
210
|
+
/>
|
211
|
+
) : (
|
212
|
+
<App />
|
213
|
+
), // Your actual app
|
214
|
+
document.getElementById("root"),
|
196
215
|
);
|
197
216
|
```
|
198
217
|
|
199
|
-
|
200
218
|
<p align="center">
|
201
219
|
<i>result:</i></br>
|
202
220
|
<img src="https://user-images.githubusercontent.com/6702424/114326299-6892fc00-9b34-11eb-8d75-85696e55458f.png">
|
203
221
|
</p>
|
204
222
|
|
205
|
-
Example of a customization using only CSS: [here](https://github.com/InseeFrLab/onyxia-ui/blob/012639d62327a9a56be80c46e32c32c9497b82db/src/app/components/KcApp.tsx)
|
223
|
+
Example of a customization using only CSS: [here](https://github.com/InseeFrLab/onyxia-ui/blob/012639d62327a9a56be80c46e32c32c9497b82db/src/app/components/KcApp.tsx)
|
206
224
|
(the [index.tsx](https://github.com/InseeFrLab/onyxia-ui/blob/012639d62327a9a56be80c46e32c32c9497b82db/src/app/index.tsx#L89-L94) )
|
207
|
-
and the result you can expect:
|
225
|
+
and the result you can expect:
|
208
226
|
|
209
227
|
<p align="center">
|
210
228
|
<i> <a href="https://datalab.sspcloud.fr">Customization using only CSS:</a> </i>
|
@@ -214,36 +232,39 @@ and the result you can expect:
|
|
214
232
|
|
215
233
|
### Advanced pages configuration
|
216
234
|
|
217
|
-
If you want to go beyond only customizing the CSS you can re-implement some of the
|
218
|
-
pages or even add new ones.
|
235
|
+
If you want to go beyond only customizing the CSS you can re-implement some of the
|
236
|
+
pages or even add new ones.
|
219
237
|
|
220
238
|
If you want to go this way checkout the demo setup provided [here](https://github.com/garronej/keycloakify-demo-app/tree/look_and_feel).
|
221
|
-
If you prefer a real life example you can checkout [onyxia-web's source](https://github.com/InseeFrLab/onyxia-web/tree/main/src/app/components/KcApp).
|
239
|
+
If you prefer a real life example you can checkout [onyxia-web's source](https://github.com/InseeFrLab/onyxia-web/tree/main/src/app/components/KcApp).
|
222
240
|
The web app is in production [here](https://datalab.sspcloud.fr).
|
223
241
|
|
224
242
|
Main takeaways are:
|
225
|
-
|
226
|
-
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
243
|
+
|
244
|
+
- You must declare your custom pages in the package.json. [example](https://github.com/garronej/keycloakify-demo-app/blob/4eb2a9f63e9823e653b2d439495bda55e5ecc134/package.json#L17-L22)
|
245
|
+
- (TS only) You must declare theses page in the type argument of the getter
|
246
|
+
function for the `kcContext` in order to have the correct typings. [example](https://github.com/garronej/keycloakify-demo-app/blob/4eb2a9f63e9823e653b2d439495bda55e5ecc134/src/KcApp/kcContext.ts#L16-L21)
|
247
|
+
- (TS only) If you use Keycloak plugins that defines non standard `.ftl` values
|
248
|
+
(Like for example [this plugin](https://github.com/micedre/keycloak-mail-whitelisting)
|
249
|
+
that define `authorizedMailDomains` in `register.ftl`) you should
|
250
|
+
declare theses value to get the type. [example](https://github.com/garronej/keycloakify-demo-app/blob/4eb2a9f63e9823e653b2d439495bda55e5ecc134/src/KcApp/kcContext.ts#L6-L13)
|
251
|
+
- You should provide sample data for all the non standard value if you want to be able
|
252
|
+
to debug the page outside of keycloak. [example](https://github.com/garronej/keycloakify-demo-app/blob/4eb2a9f63e9823e653b2d439495bda55e5ecc134/src/KcApp/kcContext.ts#L28-L43)
|
234
253
|
|
235
254
|
WARNING: If you chose to go this way use:
|
255
|
+
|
236
256
|
```json
|
237
257
|
"dependencies": {
|
238
258
|
"keycloakify": "~X.Y.Z"
|
239
259
|
}
|
240
260
|
```
|
261
|
+
|
241
262
|
in your `package.json` instead of `^X.Y.Z`. A minor update of Keycloakify might break your app.
|
242
263
|
|
243
264
|
### Hot reload
|
244
265
|
|
245
266
|
Rebuild the theme each time you make a change to see the result is not practical.
|
246
|
-
If you want to test your login screens outside of Keycloak you can mock a given `kcContext`:
|
267
|
+
If you want to test your login screens outside of Keycloak you can mock a given `kcContext`:
|
247
268
|
|
248
269
|
```tsx
|
249
270
|
import {
|
@@ -257,9 +278,9 @@ const { kcContext } = getKcContext({
|
|
257
278
|
});
|
258
279
|
|
259
280
|
reactDom.render(
|
260
|
-
<KcApp
|
281
|
+
<KcApp
|
261
282
|
kcContext={kcContextMocks.kcLoginContext}
|
262
|
-
{...defaultKcProps}
|
283
|
+
{...defaultKcProps}
|
263
284
|
/>
|
264
285
|
document.getElementById("root")
|
265
286
|
);
|
@@ -274,15 +295,15 @@ Checkout [this concrete example](https://github.com/garronej/keycloakify-demo-ap
|
|
274
295
|
By default the theme generated is standalone. Meaning that when your users
|
275
296
|
reach the login pages all scripts, images and stylesheet are downloaded from the Keycloak server.
|
276
297
|
If you are specifically building a theme to integrate with an app or a website that allows users
|
277
|
-
to first browse unauthenticated before logging in, you will get a significant
|
298
|
+
to first browse unauthenticated before logging in, you will get a significant
|
278
299
|
performance boost if you jump through those hoops:
|
279
300
|
|
280
|
-
-
|
281
|
-
-
|
282
|
-
-
|
283
|
-
-
|
284
|
-
|
285
|
-
-
|
301
|
+
- Provide the url of your app in the `homepage` field of package.json. [ex](https://github.com/garronej/keycloakify-demo-app/blob/7847cc70ef374ab26a6cc7953461cf25603e9a6d/package.json#L2)
|
302
|
+
- Build the theme using `npx build-keycloak-theme --external-assets` [ex](https://github.com/garronej/keycloakify-demo-app/blob/7847cc70ef374ab26a6cc7953461cf25603e9a6d/.github/workflows/ci.yaml#L21)
|
303
|
+
- Enable [long-term assets caching](https://create-react-app.dev/docs/production-build/#static-file-caching) on the server hosting your app.
|
304
|
+
- Make sure not to build your app and the keycloak theme separately
|
305
|
+
and remember to update the Keycloak theme every time you update your app.
|
306
|
+
- Be mindful that if your app is down your login pages are down as well.
|
286
307
|
|
287
308
|
Checkout a complete setup [here](https://github.com/garronej/keycloakify-demo-app#about-keycloakify)
|
288
309
|
|
@@ -308,51 +329,51 @@ If you need to customize pages that are not supported yet or if you need to impl
|
|
308
329
|
|
309
330
|
[Here is a demo repo](https://github.com/garronej/keycloakify-demo-app) to show how to automate
|
310
331
|
the building and publishing of the theme (the .jar file).
|
332
|
+
|
311
333
|
# Limitations
|
334
|
+
|
312
335
|
## `process.env.PUBLIC_URL` not supported.
|
313
336
|
|
314
|
-
You won't be able to [import things from your public directory **in your JavaScript code**](https://create-react-app.dev/docs/using-the-public-folder/#adding-assets-outside-of-the-module-system).
|
337
|
+
You won't be able to [import things from your public directory **in your JavaScript code**](https://create-react-app.dev/docs/using-the-public-folder/#adding-assets-outside-of-the-module-system).
|
315
338
|
(This isn't recommended anyway).
|
316
339
|
|
317
|
-
|
318
|
-
|
319
340
|
## `@font-face` importing fonts from the `src/` dir
|
320
341
|
|
321
|
-
If you are building the theme with [--external-assets](#enable-loading-in-a-blink-of-a-eye-of-login-pages-)
|
342
|
+
If you are building the theme with [--external-assets](#enable-loading-in-a-blink-of-a-eye-of-login-pages-)
|
322
343
|
this limitation doesn't apply, you can import fonts however you see fit.
|
323
344
|
|
324
|
-
### Example of setup that **won't** work
|
345
|
+
### Example of setup that **won't** work
|
325
346
|
|
326
|
-
-
|
327
|
-
-
|
347
|
+
- We have a `fonts/` directory in `src/`
|
348
|
+
- We import the font like this [`src: url("/fonts/my-font.woff2") format("woff2");`](https://github.com/garronej/keycloakify-demo-app/blob/07d54a3012ef354ee12b1374c6f7ad1cb125d56b/src/fonts.scss#L4) in a `.scss` a file.
|
328
349
|
|
329
|
-
### Possible workarounds
|
350
|
+
### Possible workarounds
|
330
351
|
|
331
|
-
-
|
332
|
-
-
|
333
|
-
-
|
334
|
-
directory and to place your `@font-face` statements in the `public/index.html`.
|
335
|
-
Example [here](https://github.com/InseeFrLab/onyxia-ui/blob/0e3a04610cfe872ca71dad59e05ced8f785dee4b/public/index.html#L6-L51).
|
336
|
-
-
|
352
|
+
- Use [`--external-assets`](#enable-loading-in-a-blink-of-a-eye-of-login-pages-).
|
353
|
+
- If it is possible, use Google Fonts or any other font provider.
|
354
|
+
- If you want to host your font recommended approach is to move your fonts into the `public`
|
355
|
+
directory and to place your `@font-face` statements in the `public/index.html`.
|
356
|
+
Example [here](https://github.com/InseeFrLab/onyxia-ui/blob/0e3a04610cfe872ca71dad59e05ced8f785dee4b/public/index.html#L6-L51).
|
357
|
+
- You can also [use non relative url](https://github.com/garronej/keycloakify-demo-app/blob/2de8a9eb6f5de9c94f9cd3991faad0377e63268c/src/fonts.scss#L16) but don't forget [`Access-Control-Allow-Origin`](https://github.com/garronej/keycloakify-demo-app/blob/2de8a9eb6f5de9c94f9cd3991faad0377e63268c/nginx.conf#L17-L19).
|
337
358
|
|
338
359
|
# Implement context persistence (optional)
|
339
360
|
|
340
|
-
If, before logging in, a user has selected a specific language
|
361
|
+
If, before logging in, a user has selected a specific language
|
341
362
|
you don't want it to be reset to default when the user gets redirected to
|
342
|
-
the login or register pages.
|
343
|
-
|
363
|
+
the login or register pages.
|
364
|
+
|
344
365
|
Same goes for the dark mode, you don't want, if the user had it enabled
|
345
|
-
to show the login page with light themes.
|
346
|
-
|
366
|
+
to show the login page with light themes.
|
367
|
+
|
347
368
|
The problem is that you are probably using `localStorage` to persist theses values across
|
348
369
|
reload but, as the Keycloak pages are not served on the same domain that the rest of your
|
349
|
-
app you won't be able to carry over states using `localStorage`.
|
370
|
+
app you won't be able to carry over states using `localStorage`.
|
350
371
|
|
351
372
|
The only reliable solution is to inject parameters into the URL before
|
352
|
-
redirecting to Keycloak. We integrate with
|
353
|
-
[`keycloak-js`](https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/javascript-adapter.adoc),
|
373
|
+
redirecting to Keycloak. We integrate with
|
374
|
+
[`keycloak-js`](https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/javascript-adapter.adoc),
|
354
375
|
by providing you a way to tell `keycloak-js` that you would like to inject
|
355
|
-
some search parameters before redirecting.
|
376
|
+
some search parameters before redirecting.
|
356
377
|
|
357
378
|
The method also works with [`@react-keycloak/web`](https://www.npmjs.com/package/@react-keycloak/web) (use the `initOptions`).
|
358
379
|
|
@@ -368,23 +389,23 @@ Note that the states are automatically restored on the other side by `powerhooks
|
|
368
389
|
```typescript
|
369
390
|
import keycloak_js from "keycloak-js";
|
370
391
|
import { injectGlobalStatesInSearchParams } from "powerhooks/useGlobalState";
|
371
|
-
import { createKeycloakAdapter
|
392
|
+
import { createKeycloakAdapter } from "keycloakify";
|
372
393
|
|
373
394
|
//...
|
374
395
|
|
375
396
|
const keycloakInstance = keycloak_js({
|
376
397
|
"url": "http://keycloak-server/auth",
|
377
398
|
"realm": "myrealm",
|
378
|
-
"clientId": "myapp"
|
399
|
+
"clientId": "myapp",
|
379
400
|
});
|
380
401
|
|
381
402
|
keycloakInstance.init({
|
382
|
-
"onLoad":
|
403
|
+
"onLoad": "check-sso",
|
383
404
|
"silentCheckSsoRedirectUri": window.location.origin + "/silent-check-sso.html",
|
384
405
|
"adapter": createKeycloakAdapter({
|
385
406
|
"transformUrlBeforeRedirect": injectGlobalStatesInSearchParams,
|
386
|
-
keycloakInstance
|
387
|
-
})
|
407
|
+
keycloakInstance,
|
408
|
+
}),
|
388
409
|
});
|
389
410
|
|
390
411
|
//...
|
@@ -396,12 +417,13 @@ flash of the blank html before the js bundle have been evaluated
|
|
396
417
|
|
397
418
|
# Kickstart video
|
398
419
|
|
399
|
-
|
420
|
+
_NOTE: keycloak-react-theming was renamed keycloakify since this video was recorded_
|
400
421
|
[](https://youtu.be/xTz0Rj7i2v8)
|
401
422
|
|
402
|
-
# About the errors related to `objectToJson` in Keycloak logs.
|
423
|
+
# About the errors related to `objectToJson` in Keycloak logs.
|
424
|
+
|
425
|
+
The logs of your keycloak server will always show this kind of errors every time a client request a page:
|
403
426
|
|
404
|
-
The logs of your keycloak server will always show this kind of errors every time a client request a page:
|
405
427
|
```log
|
406
428
|
FTL stack trace ("~" means nesting-related):
|
407
429
|
- Failed at: #local value = object[key] [in template "login.ftl" in macro "objectToJson" at line 70, column 21]
|
@@ -410,13 +432,20 @@ FTL stack trace ("~" means nesting-related):
|
|
410
432
|
- Reached through: @compress [in template "login.ftl" in macro "objectToJson" at line 36, column 5]
|
411
433
|
- Reached through: @objectToJson object=(.data_model) de... [in template "login.ftl" at line 163, column 43]
|
412
434
|
```
|
413
|
-
Theses are expected and can be safely ignored.
|
414
435
|
|
415
|
-
|
436
|
+
Theses are expected and can be safely ignored.
|
437
|
+
|
438
|
+
To [converts the `.ftl` values into a JavaScript object](https://github.com/InseeFrLab/keycloakify/blob/main/src/bin/build-keycloak-theme/generateFtl/common.ftl)
|
416
439
|
without making assumptions on the `.data_model` we have to do things that throws.
|
417
440
|
It's all-right though because every statement that can fail is inside an `<#attempt><#recorver>` block but it results in errors being printed to the logs.
|
418
441
|
|
442
|
+
# Adding custom message (to `i18n/useKcMessage.tsx`)
|
443
|
+
|
444
|
+
You can reproduce [this approach](https://github.com/garronej/keycloakify-demo-app/blob/main/src/kcMessagesExtension.ts)
|
445
|
+
( don't forget to [evaluate the code](https://github.com/garronej/keycloakify-demo-app/blob/0a6d349dba89a5702f98ba48bca6c76ac7265e1f/src/index.tsx#L15) ).
|
446
|
+
This approach is a bit hacky as it doesn't provide type safety but it works.
|
447
|
+
|
419
448
|
# Email domain whitelist
|
420
449
|
|
421
|
-
If you want to restrict the emails domain that can register, you can use [this plugin](https://github.com/micedre/keycloak-mail-whitelisting)
|
450
|
+
If you want to restrict the emails domain that can register, you can use [this plugin](https://github.com/micedre/keycloak-mail-whitelisting)
|
422
451
|
and `kcRegisterContext["authorizedMailDomains"]` to validate on.
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"KeycloakVersion.js","sourceRoot":"","sources":["../src/bin/KeycloakVersion.ts"],"names":[],"mappings":";;;
|
1
|
+
{"version":3,"file":"KeycloakVersion.js","sourceRoot":"","sources":["../src/bin/KeycloakVersion.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAU,CAAC"}
|