Git Product home page Git Product logo

keycloakify's Introduction

πŸ” Create Keycloak themes using React πŸ”

Home - Documentation - Storybook - Starter project

This build tool generates a Keycloak theme Learn more

Keycloakify is fully compatible with Keycloak 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 and up!

NOTE: Keycloak 24 introduces important changes.
We're actively working on incorporating them into Keycloakify. Follow progress.

Sponsor

We are exclusively sponsored by Cloud IAM, a French company offering Keycloak as a service.
Their dedicated support helps us continue the development and maintenance of this project.

Cloud IAM provides the following services:

  • Simplify and secure your Keycloak Identity and Access Management. Keycloak as a Service.
  • Custom theme building for your brand using Keycloakify.

Logo Dark

Logo Light

Checkout Cloud-IAM and use promo code keycloakify5
5% of your annual subscription will be donated to us, and you'll get 5% off too.

Thank you, Cloud-IAM, for your support!

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Waldemar Reusch
Waldemar Reusch

πŸ’»
William Will
William Will

πŸ’»
Bystrova Ann
Bystrova Ann

πŸ’»
Michael Kreuzmayr
Michael Kreuzmayr

πŸ’»
Mary
Mary

πŸ’»
German Γ–ΓΆ
German Γ–ΓΆ

πŸ’»
Julien Bouquillon
Julien Bouquillon

πŸ’»
Aidan Gilmore
Aidan Gilmore

πŸ’»
Void
Void

πŸ’»
juffe
juffe

πŸ’»
Lazaros Toumanidis
Lazaros Toumanidis

πŸ’»
Marc
Marc

πŸ’»
Kasir Barati
Kasir Barati

πŸ“–
Alex Oliynyk
Alex Oliynyk

πŸ’»
Thomas Silvestre
Thomas Silvestre

πŸ’»
satanshiro
satanshiro

πŸ’»
Koen Poelhekke
Koen Poelhekke

πŸ’»
Sergey Kupletsky
Sergey Kupletsky

⚠️ πŸ’»
rome-user
rome-user

πŸ’»
CΓ©line Pelletier
CΓ©line Pelletier

πŸ’»
Garth
Garth

πŸ’»
Felix Gustavsson
Felix Gustavsson

πŸ’»
Markus Siemens
Markus Siemens

πŸ’»
Rlok
Rlok

πŸ’»
Moulyy
Moulyy

πŸ’»
giorgoslytos
giorgoslytos

πŸ’»

Changelog highlights

9.5

  • Post build hook: You can now apply custom transformation to your theme files. Learn more.
  • You can now specify your option in the Keycloakify's Vite plugin instead in the package.json. See example.

9.4

Vite Support! πŸŽ‰

9.0

Bring back support for account themes in Keycloak v23 and up! See issue.

Breaking changes

Very few. Check them out here.

8.0

  • Much smaller .jar size. 70.2 MB -> 7.8 MB.
    Keycloakify now detects which of the static resources from the default theme are actually used by your theme and only include those in the .jar.
  • Build time: The first build is slowed but the subsequent build are faster. Update your CI so that the cache is persisted across CI build.

Breaking changes

There are very few breaking changes in this major version. Check them out.

7.15

  • The i18n messages you defines in your theme are now also maid available to Keycloak. In practice this mean that you can now customize the kcContext.message.summary that display a general alert and the values returned by kcContext.messagesPerField.get() that are used to display specific error on some field of the form. See video

7.14

  • Deprecate the extraPages build option. Keycloakify is now able to analyze your code to detect extra pages.

7.13

7.12

  • You can now pack multiple themes variant in a single .jar bundle. In vanilla Keycloak themes you have the ability to extend a base theme. There is now an idiomatic way of achieving the same result. Learn more.

7.9

  • Separate script for copying the default theme static assets to the public directory.
    Theses assets are only needed for testing your theme locally in Storybook or with a mockPageId.
    You are now expected to have a "prepare": "copy-keycloak-resources-to-public", in your package.json scripts.
    This script will create public/keycloak-assets when you run yarn install (If you are using another package manager like pnpm makes sure that "prepare" is actually ran.)
    See the updated starter. public/keycloak-assets shouldn't be tracked by GIT and is automatically ignored.

7.7

7.0 🍾

  • Account theme support πŸš€
  • It's much easier to customize pages at the CSS level, you can now see in the browser dev tool the customizable classes.
  • New interactive CLI tool npx eject-keycloak-page, that enables to select the page you want to customize at the component level.
  • There is a Storybook
  • Remember me is fixed

6.13

  • Build work behind corporate proxies, see issue.

6.12

Massive improvement in the developer experience:

6.11.4

  • You no longer need to have Maven installed to build the theme. Thanks to @lordvlad, see PR.
  • Feature new build options: bundler, groupId, artifactId, version.
    Theses options can be user to customize the output name of the .jar. You can use environnement variables to overrides the values read in the package.json. Thanks to @lordvlad.

6.10.0

  • Widows compat (thanks to @lordvlad, see PR). WSL is no longer required πŸŽ‰

6.8.4

  • @emotion/react is no longer a peer dependency of Keycloakify.

6.8.0

  • It is now possible to pass a custom <Template /> component as a prop to <KcApp /> and every individual page (<Login />, <RegisterUserProfile />, ...) it enables to customize only the header and footer for example without having to switch to a full-component level customization. See issue.

6.7.0

  • Add support for webauthn-authenticate.ftl thanks to @mstrodl's hacktoberfest PR.

6.6.0

  • Add support for login-password.ftl thanks to @mstrodl's hacktoberfest PR.

6.5.0

  • Add support for login-username.ftl thanks to @mstrodl's hacktoberfest PR.

6.4.0

  • You can now optionally pass a doFetchDefaultThemeResources: boolean prop to every page component and the default <KcApp /> 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.

6.0.0

  • Bundle size drastically reduced, locals and component dynamically loaded.
  • First print much quicker, use of React.lazy() everywhere.
  • Real i18n API.
  • Actual documentation for build options.

Checkout the migration guide

5.8.0

5.7.0

  • Feat logout-confirm.ftl. PR

5.6.4

Fix login-verify-email.ftl page. Before - After

5.6.0

Add support for login-config-totp.ftl page #127.

5.3.0

Rename keycloak_theme_email to keycloak_email.
If you already had a keycloak_theme_email you should rename it keycloak_email.

5.0.0

Migration guide
New i18n system.
Import of terms and services have changed. See example.

4.10.0

Add login-idp-link-email.ftl page See PR.

4.8.0

Email template customization.

4.7.4

M1 Mac support (for testing locally with a dockerized Keycloak).

4.7.2

