Skip to content

Commit 8a670ba

Browse files
committed
feat(upgrade): upgrade keycloakify to v11
1 parent e0b88ab commit 8a670ba

File tree

7 files changed

+107
-284
lines changed

7 files changed

+107
-284
lines changed

README.md

Lines changed: 24 additions & 196 deletions
Original file line numberDiff line numberDiff line change
@@ -1,223 +1,51 @@
11
<p align="center">
2-
<i>🚀 A starter/demo project for <a href="https://keycloakify.dev">Keycloakify</a> v9 🚀</i>
2+
<i>🚀 <a href="https://keycloakify.dev">Keycloakify</a> v11 starter 🚀</i>
33
<br/>
44
<br/>
5-
<img src="https://github.com/codegouvfr/keycloakify-starter/workflows/ci/badge.svg?branch=main">
6-
<br/>
7-
<br/>
8-
<a href="https://starter.keycloakify.dev">Authenticated React SPA</a>
95
</p>
106

11-
# Introduction
12-
13-
This repo constitutes an easily reusable setup for a Keycloak theme project OR for a Vite SPA React App that generates a
14-
Keycloak theme that goes along with it.
15-
If you are only looking to create a Keycloak theme (and not a Keycloak theme and an App that share the same codebase) there are a lot of things that you can remove from this starter: [Please read this section of the README](#standalone-keycloak-theme).
16-
17-
This starter is based on Vite. There is also [a Webpack based starter](https://github.com/keycloakify/keycloakify-starter-cra).
18-
19-
> 📣 Looking for a library for redirecting your user to Keycloak when they click on the 'Login' button?
20-
> Check out [oidc-spa](https://oidc-spa.dev) It's made by us and it's used in the [src/App](https://github.com/keycloakify/keycloakify-starter/tree/main/src/App) of this starter.
21-
227
# Quick start
238

249
```bash
2510
git clone https://github.com/keycloakify/keycloakify-starter
26-
2711
cd keycloakify-starter
28-
29-
yarn # install dependencies (it's like npm install)
30-
31-
yarn storybook # Start Storybook
32-
# This is by far the best way to develop your theme
33-
# This enable to quickly see your pages in isolation and in different states.
34-
# You can create stories even for pages that you haven't explicitly overloaded. See src/keycloak-theme/login/pages/LoginResetPassword.stories.tsx
35-
# See Keycloakify's storybook for if you need a starting point for your stories: https://github.com/keycloakify/keycloakify/tree/main/stories
36-
37-
yarn dev # See the Hello World app
38-
# Uncomment line 97 of src/keycloak-theme/login/kcContext where it reads: `mockPageId: "login.ftl"`, reload https://localhost:3000
39-
# You can now see the login.ftl page with the mock data. (Don't forget to comment it back when you're done)
40-
41-
# Install mvn (Maven) if not already done. On mac it's 'brew install maven', on Ubuntu/Debian it's 'sudo apt-get install maven'
42-
43-
yarn build-keycloak-theme # Actually build the theme (generates the .jar to be imported in Keycloak)
44-
# Read the instruction printed on the console to see how to test
45-
# your theme on a real Keycloak instance.
46-
47-
npx eject-keycloak-page # Prompt that let you select the pages you want to customize
48-
# This CLI tools is not guaranty to work, you can always copy paste pages
49-
# from the Keycloakify repo.
50-
# After you ejected a page you need to edit the src/keycloak-theme/login(or admin)/KcApp.tsx file
51-
# You need to add a case in the switch for the page you just imported in your project.
52-
# Look how it's done for the Login page and replicate for your new page.
53-
54-
npx initialize-email-theme # For initializing your email theme
55-
# Note that Keycloakify does not feature React integration for email yet.
56-
57-
npx download-builtin-keycloak-theme # For downloading the default theme (as a reference)
58-
# Look for the files in dist_keycloak/src/main/resources/theme/{base,keycloak}
12+
yarn install # Or use an other package manager, just be sure to delete the yarn.lock if you use another package manager.
5913
```
6014

61-
# Theme variant
15+
# Testing the theme locally
6216

63-
Keycloakify enables you to create different variant for a single theme.
64-
This enable you to have a single jar that embed two or more theme variant.
17+
[Documentation](https://docs.keycloakify.dev/testing-your-theme)
6518

66-
![Theme variant](https://content.gitbook.com/content/FcBKODbZbNDgm0rc6a9K/blobs/9iKgs2rv2Kfb2pbs4dRz/image.png)
19+
# How to customize the theme
6720

68-
You can enable this feature by providing multiple theme name in the Keycloakify build option.
69-
[See documentation](https://docs.keycloakify.dev/build-options#themename)
21+
[Documentation](https://docs.keycloakify.dev/customization-strategies)
7022

71-
# The CI workflow
23+
# Building the theme
7224

73-
- To release **don't create a tag manually**, the CI do it for you. Just update the `package.json`'s version field and push.
74-
- The `.jar` files that bundle the Keycloak theme will be attached as an asset with every GitHub release. [Example](https://github.com/InseeFrLab/keycloakify-starter/releases/tag/v0.1.0). The permalink to download the latest version is: `https://github.com/USER/PROJECT/releases/latest/download/keycloak-theme.jar`.
75-
For this demo repo it's [here](https://github.com/codegouvfr/keycloakify-starter/releases/latest/download/keycloak-theme.jar)
76-
- This CI is configured to publish [the app](https://starter.keycloakify.dev) on [GitHub Pages](https://github.com/codegouvfr/keycloakify-starter/blob/3617a71deb1a6544c3584aa8d6d2241647abd48c/.github/workflows/ci.yaml#L51-L76) and on [DockerHub](https://github.com/codegouvfr/keycloakify-starter/blob/3617a71deb1a6544c3584aa8d6d2241647abd48c/.github/workflows/ci.yaml#L78-L123) (as a Ngnix based docker image). In practice you probably want one or the other but not both... or neither if you are just building a theme (and not a theme + an app).
77-
If you want to enable the CI to publish on DockerHub on your behalf go to repository `Settings` tab, then `Secrets` you will need to add two new secrets:
78-
`DOCKERHUB_TOKEN`, you Dockerhub authorization token.
79-
`DOCKERHUB_USERNAME`, Your Dockerhub username.
80-
We deploy the demo app at [starter.keycloakify.dev](https://starter.keycloakify.dev) using GitHub page on the branch `gh-pages` (you have to enable it).
81-
To configure your own domain name update the homepage field of the `package.json` and potentially the `base` option in the `vite.config.ts`.
82-
Regarding DNS configuration you can refer to [this documentation](https://docs.gitlanding.dev/using-a-custom-domain-name).
83-
- The CI publishes the app docker image on DockerHub. `<org>/<repo>:main` for each **commit** on `main`, `<org>/<repo>:<feature-branch-name>` for each **pull-request** on `main`
84-
and when **releasing a new version**: `<org>/<repo>:latest` and `<org>/<repo>:X.Y.Z`
85-
[See on DockerHub](https://hub.docker.com/r/codegouvfr/keycloakify-starter)
25+
You need to have [Maven](https://maven.apache.org/) installed to build the theme (Maven >= 3.1.1, Java >= 7).
26+
The `mvn` command must be in the $PATH.
8627

87-
![image](https://user-images.githubusercontent.com/6702424/229296422-9d522707-114e-4282-93f7-01ca38c3a1e0.png)
28+
- On macOS: `brew install maven`
29+
- On Debian/Ubuntu: `sudo apt-get install maven`
30+
- On Windows: `choco install openjdk` and `choco install maven` (Or download from [here](https://maven.apache.org/download.cgi))
8831

89-
![image](https://user-images.githubusercontent.com/6702424/229296556-a69f2dc9-4653-475c-9c89-d53cf33dc05a.png)
90-
91-
# The storybook
92-
93-
![image](https://github.com/keycloakify/keycloakify/assets/6702424/a18ac1ff-dcfd-4b8c-baed-dcda5aa1d762)
32+
You can build the keycloak theme (to be imported over to Coursemology2 repo) by executing the following command
9433

9534
```bash
96-
yarn
97-
yarn storybook
35+
yarn build-keycloak-theme
9836
```
9937

100-
# Docker
38+
Note that by default Keycloakify generates multiple .jar files for different versions of Keycloak.
39+
You can customize this behavior, see documentation [here](https://docs.keycloakify.dev/targeting-specific-keycloak-versions).
10140

102-
Instructions for building and running the react app (`src/App`) that is collocated with our Keycloak theme.
41+
For us in Coursemology, since we currently use Keycloak v24, then we use the one with suffix `kc-22-to-25.jar`.
42+
To keep things consistent with how we build the Keycloak Theme in Coursemology, we renamed that file into `coursemology-keycloakify-keycloak-theme-{version-number}.jar`
10343

104-
```bash
105-
docker build -f Dockerfile -t keycloakify/keycloakify-starter:main .
106-
docker run -it -dp 8083:80 keycloakify/keycloakify-starter:main
107-
# You can access the app at http://localhost:8083
108-
```
109-
110-
# I only want a Keycloak theme
111-
112-
If you are only looking to create a Keycloak theme and not a Theme + a React app, you can run theses few commands to refactor the template
113-
and remove unnecessary files.
44+
# GitHub Actions
11445

115-
```bash
116-
cd path/to/keycloakify-starter
117-
rm -r src/App
118-
mv src/keycloak-theme/* src/
119-
rm -r src/keycloak-theme
120-
121-
cat << EOF > src/main.tsx
122-
import { createRoot } from "react-dom/client";
123-
import { StrictMode, lazy, Suspense } from "react";
124-
import { kcContext as kcLoginThemeContext } from "./login/kcContext";
125-
import { kcContext as kcAccountThemeContext } from "./account/kcContext";
126-
127-
const KcLoginThemeApp = lazy(() => import("./login/KcApp"));
128-
const KcAccountThemeApp = lazy(() => import("./account/KcApp"));
129-
130-
createRoot(document.getElementById("root")!).render(
131-
<StrictMode>
132-
<Suspense>
133-
{(()=>{
134-
135-
if( kcLoginThemeContext !== undefined ){
136-
return <KcLoginThemeApp kcContext={kcLoginThemeContext} />;
137-
}
138-
139-
if( kcAccountThemeContext !== undefined ){
140-
return <KcAccountThemeApp kcContext={kcAccountThemeContext} />;
141-
}
142-
143-
throw new Error(
144-
"This app is a Keycloak theme" +
145-
"It isn't meant to be deployed outside of Keycloak"
146-
);
147-
148-
})()}
149-
</Suspense>
150-
</StrictMode>
151-
);
152-
153-
EOF
154-
155-
rm .dockerignore Dockerfile nginx.conf
156-
157-
cat << EOF > .github/workflows/ci.yaml
158-
name: ci
159-
on:
160-
push:
161-
branches:
162-
- main
163-
pull_request:
164-
branches:
165-
- main
166-
167-
jobs:
168-
169-
test:
170-
runs-on: ubuntu-latest
171-
steps:
172-
- uses: actions/checkout@v2
173-
- uses: actions/setup-node@v2
174-
- uses: bahmutov/npm-install@v1
175-
- run: yarn build
176-
- run: npx keycloakify
177-
178-
check_if_version_upgraded:
179-
name: Check if version upgrade
180-
if: github.event_name == 'push'
181-
runs-on: ubuntu-latest
182-
needs: test
183-
outputs:
184-
from_version: \${{ steps.step1.outputs.from_version }}
185-
to_version: \${{ steps.step1.outputs.to_version }}
186-
is_upgraded_version: \${{ steps.step1.outputs.is_upgraded_version }}
187-
steps:
188-
- uses: garronej/[email protected]
189-
id: step1
190-
with:
191-
action_name: is_package_json_version_upgraded
192-
branch: \${{ github.head_ref || github.ref }}
193-
194-
create_github_release:
195-
runs-on: ubuntu-latest
196-
needs: check_if_version_upgraded
197-
# We create a release only if the version have been upgraded and we are on a default branch
198-
if: needs.check_if_version_upgraded.outputs.is_upgraded_version == 'true' && github.event_name == 'push'
199-
steps:
200-
- uses: actions/checkout@v2
201-
- uses: actions/setup-node@v2
202-
- uses: bahmutov/npm-install@v1
203-
- run: yarn build
204-
- run: npx keycloakify
205-
- run: mv dist_keycloak/target/retrocompat-*.jar retrocompat-keycloak-theme.jar
206-
- run: mv dist_keycloak/target/*.jar keycloak-theme.jar
207-
- uses: softprops/action-gh-release@v1
208-
with:
209-
name: Release v\${{ needs.check_if_version_upgraded.outputs.to_version }}
210-
tag_name: v\${{ needs.check_if_version_upgraded.outputs.to_version }}
211-
target_commitish: \${{ github.head_ref || github.ref }}
212-
generate_release_notes: true
213-
draft: false
214-
files: |
215-
retrocompat-keycloak-theme.jar
216-
keycloak-theme.jar
217-
env:
218-
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
219-
220-
EOF
221-
```
46+
The starter comes with a generic GitHub Actions workflow that builds the theme and publishes
47+
the jars [as GitHub releases artifacts](https://github.com/keycloakify/keycloakify-starter/releases/tag/v10.0.0).
48+
To release a new version **just update the `package.json` version and push**.
22249

223-
You can also remove `oidc-spa`, `powerhooks`, `zod` and `tsafe` from your dependencies.
50+
To enable the workflow go to your fork of this repository on GitHub then navigate to:
51+
`Settings` > `Actions` > `Workflow permissions`, select `Read and write permissions`.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"@emotion/react": "^11.13.5",
3030
"@emotion/styled": "^11.13.5",
3131
"framer-motion": "^11.2.0",
32-
"keycloakify": "^10.1.6",
32+
"keycloakify": "^11.8.9",
3333
"react": "^18.3.1",
3434
"react-dom": "^18.3.1"
3535
},

src/kc.gen.tsx

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
/* prettier-ignore-start */
1+
// This file is auto-generated by the `update-kc-gen` command. Do not edit it manually.
2+
// Hash: 9ae0fc6db02c7aaca5511c810584dc11912602c9a6a8c8f778a301e8e52807fc
23

34
/* eslint-disable */
45

56
// @ts-nocheck
67

78
// noinspection JSUnusedGlobalSymbols
89

9-
// This file is auto-generated by Keycloakify
10-
1110
import { lazy, Suspense, type ReactNode } from "react";
1211

1312
export type ThemeName = "coursemology-keycloakify";
@@ -19,37 +18,34 @@ export type KcEnvName = "MY_ENV_VARIABLE";
1918
export const kcEnvNames: KcEnvName[] = ["MY_ENV_VARIABLE"];
2019

2120
export const kcEnvDefaults: Record<KcEnvName, string> = {
22-
"MY_ENV_VARIABLE": ""
21+
MY_ENV_VARIABLE: "",
2322
};
2423

25-
export type KcContext =
26-
| import("./login/KcContext").KcContext
27-
;
24+
/**
25+
* NOTE: Do not import this type except maybe in your entrypoint.
26+
* If you need to import the KcContext import it either from src/login/KcContext.ts or src/account/KcContext.ts.
27+
* Depending on the theme type you are working on.
28+
*/
29+
export type KcContext = import("./login/KcContext").KcContext;
2830

2931
declare global {
30-
interface Window {
31-
kcContext?: KcContext;
32-
}
32+
interface Window {
33+
kcContext?: KcContext;
34+
}
3335
}
3436

3537
export const KcLoginPage = lazy(() => import("./login/KcPage"));
3638

37-
export function KcPage(
38-
props: {
39-
kcContext: KcContext;
40-
fallback?: ReactNode;
41-
}
42-
) {
43-
const { kcContext, fallback } = props;
44-
return (
45-
<Suspense fallback={fallback}>
46-
{(() => {
47-
switch (kcContext.themeType) {
48-
case "login": return <KcLoginPage kcContext={kcContext} />;
49-
}
50-
})()}
51-
</Suspense>
52-
);
39+
export function KcPage(props: { kcContext: KcContext; fallback?: ReactNode }) {
40+
const { kcContext, fallback } = props;
41+
return (
42+
<Suspense fallback={fallback}>
43+
{(() => {
44+
switch (kcContext.themeType) {
45+
case "login":
46+
return <KcLoginPage kcContext={kcContext} />;
47+
}
48+
})()}
49+
</Suspense>
50+
);
5351
}
54-
55-
/* prettier-ignore-end */

src/login/Template.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Original file: https://github.com/InseeFrLab/keycloakify/blob/main/src/login/Template.tsx
22

3+
import { kcSanitize } from "keycloakify/lib/kcSanitize";
34
import { type TemplateProps as KeycloakTemplateProps } from "keycloakify/login/TemplateProps";
45

56
import AlertBox from "src/lib/components/core/AlertBox";
@@ -21,9 +22,9 @@ const Template = (props: KeycloakTemplateProps<KcContext, I18n>) => {
2122
children,
2223
} = props;
2324

24-
const { msg } = i18n;
25+
const { msg, enabledLanguages } = i18n;
2526

26-
const { realm, locale, message, isAppInitiatedAction } = kcContext;
27+
const { realm, message, isAppInitiatedAction } = kcContext;
2728
const { homeUrl } = useCoursemologyUrls();
2829

2930
return (
@@ -33,9 +34,7 @@ const Template = (props: KeycloakTemplateProps<KcContext, I18n>) => {
3334
textNode={msg("loginTitleHtml", realm.displayNameHtml)}
3435
brandUrl={homeUrl}
3536
/>
36-
{realm.internationalizationEnabled && (
37-
<LocaleDropdown locale={locale} i18n={i18n} />
38-
)}
37+
{enabledLanguages.length > 1 && <LocaleDropdown i18n={i18n} />}
3938
</header>
4039

4140
<div className="relative h-full">
@@ -48,7 +47,7 @@ const Template = (props: KeycloakTemplateProps<KcContext, I18n>) => {
4847
<AlertBox status={message.type}>
4948
<span
5049
dangerouslySetInnerHTML={{
51-
__html: message.summary,
50+
__html: kcSanitize(message.summary),
5251
}}
5352
/>
5453
</AlertBox>

0 commit comments

Comments
 (0)