diff --git a/README.md b/README.md index ec5508c8..e18ae3d7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

- Provides a way to customize Keycloak login and register pages with React + 🔏 Keycloak theme generator for Reacts app💅

@@ -10,31 +10,87 @@

-

- Home - - - Documentation -

-# REQUIREMENT -## For building the theme: +# MOTIVATION -- `mvn` must be installed +The problem: -## For development, (testing the theme on a docker container ect ): +![keycloak_before](https://user-images.githubusercontent.com/6702424/108838381-dbbbcf80-75d3-11eb-8ae8-db41563ef9db.gif) -- `rm` -- `mkdir` ) -- `wget` -- `unzip` +When we redirected to Keycloak the user suffers from a harsh context switch. +The language is set back to default and the theme is different, -Tested on MacOS +Keycloak does offer a way to customize the theme of theses pages but it will require a lot of raw HTML/CSS hacking +to reproduce the look and feel of your app. Not mentioning the maintenance cost of such an endeavour. -# USAGE +Wouldn't it be great if we could just design the login and register pages as if they where part of our app while +still letting Keycloak handle the heavy lifting of actually authenticating the users? -## Build the theme: -`npx build-keycloak-theme` +Here is `yarn add keycloak-react-theming` for you 🍸 -## (Optional/Debug) Download more themes: +![image](https://user-images.githubusercontent.com/6702424/108833938-c9d72e00-75cd-11eb-8263-4334ca79275c.png) +![image](https://user-images.githubusercontent.com/6702424/108834054-f68b4580-75cd-11eb-9661-b1a43836c4b0.png) +![image](https://user-images.githubusercontent.com/6702424/108834220-32bea600-75ce-11eb-9e11-7661188beb7c.png) -`npx download-sample-keycloak-themes` +# How to use + +## Setting up the build tool + +Add `keycloak-react-theming` to the dev dependencies of your project `npm install --save-dev keycloak-react-theming` or `yarn add --dev keycloak-react-theming` +then configure your `package.json` build's script to build the keycloak's theme by adding `&& build-keycloak-theme`. + +Typically you will get: + +`package.json`: +```json + "devDependencies": { + "keycloak-react-theming": "^0.0.10", + [...] + }, + "scripts": { + "build": "react-scripts build && build-keycloak-theme", + [...] + }, +``` + +Then build your app with `yarn run build` or `npm run build`, you will be provided with instructions +about how to load the theme into Keycloak. + +## Developing your login and register pages in your React app + +TODO + +# How to implement context persistance + +If you want dark mode preference, language and others users preferences your can do so +very easily by using [`powerhooks/useGlobalState`](https://github.com/garronej/powerhooks) + +WARNING: `powerhooks` is still a work in progress. + +# REQUIREMENTS + +This tools assumes you are bundling your app with Webpack (tested with 4.44.2) . +It assumes there is a `build/` directory at the root of your react project directory containing a `index.html` file +and a `static/` directory generated by webpack. + +**All this is defaults with [`create-react-app`](https://create-react-app.dev)** (tested with 4.0.3=) + +- For building the theme: `mvn` (Maven) must be installed +- For development, (testing the theme in a local container ): `rm`, `mkdir`, `wget`, `unzip` are assumed to be available. + +NOTE: This build tool has only be tested on MacOS. + +# API Reference + +## The build tool + +Part of the lib that runs with node, at build time. + +- `npx build-keycloak-theme`: Builds the theme, the CWD is assumed to be the root of your react project. +- `npx download-sample-keycloak-themes`: Downloads the keycloak default themes (for development purposes) + +## The fronted lib ( imported into your react + +Part of the lib that you import in your react project and runs on the browser. + +**TODO** diff --git a/package-lock.json b/package-lock.json index a1972c19..1ce57605 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "keycloak-react-theming", - "version": "0.0.10", + "version": "0.0.11", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.0.10", + "version": "0.0.11", "license": "MIT", "dependencies": { "cheerio": "^1.0.0-rc.5" diff --git a/package.json b/package.json index 45b404c2..a9d81f77 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "keycloak-react-theming", - "version": "0.0.10", - "description": "Provides a way to customize Keycloak login and register pages with React", + "version": "0.0.11", + "description": "Keycloak theme generator for Reacts app", "repository": { "type": "git", "url": "git://github.com/garronej/keycloak-react-theming.git" diff --git a/src/bin/build-keycloak-theme/generateDebugFiles/index.ts b/src/bin/build-keycloak-theme/generateDebugFiles/index.ts index b50abae7..370f0468 100644 --- a/src/bin/build-keycloak-theme/generateDebugFiles/index.ts +++ b/src/bin/build-keycloak-theme/generateDebugFiles/index.ts @@ -2,6 +2,8 @@ import * as fs from "fs"; import { join as pathJoin, dirname as pathDirname, basename as pathBasename } from "path"; +export const containerLaunchScriptBasename = "start_keycloak_testing_container.sh"; + /** Files for being able to run a hot reload keycloak container */ export function generateDebugFiles( params: { @@ -34,7 +36,7 @@ export function generateDebugFiles( const containerName = "keycloak-testing-container"; fs.writeFileSync( - pathJoin(keycloakThemeBuildingDirPath, "start_keycloak_testing_container.sh"), + pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename), Buffer.from( [ "#!/bin/bash", diff --git a/src/bin/build-keycloak-theme/generateJavaStackFiles.ts b/src/bin/build-keycloak-theme/generateJavaStackFiles.ts index b67639cc..da37bb6e 100644 --- a/src/bin/build-keycloak-theme/generateJavaStackFiles.ts +++ b/src/bin/build-keycloak-theme/generateJavaStackFiles.ts @@ -14,7 +14,7 @@ export function generateJavaStackFiles( parsedPackageJson: ParsedPackageJson; keycloakThemeBuildingDirPath: string; } -): void { +): { jarFilePath: string; } { const { parsedPackageJson: { name, version, homepage }, @@ -94,5 +94,7 @@ export function generateJavaStackFiles( } + return { "jarFilePath": pathJoin(keycloakThemeBuildingDirPath, "target", `${name}-${version}.jar`) }; + } diff --git a/src/bin/build-keycloak-theme/index.ts b/src/bin/build-keycloak-theme/index.ts index e4317609..b99c1d13 100644 --- a/src/bin/build-keycloak-theme/index.ts +++ b/src/bin/build-keycloak-theme/index.ts @@ -3,9 +3,10 @@ import { generateKeycloakThemeResources } from "./generateKeycloakThemeResources"; import { generateJavaStackFiles } from "./generateJavaStackFiles"; import type { ParsedPackageJson } from "./generateJavaStackFiles"; -import { join as pathJoin } from "path"; +import { join as pathJoin, relative as pathRelative, basename as pathBasename } from "path"; import * as child_process from "child_process"; -import { generateDebugFiles } from "./generateDebugFiles"; +import { generateDebugFiles, containerLaunchScriptBasename } from "./generateDebugFiles"; + const reactProjectDirPath = process.cwd(); @@ -13,6 +14,9 @@ const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPat export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak"); + +console.log("🔏 Building the keycloak theme...⌚"); + if (require.main === module) { generateKeycloakThemeResources({ @@ -21,7 +25,7 @@ if (require.main === module) { "themeName": parsedPackageJson.name }); - generateJavaStackFiles({ + const { jarFilePath } = generateJavaStackFiles({ parsedPackageJson, keycloakThemeBuildingDirPath }); @@ -36,4 +40,36 @@ if (require.main === module) { "packageJsonName": parsedPackageJson.name }); + console.log([ + '', + `✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`, + `It is to be placed in "/opt/jboss/keycloak/standalone/deployments" in the container running a jboss/keycloak Docker image. (Tested with 11.0.3)`, + '', + 'Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:', + '', + 'value.yaml: ', + ' extraInitContainers: |', + ' - name: realm-ext-provider', + ' image: curlimages/curl', + ' imagePullPolicy: IfNotPresent', + ' command:', + ' - sh', + ' args:', + ' - -c', + ` - curl -L -f -S -o /extensions/${pathBasename(jarFilePath)} https://AN.URL.FOR/${pathBasename(jarFilePath)}`, + ' volumeMounts:', + ' - name: extensions', + ' mountPath: /extensions', + ' ', + ' extraVolumeMounts: |', + ' - name: extensions', + ' mountPath: /opt/jboss/keycloak/standalone/deployments', + '', + `To enable the theme within keycloak log into the admin console, go to your realm settings, click on the theme tab then select ${parsedPackageJson.name} `, + '', + 'To test your theme locally you can spin up a Keycloak container image with the theme loaded by running:', + '', + `$ ./${pathRelative(reactProjectDirPath, pathJoin(keycloakThemeBuildingDirPath, containerLaunchScriptBasename))}` + ].join("\n")); + }