WARNING: This is broken.
Testing with local Keycloak container working with M1 Mac. Thanks to @eduardosanzb.
Be aware: When running M1s you are testing with Keycloak v15 else the local container spun will be a Keycloak v16.1.0.

4.7.0

Register with user profile enabled: Out of the box options validator support.
Example

4.6.0

tss-react and powerhooks are no longer peer dependencies of keycloakify. After updating Keycloakify you can remove tss-react and powerhooks from your dependencies if you don't use them explicitly.

4.5.3

There is a new recommended way to setup highly customized theme. See here.
Unlike with the previous recommended method, with this new method your theme wont break on minor Keycloakify update.

4.3.0

Feature login-update-password.ftl.
Every time a page is added it's a breaking change for non CSS-only theme.
Change this and this to update.

4

  • Out of the box frontend form validation πŸ₯³
  • Improvements (and breaking changes in import { useKcMessage } from "keycloakify".

3

No breaking changes except that @emotion/react, tss-react and powerhooks are now peerDependencies instead of being just dependencies.
It's important to avoid problem when using keycloakify alongside mui and when passing params from the app to the login page.

2.5

2

  • It's now possible to implement custom .ftl pages.
  • Support for Keycloak plugins that introduce non standard ftl values. (Like for example this plugin that define authorizedMailDomains in register.ftl).

keycloakify's People

Contributors

0x-void avatar actions-user avatar aidangilmore avatar allcontributors[bot] avatar ann2827 avatar cahuzacf avatar celinepelletier avatar devrebs avatar dro-sh avatar garronej avatar giorgoslytos avatar kpoelhekke avatar law108000 avatar laztoum avatar lordvlad avatar marcmrf avatar mkreuzmayr avatar msiemens avatar mstrodl avatar pdossantosdocaposte avatar renovate[bot] avatar romcol avatar rome-user avatar satanshiro avatar schlich avatar tasyp avatar thosil avatar vbustamante avatar willwill96 avatar zavoloklom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keycloakify's Issues

Unable to launch on Apple M1

Hello,

I have build a Keycloak theme but when I try to launch the docker container I am facing the following issues (see below). Do you know how could I solve this problem? Thank you

09:31:08,790 ERROR [org.jboss.modcluster] (ServerService Thread Pool -- 60) MODCLUSTER000034: Failed to start advertise listener: java.net.SocketException: Protocol not available (Error setting socket option) at java.base/java.net.PlainDatagramSocketImpl.socketSetOption0(Native Method) at java.base/java.net.PlainDatagramSocketImpl.socketSetOption(PlainDatagramSocketImpl.java:91) at java.base/java.net.AbstractPlainDatagramSocketImpl.setOption(AbstractPlainDatagramSocketImpl.java:352) at java.base/java.net.MulticastSocket.setInterface(MulticastSocket.java:477) at [email protected]//org.jboss.modcluster.advertise.impl.AdvertiseListenerImpl.init(AdvertiseListenerImpl.java:151) at [email protected]//org.jboss.modcluster.advertise.impl.AdvertiseListenerImpl.start(AdvertiseListenerImpl.java:161) at [email protected]//org.jboss.modcluster.ModClusterService.init(ModClusterService.java:165) at [email protected]//org.wildfly.mod_cluster.undertow.UndertowEventHandlerAdapterService.start(UndertowEventHandlerAdapterService.java:83) at [email protected]//org.wildfly.clustering.service.AsyncServiceConfigurator$AsyncService.lambda$start$0(AsyncServiceConfigurator.java:117) at [email protected]//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at [email protected]//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982) at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486) at [email protected]//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377) at java.base/java.lang.Thread.run(Thread.java:834) at [email protected]//org.jboss.threads.JBossThread.run(JBossThread.java:485)

Implement login-update-password.ftl

Hello,

There are no implementations for some pages, such as login-update-password.ftl

I think it'd be better if we can inject our implementations dynamically, for example:

switch (kcContext.pageId) {
...
      case 'login-update-password.ftl':
           return <LoginUpdatePassword {...{ kcContext, ...kcProps }} />;
...
}

=> the library would build the login-update-password.ftl file

External Components without stylings

Hi,
Here are the things important to note:

The components are imported to Keycloackify successfully, but when it comes to the css variables that are required for it is own styling, then it gets ignored.
So we ended up with components without styling.
Two example of imports:
Component import:
import Button from '@components/button';
Styles and themes import:
import '@components/theme/src/theme.scss';
Example of the theme file that is been imported:

@import 'variables.scss'; // should be included only here not in a WES, SES, COS !!!

// utility function to convert a hex color like #ffffff to it's r,g,b elements.
@function cssrgb($hex) {
  @return red($hex), green($hex), blue($hex);
}

/**
 defines a css variable with the provided $name with $hex as value
 and additionally converts the $hex to it's r,g,b elements and defines a $name-rgb variable
 Example
 @include defineCssColorVariable(--my-var, #ffffff)

 Result:
 
 --my-var: #ffffff;

 the -rgb variable can then be used as input for the css `rgba` function
 Example:

 rgba(var(--my-var-rgb), 0.5)

 would be interpreted as `rgba(255, 255, 255, 0.5)`
 */
@mixin defineCssColorVariable($name, $hex) {
  #{$name}: #{$hex};
  #{$name}-rgb: #{cssrgb($hex)};
}

:global {
  :root {
    --white: #ffffff;
    // title text H1, H2, dark background
    @include defineCssColorVariable(--grey-10, #33445c);

    // info
    --background-info: var(--blue-light);


    // success
    --background-success: var(--green-light);


    // warning
    --background-warning: var(--yellow-light);


    // borders
    --border-color: var(--grey-40);


    // font-size
    --font-xl: 19px;

    // base font parameters
    --font-size-base: var(--font-m);


    // icons
    --menu-icon-color: var(--grey-35);


    // animations
    --ease-in: cubic-bezier(0.4, 0, 0.2, 1);

  }
}

Is there a way to make Keycloakify responsive to our imported components stylings?

Very cool! Curious to learn more about how it works

Just want to say I think this is an extremely cool project! It's cool to see how much energy you are putting into it.

I am curious to learn more about how the build system works, including what inputs are expected and how they might be structured. What dependencies (for instance, running the demo app, i had to install maven and wget on Mac), and what outputs, and intermediate outputs are generated.?

As far as I can tell, the build tool uses webpack to generate some modules, and then those modules are injected into the ftl templates? How is the window.kcContext context populated?

Anyway, maybe i'm just that kind of person who needs to know how things work before moving forward, but it would also help with integrating with other build tools such as Bazel, and maybe would help in getting a little more traction :-)

Spaces in file path

When building in a project that has spaces in the file path, keycloakify tries to build "seperate" projects.

This is uncommon on Linux but we're using WSL and referencing a host path with a space in it's path.

Thanks!

Module parse failed: Unexpected token

Hi. Thank you for this nice library. I'm a Keycloak and react developer since a while and I was very excited to discover this library. So I'm about to convert my themes using this library. Now I have this error stopping me from going further.

I obtain this error when I try to run the dev server after adding my own config, based on this config.

./node_modules/keycloakify/src/lib/components/Template.tsx 3:12
Module parse failed: Unexpected token (3:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| 
| import { useReducer, useEffect, memo } from "react";
> import type { ReactNode } from "react";
| import { useKcMessage } from "../i18n/useKcMessage";
| import { useKcLanguageTag } from "../i18n/useKcLanguageTag";

I've added these libraries because I need material inside my design:

...
"@fontsource/roboto": "^4.4.5",
"@material-ui/core": "^4.12.0",
...

This is my kcContext :

import {getKcContext} from "keycloakify";

declare type RegisterType = {
    pageId: "register.ftl";
    phoneNumber: string;
}

declare type PhoneTanType = {
    pageId: "request-sms-tan.ftl";
    phoneNumber: string;
}

export const {kcContext} = getKcContext<RegisterType | PhoneTanType>({
    "mockPageId": "request-sms-tan.ftl",
    "mockData": [
        {
            "pageId": "request-sms-tan.ftl",
            "phoneNumber": "+234567890987"
        },
    ]
});

export type KcContext = NonNullable<typeof kcContext>;

Now when I use a pure js project, I don't have this error. After some researches, Webpack is the problem, not knowing how to load "import type" (obviously πŸ˜†).

Does someone have an Idea how to deal with such a situation?

A question about building the FTL files

Hope you don't mind the question, I wasn't sure where else to ask it.

As part of the "build" process, you are attaching variables on to a global object called kcContext (window.kcContext).

This is fine and works great.

As part of my task I have to migrate not only the login related pages, but also account pages as well. For example, I have an account page that allows the user to change their email address. Here is the code that links the user to that page;

            <@inputs.input id="username" name="username" type="text" value="${(account.email!'')}" class="input_withOption" disabled="true" labelText="Email address" hasOption="true">
                <@buttons.link href="${email.emailPage}" class="inputOption inputOption__link" importance="tertiary" gaId="updateLoginDetails_changeEmailButton">Change</@buttons.link>
            </@inputs.input>

We display the email address and provide a "Change" link. We pre-populate the email address field with the email they used for their account.

The account object is provided I believe from Keycloak. Currently it is not exposed by Keycloakify, even though I assume it is available.

So I was looking at this code;

<script>
    Object.deepAssign(
        window.kcContext,
        { "pageId": "login-reset-password.ftl" }
    );
    Object.deepAssign(
        window.kcContext,
         
{
    "realm": {
        "loginWithEmailAllowed": (function (){

            <#attempt>
                return ${realm.loginWithEmailAllowed?c};
            <#recover>
            </#attempt>

        })()
    }
}

    );
</script>

Specifically this;

            <#attempt>
                return ${realm.loginWithEmailAllowed?c};
            <#recover>
            </#attempt>

This is compiled by keycloakfiy.

Is there any way I can easily extend the build process so that I can output my own variables?

Accessing social variable from context outside the Login page

Hey, I want to add "Sign Up with {social display name}" buttons in my register page, but apparently it's not possible to access the social variable outside the login page.

After checking the code, I guess it's because it's missing this part in the generateFtl/register.ftl file:

 "social": { ... },

Is there already a workaround for this?

If not, one idea I have, is to build the generateFtl files programmatically, where we define the variables based on the config or the default value. For example (The code is just so the idea can be better understood) :

//foo/variables
export const url = `{
        "loginResetCredentialsUrl": (function (){
            <#attempt>
                return "${url.loginResetCredentialsUrl?no_esc}";
            <#recover>
            </#attempt>
        })(),
        "registrationUrl": (function (){
            <#attempt>
                return "${url.registrationUrl?no_esc}";
            <#recover>
            </#attempt>
        })()
}`

export const realm = `{
        "loginWithEmailAllowed": (function(){
            <#attempt>
                return ${realm.loginWithEmailAllowed?c};
            <#recover>
            </#attempt>
        })(),
        "rememberMe": (function (){
            <#attempt>
                return ${realm.rememberMe?c};
            <#recover>
            </#attempt>
        })(),
        "password": (function (){
            <#attempt>
                return ${realm.password?c};
            <#recover>
            </#attempt>
        })(),
        "resetPasswordAllowed": (function (){
            <#attempt>
                return ${realm.resetPasswordAllowed?c};
            <#recover>
            </#attempt>
        })(),
        "registrationAllowed": (function (){
            <#attempt>
                return ${realm.registrationAllowed?c};
            <#recover>
            </#attempt>
        })()
}`
// ...
import * as variables from 'foo/variables'
import * as config from 'foo/config'

const defaultVariables = {
	login: ["url", "realm", ...],
	...
}

const generateFile = (name: string) => {
	const fileVariables = config.variables?.[name] || defaultVariables[name]
	
	const entries = fileVariables.map(variable => {
		return [variable, variables[variable]]
	}

	const file = `
		<script>
			const _= ${JSON.stringify(Object.fromEntries(entries))} 
		</script>
	`
	
	// write file
}

Then in a config file we could easily add or remove the variables we need

{
	variables: {
		register: ["url", "realm", ..., "social"]
	}
}

I don't know much about how the lib works, so I hope this helps to find a way to solve this problem.

Error on common.ftl thrown by Keycloak

Errors coming in the Keycloak logs.
Tried my best to figure it out, but don't have the FTL knowledge.

This object[key] part in the FTL common.ftl is generating errors everywhere :(
Keycloak version 15.0.2

18:32:33,252 ERROR [freemarker.runtime] (default task-11) Error executing FreeMarker template part in the #attempt block: freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
==> object[key]  [in template "login.ftl" at line 70, column 37]
----
FTL stack trace ("~" means nesting-related):
	- Failed at: #local value = object[key]  [in template "login.ftl" in macro "objectToJson" at line 70, column 21]
	- Reached through: @compress  [in template "login.ftl" in macro "objectToJson" at line 36, column 5]
	- Reached through: @objectToJson object=value depth=(dep...  [in template "login.ftl" in macro "objectToJson" at line 81, column 27]
	- Reached through: @compress  [in template "login.ftl" in macro "objectToJson" at line 36, column 5]
	- Reached through: @objectToJson object=(.data_model) de...  [in template "login.ftl" at line 230, column 35]
----

[build] TypeError [ERR_INVALID_CALLBACK] ?

Hi. I got a type error during build.
β€˜keycloak_11.0.3_builtin_themes.zip’ saved but there is an error for callback.

...
 11650K .......... .......... .......... .......... .......... 99% 3.26M 0s
 11700K .......... .......... .......... .......... .......... 99% 4.71M 0s
 11750K .......... .......... .......... .......... .......... 99% 2.75M 0s
 11800K .......... .....                                      100% 3.30M=3.6s

2021-09-29 14:37:02 (3.23 MB/s) - β€˜keycloak_11.0.3_builtin_themes.zip’ saved [12098580/12098580]

fs.js:177
    throw new ERR_INVALID_CALLBACK(cb);
    ^

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
    at makeCallback (fs.js:177:11)
    at Object.mkdir (fs.js:978:14)
    at Object.target.init (/home/cindy/.nvm/versions/node/v14.17.1/lib/node_modules/mvn/target.js:25:10)
    at Object.<anonymous> (/home/cindy/.nvm/versions/node/v14.17.1/lib/node_modules/mvn/target.js:39:8)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:92:18) {
  code: 'ERR_INVALID_CALLBACK'
}
child_process.js:682
    throw err;
    ^

Error: Command failed: mvn package
fs.js:177
    throw new ERR_INVALID_CALLBACK(cb);
    ^

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
    at makeCallback (fs.js:177:11)
    at Object.mkdir (fs.js:978:14)
    at Object.target.init (/home/cindy/.nvm/versions/node/v14.17.1/lib/node_modules/mvn/target.js:25:10)
    at Object.<anonymous> (/home/cindy/.nvm/versions/node/v14.17.1/lib/node_modules/mvn/target.js:39:8)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:92:18) {
  code: 'ERR_INVALID_CALLBACK'
}

    at checkExecSyncError (child_process.js:643:11)
    at Object.execSync (child_process.js:679:15)
    at main (/home/cindy/dev/ndc-ui/node_modules/keycloakify/bin/build-keycloak-theme/build-keycloak-theme.js:80:19)
    at Object.<anonymous> (/home/cindy/dev/ndc-ui/node_modules/keycloakify/bin/build-keycloak-theme/index.js:17:37)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)

    at internal/main/run_main_module.js:17:47 {
  status: 1,
  signal: null,
  output: [
    null,
    Buffer(0) [Uint8Array] [],
    Buffer(840) [Uint8Array] [
      102, 115,  46, 106, 115,  58,  49, 55,  55,  10,  32,  32,
       32,  32, 116, 104, 114, 111, 119, 32, 110, 101, 119,  32,
       69,  82,  82,  95,  73,  78,  86, 65,  76,  73,  68,  95,
       67,  65,  76,  76,  66,  65,  67, 75,  40,  99,  98,  41,
       59,  10,  32,  32,  32,  32,  94, 10,  10,  84, 121, 112,
      101,  69, 114, 114, 111, 114,  32, 91,  69,  82,  82,  95,
       73,  78,  86,  65,  76,  73,  68, 95,  67,  65,  76,  76,
       66,  65,  67,  75,  93,  58,  32, 67,  97, 108, 108,  98,
       97,  99, 107,  32,
      ... 740 more items
    ]
  ],
  pid: 10978,
  stdout: Buffer(0) [Uint8Array] [],
  stderr: Buffer(840) [Uint8Array] [
    102, 115,  46, 106, 115,  58,  49, 55,  55,  10,  32,  32,
     32,  32, 116, 104, 114, 111, 119, 32, 110, 101, 119,  32,
     69,  82,  82,  95,  73,  78,  86, 65,  76,  73,  68,  95,
     67,  65,  76,  76,  66,  65,  67, 75,  40,  99,  98,  41,
     59,  10,  32,  32,  32,  32,  94, 10,  10,  84, 121, 112,
    101,  69, 114, 114, 111, 114,  32, 91,  69,  82,  82,  95,
     73,  78,  86,  65,  76,  73,  68, 95,  67,  65,  76,  76,
     66,  65,  67,  75,  93,  58,  32, 67,  97, 108, 108,  98,
     97,  99, 107,  32,
    ... 740 more items
  ]
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] keycloak: `craco build && build-keycloak-theme`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] keycloak script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

May I know what am I missing?
Is there a problem with the configuration of the environment?

How to fix errors in common.ftl

Hi!
I managed to fix the template. You can look at the implementation here:

Errors with "The type of the containing value was: extended_hash+string"

Π‘Π½ΠΈΠΌΠΎΠΊ экрана 2021-12-01 Π² 12 05 39

  1. Long loading of the template and a large number of errors in the console can be fixed:
<#attempt>
  <#local value = object[key]!"error_data_is_undefined">
<#recover>
  /* couldn't dereference ${key} of object */
  <#continue>
</#attempt>

The freemarker documentation advises:

<#local value = object[key]!"">

But keycloakify app pages expect undefined.
Π‘Π½ΠΈΠΌΠΎΠΊ экрана 2021-12-03 Π² 16 51 59

And I followed a simple path. (So that these changes do not break other applications.)

JSON.parse(JSON.stringify(<@objectToJson_please_ignore_errors object=.data_model depth=0 arr=[] ftl="ftl_template_for_replacement" />), (key, value) => value === "error_data_is_undefined" ? undefined : value)

After that, 4 errors will remain in the console for the login.ftl page. Keys: loginUpdateTotpUrl, loginUsernameReminderUrl, loginUpdateProfileUrl, loginUpdatePasswordUrl from url object. And the template will work quickly.

  1. The following solution is not perfect, but it helps to fix errors. I've looked through all the templates from the base theme. And collected a list of all the urls that frontend uses: "loginAction", "resourcesPath", "resourcesCommonPath", "loginRestartFlowUrl", "loginUrl", "loginResetCredentialsUrl", "registrationUrl", "registrationAction", "oauth2DeviceVerificationAction", "oauthAction", "loginResetCredentialsUrl". (In my fork, I extend the current keycloakify templates with the basic ones. That's why I'm collecting lists for all the templates. This also applies to fieldNames in messagesPerField.)I added the arr=[] prop to each objectToJson_please_ignore_errors. And before:
"${key}": <@objectToJson_please_ignore_errors object=value depth=depth+1 arr=arr_keys ftl=ftl />

I'm doing the checks:

<#local arr_keys = []>
<#if depth==0 && key=="url" >
  <#local arr_keys = ["loginAction", "resourcesPath", "resourcesCommonPath", "loginRestartFlowUrl", "loginUrl", "loginResetCredentialsUrl", "registrationUrl", "registrationAction", "oauth2DeviceVerificationAction", "oauthAction", "loginResetCredentialsUrl"]>
</#if>

One new error will appear in the login.tpl template related to the fieldNames enumeration.
Π‘Π½ΠΈΠΌΠΎΠΊ экрана 2021-12-06 Π² 11 42 35

This error can be fixed by adding additional checks:

<#assign attributes = (profile.attributes)![]>
<#attempt>
  <#list attributes as attribute>
    <#if (attribute.name)??>
      <#assign fieldNames += [attribute.name]>
    </#if>
  </#list>
<#recover>
</#attempt>

Error in the login-reset-password.ftl template

Key: attemptedUsername from auth object. AttemptedUsername is used in login-reset-password.ftl template. If you try to get the value by the key of the attemptUsername in login-reset-password.ftp template (or in login.ftl template), it will not lead to an error. Therefore, ftlName parameter should appear in the conditions.

At the end of generateFtl.ts file:

objectKeys(ftlPlaceholders).forEach(
            id => (ftlCode = ftlCode.replace(id, ftlPlaceholders[id]).replace("ftl_template_for_replacement", pageId)),
        );

At the end of common.ftl file:

Object.deepAssign(
        out,
        //Removing all the undefined
        JSON.parse(JSON.stringify(<@objectToJson_please_ignore_errors object=.data_model depth=0 arr=[] ftl="ftl_template_for_replacement" />), (key, value) => value === "error_data_is_undefined" ? undefined : value)
    );

Before:

"${key}": <@objectToJson_please_ignore_errors object=value depth=depth+1 arr=arr_keys ftl=ftl />,
<#if depth==0 && key=="auth" && ftl=="login-reset-password.ftl" >
  <#local arr_keys = ["showUsername", "showResetCredentials", "showTryAnotherWayLink", "attemptedUsername"]>
<#elseif depth==0 && key=="auth">
  <#local arr_keys = ["showUsername", "showResetCredentials", "showTryAnotherWayLink"]>
</#if>

Error in the login-update-profile.ftl template

I'm not sure if this page worked before my changes. On my computer, when I tried to open this page for 10 minutes, errors appeared in the console. As a result, the page did not load. After my changes, it became clear that this page is broken. Because the download has become faster. There is an error in the browser window 500 (internal server error).

I got all the top-level keys from the .data_model on login-update-profile page: msg, execution, updateProfileCtx, social, auth, requiredActionUrl, message, locale, authenticatorConfigured, login, url, advancedMsg, messagesPerField, client, realm, kcSanitize, scripts, user, properties.

First I excluded all the keys (before "${key}": <@objectToJson_please_ignore_errors...).

<#if depth==0 && key=="url" ><#continue></#if>
<#if depth==0 && key=="auth" ><#continue></#if>
<#if depth==0 && key=="locale" ><#continue></#if>
<#if depth==0 && key=="realm" ><#continue></#if>
<#if depth==0 && key=="scripts" ><#continue></#if>
<#if depth==0 && key=="message" ><#continue></#if>
<#if depth==0 && key=="client" ><#continue></#if>
<#if depth==0 && key=="messagesPerField" ><#continue></#if>
<#if depth==0 && key=="user" ><#continue></#if>
<#if depth==0 && key=="requiredActionUrl" ><#continue></#if>
<#if depth==0 && key=="msg" ><#continue></#if>
<#if depth==0 && key=="execution" ><#continue></#if>
<#if depth==0 && key=="updateProfileCtx" ><#continue></#if>
<#if depth==0 && key=="social" ><#continue></#if>
<#if depth==0 && key=="authenticatorConfigured" ><#continue></#if>
<#if depth==0 && key=="login" ><#continue></#if>
<#if depth==0 && key=="advancedMsg" ><#continue></#if>
<#if depth==0 && key=="kcSanitize" ><#continue></#if>
<#if depth==0 && key=="properties" ><#continue></#if>

I found a problem in updateProfileCtx key. Since frontend does not use this object, I have excluded it altogether.

<#if depth==0 && key=="updateProfileCtx" ><#continue></#if>

This object has the following keys: lastName, getClass, setSingleAttribute, getUserProfileContext, getFirstAttribute, getAttributeStream, getUsername, setLastName, setAttribute, hashCode, class, email, isEditUsernameAllowed, getAttributes, setUsername, getLastName, firstName, editUsernameAllowed, setEmail, setFirstName, equals, getEmail, attributes, toString, getFirstName, userProfileContext, username.

The real problem is one or more of them.

Error in the saml-post-form.ftl template (optional)

At the moment there are two additional templates in my fork: saml-post-form.ftl, login-config-totp.ftl.
loginAction key of url object creates an error. That's why I excluded him:

<#if depth==0 && key=="url" && ftl=="saml-post-form.ftl" >
  <#local arr_keys = ["resourcesPath", "resourcesCommonPath", "loginRestartFlowUrl", "loginUrl", "loginResetCredentialsUrl", "registrationUrl", "registrationAction", "oauth2DeviceVerificationAction", "oauthAction", "loginResetCredentialsUrl"]>
<#elseif depth==0 && key=="url">
  <#local arr_keys = ["loginAction", "resourcesPath", "resourcesCommonPath", "loginRestartFlowUrl", "loginUrl", "loginResetCredentialsUrl", "registrationUrl", "registrationAction", "oauth2DeviceVerificationAction", "oauthAction", "loginResetCredentialsUrl"]>
</#if>

At this stage, all errors in the templates have been fixed.

Error executing Freemarker

Hi,
I am using keycloakify in a very basic way. Just copied Register.tsx from the library itself and pasted in my code and I am getting this error:

 12:37:18,101 ERROR [freemarker.runtime] (default task-6) Error executing FreeMarker template part in the #attempt block: freemarker.core.InvalidReferenceException: The following has evaluated to null or missing:
[keycloak] ==> object[key]  [in template "register.ftl" at line 70, column 37]
[keycloak] 

Could you please help, why it is coming?

TIA

Compilation Error when try to run yarn start

When i run the yarn start then i got the following error

Compiled with problems:X

ERROR in ./node_modules/keycloakify/lib/components/LoginOtp.js 43:13-28

Module not found: Error: Can't resolve 'path' in '/home/kousher/Projects/edge-commerce/keycloak-bookstore/node_modules/keycloakify/lib/components'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }


ERROR in ./node_modules/keycloakify/lib/components/Template.js 75:13-28

Module not found: Error: Can't resolve 'path' in '/home/kousher/Projects/edge-commerce/keycloak-bookstore/node_modules/keycloakify/lib/components'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }


ERROR in ./node_modules/keycloakify/lib/getKcContext/kcContextMocks/kcContextMocks.js 70:13-28

Module not found: Error: Can't resolve 'path' in '/home/kousher/Projects/edge-commerce/keycloak-bookstore/node_modules/keycloakify/lib/getKcContext/kcContextMocks'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }


ERROR in ./node_modules/keycloakify/lib/getKcContext/kcContextMocks/urlResourcesPath.js 8:13-28

Module not found: Error: Can't resolve 'path' in '/home/kousher/Projects/edge-commerce/keycloak-bookstore/node_modules/keycloakify/lib/getKcContext/kcContextMocks'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
	- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "path": false }

OS: Ubuntu 20.04.3 LTS 64 Bit

Redirect after login?

Hi. :)

