2021-06-14 21:21:36 +02:00
import { generateKeycloakThemeResources } from "./generateKeycloakThemeResources" ;
import { generateJavaStackFiles } from "./generateJavaStackFiles" ;
2021-10-11 21:35:40 +02:00
import {
join as pathJoin ,
relative as pathRelative ,
basename as pathBasename ,
} from "path" ;
2021-06-14 21:21:36 +02:00
import * as child_process from "child_process" ;
2021-10-11 21:35:40 +02:00
import {
generateDebugFiles ,
containerLaunchScriptBasename ,
} from "./generateDebugFiles" ;
2021-06-14 21:21:36 +02:00
import { URL } from "url" ;
2021-08-04 16:12:54 +02:00
type ParsedPackageJson = {
name : string ;
version : string ;
homepage? : string ;
} ;
2021-06-14 21:21:36 +02:00
const reactProjectDirPath = process . cwd ( ) ;
2021-10-11 21:35:40 +02:00
const doUseExternalAssets =
process . argv [ 2 ] ? . toLowerCase ( ) === "--external-assets" ;
2021-06-14 21:21:36 +02:00
2021-10-11 21:35:40 +02:00
const parsedPackageJson : ParsedPackageJson = require ( pathJoin (
reactProjectDirPath ,
"package.json" ,
) ) ;
2021-06-14 21:21:36 +02:00
2021-10-11 21:35:40 +02:00
export const keycloakThemeBuildingDirPath = pathJoin (
reactProjectDirPath ,
"build_keycloak" ,
) ;
2021-06-14 21:21:36 +02:00
2021-08-04 16:12:54 +02:00
function sanitizeThemeName ( name : string ) {
2021-10-11 21:35:40 +02:00
return name
. replace ( /^@(.*)/ , "$1" )
. split ( "/" )
. join ( "-" ) ;
2021-08-04 16:12:54 +02:00
}
2021-06-14 21:21:36 +02:00
2021-08-04 16:12:54 +02:00
export function main() {
2021-06-14 21:21:36 +02:00
console . log ( "🔏 Building the keycloak theme...⌚" ) ;
2021-10-11 21:35:40 +02:00
const extraPagesId : string [ ] =
( parsedPackageJson as any ) [ "keycloakify" ] ? . [ "extraPages" ] ? ? [ ] ;
const extraThemeProperties : string [ ] =
( parsedPackageJson as any ) [ "keycloakify" ] ? . [ "extraThemeProperties" ] ? ?
[ ] ;
2021-08-04 16:12:54 +02:00
const themeName = sanitizeThemeName ( parsedPackageJson . name ) ;
2021-06-23 18:03:49 +02:00
2021-06-14 21:21:36 +02:00
generateKeycloakThemeResources ( {
keycloakThemeBuildingDirPath ,
"reactAppBuildDirPath" : pathJoin ( reactProjectDirPath , "build" ) ,
2021-08-04 16:12:54 +02:00
themeName ,
2021-06-14 21:21:36 +02:00
. . . ( ( ) = > {
const url = ( ( ) = > {
const { homepage } = parsedPackageJson ;
2021-10-11 21:35:40 +02:00
return homepage === undefined ? undefined : new URL ( homepage ) ;
2021-06-14 21:21:36 +02:00
} ) ( ) ;
return {
"urlPathname" :
2021-10-11 21:35:40 +02:00
url === undefined
? "/"
: url . pathname . replace ( /([^/])$/ , "$1/" ) ,
"urlOrigin" : ! doUseExternalAssets
? undefined
: ( ( ) = > {
if ( url === undefined ) {
console . error (
"ERROR: You must specify 'homepage' in your package.json" ,
) ;
process . exit ( - 1 ) ;
}
return url . origin ;
} ) ( ) ,
2021-06-14 21:21:36 +02:00
} ;
2021-06-23 18:03:49 +02:00
} ) ( ) ,
2021-07-06 15:52:14 +03:00
extraPagesId ,
2021-10-06 17:22:52 +02:00
extraThemeProperties ,
2021-10-11 21:35:40 +02:00
//We have to leave it at that otherwise we break our default theme.
2021-10-07 21:00:53 +02:00
//Problem is that we can't guarantee that the the old resources common
2021-10-11 21:35:40 +02:00
//will still be available on the newer keycloak version.
"keycloakVersion" : "11.0.3" ,
2021-06-14 21:21:36 +02:00
} ) ;
const { jarFilePath } = generateJavaStackFiles ( {
2021-08-04 16:12:54 +02:00
version : parsedPackageJson.version ,
themeName ,
homepage : parsedPackageJson.homepage ,
2021-10-11 21:35:40 +02:00
keycloakThemeBuildingDirPath ,
2021-06-14 21:21:36 +02:00
} ) ;
2021-10-11 21:35:40 +02:00
child_process . execSync ( "mvn package" , {
"cwd" : keycloakThemeBuildingDirPath ,
} ) ;
2021-06-14 21:21:36 +02:00
generateDebugFiles ( {
keycloakThemeBuildingDirPath ,
2021-10-06 17:22:52 +02:00
themeName ,
2021-10-11 21:35:40 +02:00
"keycloakVersion" : "15.0.2" ,
2021-06-14 21:21:36 +02:00
} ) ;
2021-10-11 21:35:40 +02:00
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. ` ,
"" ,
"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" ,
" extraEnv: |" ,
" - name: KEYCLOAK_USER" ,
" value: admin" ,
" - name: KEYCLOAK_PASSWORD" ,
" value: xxxxxxxxx" ,
" - name: JAVA_OPTS" ,
" value: -Dkeycloak.profile=preview" ,
"" ,
"" ,
"To test your theme locally, with hot reloading, you can spin up a Keycloak container image with the theme loaded by running:" ,
"" ,
` 👉 $ ./ ${ 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 configured 👉 http://localhost:8080/auth/realms/myrealm/account 👈" ,
"" ,
] . join ( "\n" ) ,
) ;
2021-06-14 21:21:36 +02:00
}