diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 368bd3cc..4435b228 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -22,7 +22,6 @@ jobs:
PACKAGE_MANAGER=yarn
fi
$PACKAGE_MANAGER run format:check
-
test:
runs-on: macos-10.15
needs: test_formatting
@@ -33,7 +32,7 @@ jobs:
steps:
- name: Tell if project is using npm or yarn
id: step1
- uses: garronej/github_actions_toolkit@v2.2
+ uses: garronej/ts-ci@v1.1.3
with:
action_name: tell_if_project_uses_npm_or_yarn
- uses: actions/checkout@v2.3.4
@@ -51,28 +50,35 @@ jobs:
npm test
check_if_version_upgraded:
name: Check if version upgrade
- if: github.event_name == 'push'
+ # We run this only if it's a push on the default branch or if it's a PR from a
+ # branch (meaning not a PR from a fork). It would be more straightforward to test if secrets.NPM_TOKEN is
+ # defined but GitHub Action don't allow it yet.
+ if: |
+ github.event_name == 'push' ||
+ github.event.pull_request.head.repo.owner.login == github.event.pull_request.base.repo.owner.login
runs-on: ubuntu-latest
needs: test
outputs:
from_version: ${{ steps.step1.outputs.from_version }}
to_version: ${{ steps.step1.outputs.to_version }}
- is_upgraded_version: ${{steps.step1.outputs.is_upgraded_version }}
+ is_upgraded_version: ${{ steps.step1.outputs.is_upgraded_version }}
+ is_release_beta: ${{steps.step1.outputs.is_release_beta }}
steps:
- - uses: garronej/github_actions_toolkit@v2.2
+ - uses: garronej/ts-ci@v1.1.3
id: step1
with:
action_name: is_package_json_version_upgraded
+ branch: ${{ github.head_ref || github.ref }}
update_changelog:
runs-on: ubuntu-latest
needs: check_if_version_upgraded
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true'
steps:
- - uses: garronej/github_actions_toolkit@v2.4
+ - uses: garronej/ts-ci@v1.1.3
with:
action_name: update_changelog
- branch: ${{ github.ref }}
+ branch: ${{ github.head_ref || github.ref }}
create_github_release:
runs-on: ubuntu-latest
@@ -80,9 +86,6 @@ jobs:
- update_changelog
- check_if_version_upgraded
steps:
- - uses: actions/checkout@v2
- with:
- ref: ${{ github.ref }}
- name: Build GitHub release body
id: step1
run: |
@@ -98,10 +101,10 @@ jobs:
with:
name: Release v${{ needs.check_if_version_upgraded.outputs.to_version }}
tag_name: v${{ needs.check_if_version_upgraded.outputs.to_version }}
- target_commitish: ${{ github.ref }}
+ target_commitish: ${{ github.head_ref || github.ref }}
body: ${{ steps.step1.outputs.body }}
draft: false
- prerelease: false
+ prerelease: ${{ needs.check_if_version_upgraded.outputs.is_release_beta == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -138,7 +141,12 @@ jobs:
echo "Can't publish on NPM, You must first create a secret called NPM_TOKEN that contains your NPM auth token. https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets"
false
fi
- npm publish
+ EXTRA_ARGS=""
+ if [ "$IS_BETA" = "true" ]; then
+ EXTRA_ARGS="--tag beta"
+ fi
+ npm publish $EXTRA_ARGS
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
- VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
\ No newline at end of file
+ VERSION: ${{ needs.check_if_version_upgraded.outputs.to_version }}
+ IS_BETA: ${{ needs.check_if_version_upgraded.outputs.is_release_beta }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 76d10b8b..643eb121 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,85 @@
+### **4.5.1** (2022-01-18)
+
+- fix previous version
+
+## **4.5.0** (2022-01-18)
+
+- Read public/CNAME for domain name in --externel-assets mode
+
+## **4.4.0** (2022-01-01)
+
+- Merge pull request #73 from lazToum/main
+
+(feature) added login-page-expired.ftl
+- added login-page-expired.ftl
+- Add update instruction for 4.3.0
+
+## **4.3.0** (2021-12-27)
+
+- Merge pull request #72 from praiz/main
+
+feat(*): added login-update-password
+- feat(*): added login-update-password
+
+### **4.2.21** (2021-12-27)
+
+- update dependencies
+
+### **4.2.19** (2021-12-21)
+
+- Merge pull request #70 from VBustamante/patch-1
+- Added realm name field to KcContext mocks object
+- Merge pull request #69 from VBustamante/patch-1
+
+Adding name field to realm in KcContext type
+- Adding name field to realm in KcContext type
+
+### **4.2.18** (2021-12-17)
+
+- Improve css url() import (fix CRA 5)
+
+### **4.2.17** (2021-12-16)
+
+- Fix path.join polyfill
+
+### **4.2.16** (2021-12-16)
+
+
+
+### **4.2.15** (2021-12-16)
+
+- use custom polyfill for path.join (fix webpack 5 build)
+
+### **4.2.14** (2021-12-12)
+
+- Merge pull request #65 from InseeFrLab/doge_ftl_errors
+
+Prevent ftl errors in Keycloak log
+- Encourage users to report errors in logs
+- Fix ftl error related to url.loginAction in saml-post-form.ftl
+- Ftl prevent error with updateProfileCtx
+- Ftl prevent error with auth.attemptedUsername
+- Fix ftl error as comment formatting
+- Merge remote-tracking branch 'origin/main' into doge_ftl_errors
+- Update README, remove all instruction about errors in logs
+- Avoid error in Keycloak logs, fix long template loading time
+- Add missing collon in README sample code
+
+Add miss ','
+
+### **4.2.13** (2021-12-08)
+
+- Fix broken link about how to import fonts #62
+- Add a video to show how to test the theme in a local container
+
+### **4.2.12** (2021-12-08)
+
+- Update post build instructions
+
+### **4.2.11** (2021-12-07)
+
+
+
### **4.2.10** (2021-11-12)
- Export an exaustive list of KcLanguageTag
diff --git a/README.md b/README.md
index 57e0d08f..a6bdce4c 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,21 @@
๐ Create Keycloak themes using React ๐
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -20,10 +30,9 @@
@@ -228,7 +233,7 @@ If you want to go beyond only customizing the CSS you can re-implement some of t
pages or even add new ones.
If you want to go this way checkout the demo setup provided [here](https://github.com/garronej/keycloakify-demo-app/tree/look_and_feel).
-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).
+If you prefer a real life example you can checkout [onyxia-web's source](https://github.com/InseeFrLab/onyxia-web/tree/main/src/ui/components/KcApp).
The web app is in production [here](https://datalab.sspcloud.fr).
Main takeaways are:
@@ -290,7 +295,7 @@ If you are specifically building a theme to integrate with an app or a website t
to first browse unauthenticated before logging in, you will get a significant
performance boost if you jump through those hoops:
-- 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)
+- 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) or in a `public/CNAME` file. [ex](https://github.com/garronej/keycloakify-demo-app/blob/main/public/CNAME).
- 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)
- Enable [long-term assets caching](https://create-react-app.dev/docs/production-build/#static-file-caching) on the server hosting your app.
- Make sure not to build your app and the keycloak theme separately
@@ -357,7 +362,7 @@ the building and publishing of the theme (the .jar file).
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).
(This isn't recommended anyway).
-## `@font-face` importing fonts from theย `src/` dir
+## `@font-face` importing fonts from the `src/` dir
If you are building the theme with [--external-assets](#enable-loading-in-a-blink-of-a-eye-of-login-pages-)
this limitation doesn't apply, you can import fonts however you see fit.
@@ -373,7 +378,8 @@ this limitation doesn't apply, you can import fonts however you see fit.
- If it is possible, use Google Fonts or any other font provider.
- If you want to host your font recommended approach is to move your fonts into the `public`
directory and to place your `@font-face` statements in the `public/index.html`.
- Example [here](https://github.com/InseeFrLab/onyxia-ui/blob/0e3a04610cfe872ca71dad59e05ced8f785dee4b/public/index.html#L6-L51).
+ Example [here](https://github.com/garronej/keycloakify-demo-app/blob/9aa2dbaec28a7786d6b2983c9a59d393dec1b2d6/public/index.html#L27-L73)
+ (and the font are [here](https://github.com/garronej/keycloakify-demo-app/tree/main/public/fonts/WorkSans)).
- 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).
# Implement context persistence (optional)
@@ -433,33 +439,29 @@ keycloakInstance.init({
If you really want to go the extra miles and avoid having the white
flash of the blank html before the js bundle have been evaluated
-[here is a snippet](https://github.com/InseeFrLab/onyxia-ui/blob/a77eb502870cfe6878edd0d956c646d28746d053/public/index.html#L5-L54) that you can place in your `public/index.html` if you are using `powerhooks/useGlobalState`.
+[here is a snippet](https://github.com/InseeFrLab/onyxia-web/blob/e1c1f309aaa3d5f860df39ba0b75cce89c88a9de/public/index.html#L117-L166) that you can place in your `public/index.html` if you are using `powerhooks/useGlobalState`.
# Kickstart video
_NOTE: keycloak-react-theming was renamed keycloakify since this video was recorded_
[](https://youtu.be/xTz0Rj7i2v8)
-# About the errors related to `objectToJson` in Keycloak logs.
+# FTL errors related to `ftl_object_to_js_code_declaring_an_object` in Keycloak logs.
-The logs of your keycloak server will always show this kind of errors every time a client request a page:
+If you ever encounter one of these errors:
```log
FTL stack trace ("~" means nesting-related):
- - Failed at: #local value = object[key] [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 70, column 21]
- - Reached through: @compress [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 36, column 5]
- - Reached through: @objectToJson_please_ignore_errors object=value depth=(dep... [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 81, column 27]
- - Reached through: @compress [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 36, column 5]
- - Reached through: @objectToJson_please_ignore_errors object=(.data_model) de... [in template "login.ftl" at line 163, column 43]
+ - Failed at: #local value = object[key] [in template "login.ftl" in macro "ftl_object_to_js_code_declaring_an_object" at line 70, column 21]
+ - Reached through: @compress [in template "login.ftl" in macro "ftl_object_to_js_code_declaring_an_object" at line 36, column 5]
+ - Reached through: @ftl_object_to_js_code_declaring_an_object object=value depth=(dep... [in template "login.ftl" in macro "ftl_object_to_js_code_declaring_an_object" at line 81, column 27]
+ - Reached through: @compress [in template "login.ftl" in macro "ftl_object_to_js_code_declaring_an_object" at line 36, column 5]
+ - Reached through: @ftl_object_to_js_code_declaring_an_object object=(.data_model) de... [in template "login.ftl" at line 163, column 43]
```
-Theses are expected to show up in the log.
-Unfortunately, there is nothing I know of that can be done to avoid them or even mute them.
-They can be, however, safely ignored.
-
-To [converts the `.ftl` values into a JavaScript object](https://github.com/InseeFrLab/keycloakify/blob/main/src/bin/build-keycloak-theme/generateFtl/common.ftl)
-without making assumptions on the `.data_model` we have to do things that throws.
-It's all-right because every statement that can fail is inside an `<#attempt><#recorver>` block but it results in errors being printed to the logs.
+It's just noise, they can be safely ignored.
+You can, however, and are encouraged to, report any that you would spot.
+Just open an issue about it and I will release a patched version of Keycloakify in the better delays.
# Adding custom message (to `i18n/useKcMessage.tsx`)
@@ -477,6 +479,10 @@ and `kcRegisterContext["authorizedMailDomains"]` to validate on.
# Changelog highlights
+> **New in v4.3.0**: Feature [`login-update-password.ftl`](https://user-images.githubusercontent.com/6702424/147517600-6191cf72-93dd-437b-a35c-47180142063e.png).
+> Every time a page is added it's a breaking change for non CSS-only theme.
+> Change [this](https://github.com/garronej/keycloakify-demo-app/blob/df664c13c77ce3c53ac7df0622d94d04e76d3f9f/src/KcApp/KcApp.tsx#L17) and [this](https://github.com/garronej/keycloakify-demo-app/blob/df664c13c77ce3c53ac7df0622d94d04e76d3f9f/src/KcApp/KcApp.tsx#L37) to update.
+
## v4
- Out of the box [frontend form validation](#user-profile-and-frontend-form-validation) ๐ฅณ
diff --git a/package.json b/package.json
index 31058b86..4a20108d 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "keycloakify",
- "version": "4.2.10",
+ "version": "4.5.1",
"description": "Keycloak theme generator for Reacts app",
"repository": {
"type": "git",
@@ -58,7 +58,7 @@
"@emotion/react": "^11.4.1",
"powerhooks": "^0.10.0",
"react": "^16.8.0 || ^17.0.0",
- "tss-react": "^1.1.0"
+ "tss-react": "^1.1.0 || ^3.0.0"
},
"devDependencies": {
"@emotion/react": "^11.4.1",
@@ -72,16 +72,16 @@
"properties-parser": "^0.3.1",
"react": "^17.0.1",
"rimraf": "^3.0.2",
- "tss-react": "^1.1.0",
+ "tss-react": "^3.0.0",
"typescript": "^4.2.3"
},
"dependencies": {
"cheerio": "^1.0.0-rc.5",
- "evt": "2.0.0-beta.38",
+ "evt": "2.0.0-beta.39",
"minimal-polyfills": "^2.2.1",
"path-browserify": "^1.0.1",
"react-markdown": "^5.0.3",
"scripting-tools": "^0.19.13",
- "tsafe": "^0.8.1"
+ "tsafe": "^0.9.0"
}
}
diff --git a/src/bin/build-keycloak-theme/build-keycloak-theme.ts b/src/bin/build-keycloak-theme/build-keycloak-theme.ts
index dd599d2b..9ee8a052 100644
--- a/src/bin/build-keycloak-theme/build-keycloak-theme.ts
+++ b/src/bin/build-keycloak-theme/build-keycloak-theme.ts
@@ -4,6 +4,7 @@ import { join as pathJoin, relative as pathRelative, basename as pathBasename }
import * as child_process from "child_process";
import { generateDebugFiles, containerLaunchScriptBasename } from "./generateDebugFiles";
import { URL } from "url";
+import * as fs from "fs";
type ParsedPackageJson = {
name: string;
@@ -41,7 +42,17 @@ export function main() {
const url = (() => {
const { homepage } = parsedPackageJson;
- return homepage === undefined ? undefined : new URL(homepage);
+ if (homepage !== undefined) {
+ return new URL(homepage);
+ }
+
+ const cnameFilePath = pathJoin(reactProjectDirPath, "public", "CNAME");
+
+ if (fs.existsSync(cnameFilePath)) {
+ return new URL(`https://${fs.readFileSync(cnameFilePath).toString("utf8").replace(/\s+$/, "")}`);
+ }
+
+ return undefined;
})();
return {
@@ -121,11 +132,14 @@ export function main() {
"",
`๐ $ ./${pathRelative(reactProjectDirPath, pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename))} ๐`,
"",
- 'To enable the theme within keycloak log into the admin console ( ๐ http://localhost:8080 username: admin, password: admin ๐), create a realm (called "myrealm" for example),',
- `go to your realm settings, click on the theme tab then select ${themeName}.`,
- `More details: https://www.keycloak.org/getting-started/getting-started-docker`,
+ "Once your container is up and running: ",
+ "- Log into the admin console ๐ http://localhost:8080 username: admin, password: admin ๐",
+ '- Create a realm named "myrealm"',
+ '- Create a client with id "myclient" and root url: "https://www.keycloak.org/app/"',
+ `- Select Login Theme: ${themeName} (don't forget to save at the bottom of the page)`,
+ `- Go to ๐ https://www.keycloak.org/app/ ๐ Click "Save" then "Sign in". You should see your login page`,
"",
- "Once your container is up and configured ๐ http://localhost:8080/auth/realms/myrealm/account ๐",
+ "Video demoing this process: https://youtu.be/N3wlBoH4hKg",
"",
].join("\n"),
);
diff --git a/src/bin/build-keycloak-theme/generateFtl/Object.deepAssign.js b/src/bin/build-keycloak-theme/generateFtl/Object.deepAssign.js
deleted file mode 100644
index 028d9990..00000000
--- a/src/bin/build-keycloak-theme/generateFtl/Object.deepAssign.js
+++ /dev/null
@@ -1,28 +0,0 @@
-
-Object.defineProperty(
- Object,
- "deepAssign",
- {
- "value": function callee(target, source) {
- Object.keys(source).forEach(function (key) {
- var value = source[key];
- if (target[key] === undefined) {
- target[key] = value;
- return;
- }
- if (value instanceof Object) {
- if (value instanceof Array) {
- value.forEach(function (entry) {
- target[key].push(entry);
- });
- return;
- }
- callee(target[key], value);
- return;
- }
- target[key] = value;
- });
- return target;
- }
- }
-);
\ No newline at end of file
diff --git a/src/bin/build-keycloak-theme/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl b/src/bin/build-keycloak-theme/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl
new file mode 100644
index 00000000..b1e6627d
--- /dev/null
+++ b/src/bin/build-keycloak-theme/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl
@@ -0,0 +1,290 @@
+
\ No newline at end of file
diff --git a/src/bin/build-keycloak-theme/generateFtl/generateFtl.ts b/src/bin/build-keycloak-theme/generateFtl/generateFtl.ts
index 36bd7eac..f2bd3b95 100644
--- a/src/bin/build-keycloak-theme/generateFtl/generateFtl.ts
+++ b/src/bin/build-keycloak-theme/generateFtl/generateFtl.ts
@@ -16,15 +16,13 @@ export const pageIds = [
"terms.ftl",
"login-otp.ftl",
"login-update-profile.ftl",
+ "login-update-password.ftl",
"login-idp-link-confirm.ftl",
+ "login-page-expired.ftl",
] as const;
export type PageId = typeof pageIds[number];
-function loadAdjacentFile(fileBasename: string) {
- return fs.readFileSync(pathJoin(__dirname, fileBasename)).toString("utf8");
-}
-
export function generateFtlFilesCodeFactory(params: {
cssGlobalsToDefine: Record
+ {msg("pageExpiredMsg1")}
+
+ {msg("doClickHere")}
+ {" "}
+ .
+ {msg("pageExpiredMsg2")}{" "}
+
+ {msg("doClickHere")}
+ {" "}
+ .
+