Is there any way to redirect origin page after login?
My application stays on the login page after successful login.

I tried 2 different ways to login.

  1. with axios
    const handleLogin = async () => {
      await api.login({url: url.loginAction, userName: userName, password: password, });

      // go back to home page!
    };
  1. with form & submit button
<form
    method="post"
    action={url.loginAction}
>
...
</form>

[QS] How to use kcContext for custom implementation

First of all thanks a lot for creating this package, it might just be a lifesaver for people like us.

I am trying to make use of keycloakify with custom Material UI login screen.

From the source code, I can see that in the example template, you have created your own login page

I see in this login page you are making use of kcContext, which help maintain the values state.

Is there any documentation on how to use kcContext for any custom implementation. If not can you guide me in the right direction and I will more than happy make it possible.

Appreciate your help.

MVN command not found on Github self-hosted runner

I have install maven on our company's self hosted runner and verified from workflow the mvn -version is showing that maven is installed.

still when I run the build-keycloak-theme it gives me error

/bin/sh: mvn: command not found
node:child_process:903
    throw err;
    ^

Error: Command failed: mvn package
/bin/sh: mvn: command not found

    at checkExecSyncError (node:child_process:826:11)
    at Object.execSync (node:child_process:900:15)

any idea how I can resolve this issue ?

Issue: crash if project uses KcApp

Compiling...
/home/user/projects/keycloak/keycloakify-demo-app/node_modules/react-scripts/scripts/start.js:19
  throw err;
  ^

[Error: ENOENT: no such file or directory, stat '/home/user/.steampath'] {
  errno: -2,
  code: 'ENOENT',
  syscall: 'stat',
  path: '/home/user/.steampath'
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

OS: Linux
Keycloakify version is 0.3.22.
I'm using this template without any edit, just only upgraded keycloakify.

./node_modules/keycloakify/lib/i18n/useKcMessage.js
Module not found: Can't resolve 'markdown' in '/home/user/projects/keycloak/keycloakify-demo-app/node_modules/keycloakify/lib/i18n/useKcMessage.js

yarn add markdown fixes the issue.

Ability to add custom .ftl pages

Hello!

We have a highly customized Keycloak setup and have added a couple of additional '.ftl' pages to our login & signup flows.

As far as I know, the current version does not support such a thing as building arbitrary Freemarker pages. The only way I see to achieve this is to fork the library and add them manually to the build script.

Will it be possible to incorporate such functionality into the library? I could work on the PR if it's feasible (any advice is more than welcome ofc).

P.S. Thanks for the lib, it's a great piece of work, saved so much time for us πŸ™Œ

Error during the "build-keycloak-theme" execution

keycloakify 2.0.10
Node 14.17.3

I created a new project via create-react-app. index.tsx looks like this:

import ReactDOM from "react-dom";
import "./index.css";
import reportWebVitals from "./reportWebVitals";
import { KcApp, defaultKcProps, getKcContext } from "keycloakify";
import { css } from "tss-react";

const { kcContext } = getKcContext();

const myClassName = css({ color: "red" });

ReactDOM.render(
  <KcApp
    kcContext={kcContext!}
    {...{
      ...defaultKcProps,
      kcHeaderWrapperClass: myClassName,
    }}
  />
  ,
  document.getElementById("root")
);

reportWebVitals();

When I'm trying to run yarn build && build-keycloak-theme I'm getting this:

image

Downgraded versions of Node or keycloakify makes no difference.

I also tried the demo-app and still got the same error.

Any ideas?

Thanks 😊

How can we use custom styles in KcApp?

Hello,

Could you please provide some documentation that how can we add our custom styles?

I have tried many ways using useStyles of tss-react and styling of material/ui but whenever I run app keycloak, page does not render and says that Refused to apply styles.

I would be grateful if you can provide a guide to customize styles.

Thanks

Support OTP

Thank you for this life saving project!

How can we customize the otp one time code page?

Regards

How to use theme.properties

Hello! Love the project!

I'm new to Keycloak and Keycloakify, so apologies if this is a simple question.

I'm working on migrating an existing Keycloak theme to use Keycloakify. The existing theme is written using FTL.

The existing theme has variables in the FTL files like so;

        <a name="Home" href="${primaryUrl}" title="${nameOfTitle}" data-ga-tracking-id="headerLogo">

My understanding is that these variables come from the theme.properties file.

How can I access these variables on the React side?

Thanks

Adding/Replacing existing kcContext mock data

I tried to add required actions to the info.ftl mock but it throws an error when I try to get the mocked context as shown in the image below. Have I made a mistake or does the feature not work exactly as intended?

The field is supposed to be undefined and according to the code in deepassign it should just use the new provided property.

 "mockData": [
    {
      "pageId": "info.ftl",
      requiredActions : [
        "CONFIGURE_TOTP",
        "UPDATE_PASSWORD",
        "UPDATE_PROFILE",
        "VERIFY_EMAIL",
        "terms_and_conditions"
      ]
    }
]

image

ios Invalid regular expression: invalid group specifier name

Hello! I'm using your tool and it's currently in production and I have a major issue on iOS (15). As the title says, I'm getting this error here when I uses it on iOS: Invalid regular expression: invalid group specifier name.

image

This only happens on iOS and only when I import something from keycloakify. Any help would be appreciated.

Quotes in `HTML Display name` can lead to undefined errors

I ran into an undefined error which was preventing my login page from rendering due to having this on my realm:

HTML Display name: <div class="kc-logo-text"><span>Keycloak</span></div>

Removing that value fixes the issue so there is a workaround. Based on the output, the " appear to be causing the issue. I'm not sure why I used that setting in the past (may be default?) but I imagine this library would render it obsolete.

The full rendered snippet is here: https://pastebin.com/kdNU2vY8

What is the equivalent to `advancedMsg` ?

Hello, during the conversion of my themes from Keycloak Freemarker to keycloakify, I came across this problem. Actually, there's no equivalent to advancedMsg when using this library, or I didn't found any.

<#if client.name?has_content>
      ${msg("oauthGrantTitle",advancedMsg(client.name))}
<#else>
      ${msg("oauthGrantTitle",client.clientId)}
</#if>

This is what I've tried:

client.name ? msgStr('oauthGrantTitle', msgStr(client.name)) : msg("oauthGrantTitle", client.clientId

but without surprise, I'm getting an error:

  • First typescript error - because they're not from the same type
  • Second dom error - this means, that no text is being printed to the screen during development.

Do you have an idea how I can do it right ?

logs about error in macro "objectToJson_please_ignore_errors" should be removed

FTL stack trace ("~" means nesting-related):
- Failed at: #local value = object[key] [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 77, column 21]
- Reached through: @compress [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 43, column 5]
- Reached through: @objectToJson_please_ignore_errors ob... [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 88, column 27]
- Reached through: @compress [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 43, column 5]
- Reached through: @objectToJson_please_ignore_errors ob... [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 88, column 27]
- Reached through: @compress [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 43, column 5]
- Reached through: @objectToJson_please_ignore_errors ob... [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 88, column 27]
- Reached through: @compress [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 43, column 5]
- Reached through: @objectToJson_please_ignore_errors ob... [in template "login.ftl" in macro "objectToJson_please_ignore_errors" at line 88, column 27]

Building error

Using Ubuntu 20

ares@ares:~/gitt/main/keycloakify-main$ sudo yarn keycloak
yarn run v1.22.10
$ yarn build && build-keycloak-theme
$ yarn clean && tsc && yarn grant-exec-perms && yarn copy-files
$ rimraf dist/
$ node dist/bin/tools/grant-exec-perms.js
$ copyfiles -u 1 src//*.ftl src//.xml src/**/.js dist/
πŸ” Building the keycloak theme...⌚
/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/tools/transformCodebase.js:66
finally { if (e_1) throw e_1.error; }
^

Error: ENOENT: no such file or directory, scandir '/home/ares/gitt/main/keycloakify-main/build'
at Object.readdirSync (fs.js:790:3)
at crawlRec (/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/tools/crawl.js:41:39)
at Object.crawl (/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/tools/crawl.js:61:9)
at Object.transformCodebase (/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/tools/transformCodebase.js:46:40)
at Object.generateKeycloakThemeResources (/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/build-keycloak-theme/generateKeycloakThemeResources.js:69:25)
at Object.main (/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/build-keycloak-theme/build-keycloak-theme.js:50:38)
at Object. (/home/ares/gitt/main/keycloakify-main/node_modules/keycloakify/bin/build-keycloak-theme/index.js:17:28)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Additional configuration options in the package.json

Hi!
I need to build several themes for different realms. But with the same components.
(I use my KcApp and pages components). I really don't want to duplicate the react app because of this.

Could you add more customization options for the titles? For example:

package.json:

{
  "other_props": "...",
  "keycloakify": {
    "themeName": "example",
    "sourcePath": "build",
    "buildPath": "build_keycloak2"
  }
}

src/bin/build-keycloak-theme.ts:

const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPath, "package.json"));

const buildDirName: string = (parsedPackageJson as any)["keycloakify"]?.["buildPath"] ?? 'build_keycloak';
export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, buildDirName);

...

const reactDirName: string = (parsedPackageJson as any)["keycloakify"]?.["sourcePath"] ?? 'build';
const themeName = sanitizeThemeName((parsedPackageJson as any)["keycloakify"]?.["themeName"] ?? parsedPackageJson.name);

...

"reactAppBuildDirPath": pathJoin(reactProjectDirPath, reactDirName),

Theme translation messages support

I would like to add translation files to the theme.

Expected behaviour

Keycloak documentation on internationalization states that in order to support a custom language two steps are neccessary:

  1. create a messages* file inside the theme folder
  2. modify theme.properties by adding the locales= ... entry

Actual state

(1) Messages

I was investigating if translations are already supported. AFAIK the build theme script generateKeycloakThemeResources.js only copies the resources folder to the theme folder. The messages folder is not mentioned in the script.

To be clear what I was looking for: Keycloak expects the messages folder next to the resources folder.

    META-INF/keycloak-themes.json
    theme/mytheme/login/theme.properties
    theme/mytheme/login/login.ftl
    theme/mytheme/login/resources/css/styles.css
    theme/mytheme/login/resources/img/image.png
    theme/mytheme/login/messages/messages_en.properties
    theme/mytheme/email/messages/messages_en.properties

Maybe I am missing something here, so any help regarding adding translation files would be much appreciated.

A workaround would be to add the messages folder to the theme by updating a jar package once it is compiled, but that is not a permanent solution.

(2) Modify theme.properties

I think this pull-request solves it: #18

Easiest way to make it work with next.js?

From reading this issue #5 it sounds like this project is pretty tied to create-react-app. Unfortunately for me the app I'm working on is using (normally ssr'd) next.js. I'm no next.js pro yet so I'll have to think about how to make this work a bit. Do you have any ideas?

Some pages are not exported from v2

I'm trying to adopt keycloakify with my own theme library by re-implementing KcApp, importing all pages and incrementally substituting my own template and page components. However with the v2 upgrade (I had just gotten this working for v1 when v2 was released) LoginOtp, Register and Terms are not exported. Is this an oversight, or is something not working for them?

VueJS support

This is awesome project, thank you.
Can it support other technologies like VueJS?

I saw that the base Keycloak theme is generating JSON files based on the realm configuration
What else do we need?

no such file or directory, scandir 'E:\keycloak_custom\my-app\build_keycloak\src\main\resources\theme\my-app\tmp_xxKdLpdIdLd\keycloak\login\resources'

Error: ENOENT: no such file or directory, scandir 'E:\keycloak_custom\my-app\build_keycloak\src\main\resources\theme\my-app\tmp_xxKdLpdIdLd\keycloak\login\resources'
    at Object.readdirSync (node:fs:1390:3)
    at crawlRec (E:\keycloak_custom\my-app\node_modules\keycloakify\bin\tools\crawl.js:41:39)
    at crawl (E:\keycloak_custom\my-app\node_modules\keycloakify\bin\tools\crawl.js:61:9)
    at transformCodebase (E:\keycloak_custom\my-app\node_modules\keycloakify\bin\tools\transformCodebase.js:48:50)
    at generateKeycloakThemeResources (E:\keycloak_custom\my-app\node_modules\keycloakify\bin\build-keycloak-theme\generateKeycloakThemeResources.js:124:51)
    at main (E:\keycloak_custom\my-app\node_modules\keycloakify\bin\build-keycloak-theme\build-keycloak-theme.js:57:73)
    at Object.<anonymous> (E:\keycloak_custom\my-app\node_modules\keycloakify\bin\build-keycloak-theme\index.js:17:37)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32) {
  errno: -4058,
  syscall: 'scandir',
  code: 'ENOENT',
  path: 'E:\\keycloak_custom\\my-app\\build_keycloak\\src\\main\\resources\\theme\\my-app\\tmp_xxKdLpdIdLd\\keycloak\\login\\resources'
}

Split css does not have keycloak resource path preprended

I'm pretty new to react and this is more of a question than an issue and it may not even be an issue with this library.

Some background on what I'm trying to achieve:
I would like to use a single Keycloakify project to render different themes for multiple clients based on the clientId kc context value. In the past, I would simply extend a theme and append to the styles property with the file path to client specific css to override the previous styles. Is there a way to do that with this library?

I first tried to import the css path as I do with favicon import client1Favicon from "app/assets/client1/favicon.ico"; and append that to styles but I had no luck with that as the value was an object. But I'll continue looking into this, there may be some webpack option I can use to address this.

I also tried using code splitting feature to generate multiple css files but I now receive 404s as the Keycloak resource path is not prepended, example:

https://REDACTED/auth/resources/31exq/login/keycloakify/build/static/css/main.761845f0.chunk.css
https://REDACTED/static/css/4.75c36a70.chunk.css

Only the main.* chunks are available. Would it be possible for this to be fixed in the build-keycloak-theme scripts?

Here's a snippet of my components:

Main component:

const Component = lazy(() => {
  return Promise.resolve(import("./path/to/component2"));
});

export const Login = ({ kcContext, ...kcProps }: KcContextLoginComponent) => {
  return (
    <Suspense fallback={<DefaultLogin {...props} />}>
      <Component {...props} />
    </Suspense>
  )
};

Component2

import "./component2.scss";

const Component2 = memo((props: KcContextLoginComponent) => {
  return <Login {...props} />;
});
Component2.displayName = "Component2";

export default Component2;

Here's my resulting build folder directory build_keycloak/src/main/resources/theme/keycloakify/login/resources/build/static:

.
β”œβ”€β”€ css
β”‚   β”œβ”€β”€ 3.976b061b.chunk.css
β”‚   β”œβ”€β”€ 3.976b061b.chunk.css.map
β”‚   β”œβ”€β”€ 4.1a7cc1a2.chunk.css
β”‚   β”œβ”€β”€ 4.1a7cc1a2.chunk.css.map
β”‚   β”œβ”€β”€ main.1bbd513a.chunk.css
β”‚   └── main.1bbd513a.chunk.css.map
β”œβ”€β”€ js
β”‚   β”œβ”€β”€ 2.62a3ec59.chunk.js
β”‚   β”œβ”€β”€ 2.62a3ec59.chunk.js.LICENSE.txt
β”‚   β”œβ”€β”€ 2.62a3ec59.chunk.js.map
β”‚   β”œβ”€β”€ 3.f64e32e6.chunk.js
β”‚   β”œβ”€β”€ 3.f64e32e6.chunk.js.map
β”‚   β”œβ”€β”€ 4.30b8d41c.chunk.js
β”‚   β”œβ”€β”€ 4.30b8d41c.chunk.js.map
β”‚   β”œβ”€β”€ 5.66f9d5bf.chunk.js
β”‚   β”œβ”€β”€ 5.66f9d5bf.chunk.js.map
β”‚   β”œβ”€β”€ main.66a4253a.chunk.js
β”‚   β”œβ”€β”€ main.66a4253a.chunk.js.map
β”‚   β”œβ”€β”€ runtime-main.0d72eac6.js
β”‚   └── runtime-main.0d72eac6.js.map
└── media
    β”œβ”€β”€ banner.8160ab86.png
    β”œβ”€β”€ favicon.0c02463a.ico
    β”œβ”€β”€ favicon.5d99451e.ico
    β”œβ”€β”€ favicon.81150f84.ico
    β”œβ”€β”€ favicon.9115d06a.ico
    β”œβ”€β”€ favicon.9921761b.ico
    β”œβ”€β”€ favicon.ec5b0a49.ico
    β”œβ”€β”€ favicon.f5926395.ico
    β”œβ”€β”€ favicon.f6bfd61d.ico
    └── logo-text-300x63.e429c0bd.png

Adding custom field to user attributes and registration form

Hi, first of all thank you for this amazing project. I agree with all your motivations :).

Which branch is the right one for me to start ?

  • I have a keycloak server already running.
  • I want to add a custom theme extending "keycloak" theme
  • Add a select field to the registration form to add a custom user attribute.

"look_and_feel" branch ?
demo branch ?

I started with the "look_and_feel" following "advanced usage" following this guide.

Replaces those lines by const kcContext = realKcContext ?? kcContextMocks.kcLoginContext;, now if you run yarn start you will be able to debug the login page, replace kcLoginContext by kcRegisterContext and the register page will be loaded instead.

This point doesnt apply for the code of the "look_and_feel" branch though.

You see my confusion ? Otherwise let me know and I can try to explain it in other way :)

Thank you!

Local Fonts not loading

Dear @garronej

many thanks for the great project. We started using it for our project.

Can you please help us with the local fonts?
We can not load them from GoogleFonts or remote and they shall be there as local fonts.

I tried all your workarounds and it just didnt work. Can you please provide us guidance, which steps we have to do, to build the project and include in docker image with our local fonts? The KC docker image keeps ignoring them.

This would be so great. The links at workaround are not working anymore.

Many thanks!

register.ftl and login-verify-email.ftl throw errors

Hello, i made a fully custom theme using others deps as 'styled-components' and 'react-intl', everything is working well except the register and login verify email where both of those pages throw me the same error:

FTL stack trace ("~" means nesting-related):
        - Failed at: #local value = object[key]  [in template "login-verify-email.ftl" in macro "objectToJson" at line 70, column 21]

this is the code at line 70:

 <#attempt>
                    <#local value = object[key]>
                <#recover>
                    /* couldn't dereference ${key} of object */
                    <#continue>
                </#attempt>

Do you have any ideas of what is going on with this issue, the user cannot register and verify its email (he can only log in) ?
Thanks

Unable to use messagesPerField existsError and get

Hello,

I'm glad that you introduced messagesPerField.exists and messagesPerField.get in the new keycloakify v2.4.0 !
Though, I'm unable to use it.
Looking at the code, it seems that if I have no profile.attributes in my configuration. I don't know if that's necessary as I would like to use it on classic fields such as userLabel, username, email, firstName, lastName, password and password-confirm.

I'm not sure if this is a bug or whether it is intended.
I would be happy if you could update the lib for it to iterate on those values at least.

Cheers!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.