From d26dbf4b3d8826baadee517d05560f78d8463d8c Mon Sep 17 00:00:00 2001 From: Sergey Kupletsky Date: Sun, 24 Sep 2023 23:42:10 +0200 Subject: [PATCH 01/39] fix: change JS path transformation for static resources - Handle both arrow functions and traditional function expressions - Add tests to ensure correctness of transformations --- .../replaceImportsFromStaticInJsCode.ts | 21 +++++++---- test/bin/replaceImportFromStatic.spec.ts | 35 ++++++++++++++++--- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts b/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts index 4ea29ffb..512dcb3c 100644 --- a/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts +++ b/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts @@ -16,18 +16,25 @@ export function replaceImportsFromStaticInJsCode(params: { jsCode: string }): { const { jsCode } = params; const getReplaceArgs = (language: "js" | "css"): Parameters => [ - new RegExp(`([a-zA-Z_]+)\\.([a-zA-Z]+)=function\\(([a-zA-Z]+)\\){return"static\\/${language}\\/"`, "g"), - (...[, n, u, e]) => ` - ${n}[(function(){ - var pd= Object.getOwnPropertyDescriptor(${n}, "p"); + new RegExp(`([a-zA-Z_]+)\\.([a-zA-Z]+)=(function\\(([a-z]+)\\){return|([a-z]+)=>)"static\\/${language}\\/"`, "g"), + (...[, n, u, matchedFunction, eForFunction]) => { + const isArrowFunction = matchedFunction.includes("=>"); + const e = isArrowFunction ? matchedFunction.replace("=>", "").trim() : eForFunction; + + return ` + ${n}[(function(){ + var pd = Object.getOwnPropertyDescriptor(${n}, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(${n}, "p", { get: function() { return window.${ftlValuesGlobalName}.url.resourcesPath; }, - set: function (){} + set: function() {} }); } - return "${u}"; - })()] = function(${e}) { return "${true ? "/build/" : ""}static/${language}/"` + return "${u}"; + })()] = ${isArrowFunction ? `${e} =>` : `function(${e}) { return `} "/build/static/${language}/"` + .replace(/\s+/g, " ") + .trim(); + } ]; const fixedJsCode = jsCode diff --git a/test/bin/replaceImportFromStatic.spec.ts b/test/bin/replaceImportFromStatic.spec.ts index 269ca255..c185a99e 100644 --- a/test/bin/replaceImportFromStatic.spec.ts +++ b/test/bin/replaceImportFromStatic.spec.ts @@ -32,6 +32,10 @@ describe("bin/js-transforms", () => { 908:"67c9ed2c" }[e]+".chunk.css" } + + n.u=e=>"static/js/"+e+"."+{69:"4f205f87",128:"49264537",453:"b2fed72e",482:"f0106901"}[e]+".chunk.js" + + t.miniCssF=e=>"static/css/"+e+"."+{164:"dcfd7749",908:"67c9ed2c"}[e]+".chunk.css" `; it("transforms standalone code properly", () => { const { fixedJsCode } = replaceImportsFromStaticInJsCode({ @@ -52,11 +56,11 @@ describe("bin/js-transforms", () => { } __webpack_require__[(function (){ - var pd= Object.getOwnPropertyDescriptor(__webpack_require__, "p"); + var pd = Object.getOwnPropertyDescriptor(__webpack_require__, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(__webpack_require__, "p", { get: function() { return window.kcContext.url.resourcesPath; }, - set: function (){} + set: function() {} }); } return "u"; @@ -69,11 +73,11 @@ describe("bin/js-transforms", () => { } t[(function (){ - var pd= Object.getOwnPropertyDescriptor(t, "p"); + var pd = Object.getOwnPropertyDescriptor(t, "p"); if( pd === undefined || pd.configurable ){ Object.defineProperty(t, "p", { get: function() { return window.kcContext.url.resourcesPath; }, - set: function (){} + set: function() {} }); } return "miniCssF"; @@ -83,7 +87,28 @@ describe("bin/js-transforms", () => { 908:"67c9ed2c" } [e] + ".chunk.css" } - + + n[(function(){ + var pd = Object.getOwnPropertyDescriptor(n, "p"); + if( pd === undefined || pd.configurable ){ + Object.defineProperty(n, "p", { + get: function() { return window.kcContext.url.resourcesPath; }, + set: function() {} + }); + } + return "u"; + })()] = e => "/build/static/js/"+e+"."+{69:"4f205f87",128:"49264537",453:"b2fed72e",482:"f0106901"}[e]+".chunk.js" + + t[(function(){ + var pd = Object.getOwnPropertyDescriptor(t, "p"); + if( pd === undefined || pd.configurable ){ + Object.defineProperty(t, "p", { + get: function() { return window.kcContext.url.resourcesPath; }, + set: function() {} + }); + } + return "miniCssF"; + })()] = e => "/build/static/css/"+e+"."+{164:"dcfd7749",908:"67c9ed2c"}[e]+".chunk.css" `; expect(isSameCode(fixedJsCode, fixedJsCodeExpected)).toBe(true); From b6eb1652076f462bc97ee08626871275c3438fc9 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 25 Sep 2023 13:41:51 +0200 Subject: [PATCH 02/39] https://github.com/keycloakify/keycloakify/discussions/422 --- .github/workflows/ci.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 2c63dd9e..8cdc0573 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -3,6 +3,7 @@ on: push: branches: - main + - v* pull_request: branches: - main From 0e51807856db7ab39cb88ca9224eb9776ccee6fd Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 01:58:04 +0000 Subject: [PATCH 03/39] docs: update README.md [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 22d2bc32..900aaddb 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Thomas Silvestre
Thomas Silvestre

💻 satanshiro
satanshiro

💻 Koen Poelhekke
Koen Poelhekke

💻 + Sergey Kupletsky
Sergey Kupletsky

⚠️ 💻 From 5ae568f19cf3f71f86f69adf953c6b795042c4e5 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 27 Sep 2023 01:58:05 +0000 Subject: [PATCH 04/39] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 76204e9c..f2aad766 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -158,6 +158,16 @@ "contributions": [ "code" ] + }, + { + "login": "zavoloklom", + "name": "Sergey Kupletsky", + "avatar_url": "https://avatars.githubusercontent.com/u/4151869?v=4", + "profile": "https://github.com/zavoloklom", + "contributions": [ + "test", + "code" + ] } ], "contributorsPerLine": 7, @@ -165,5 +175,6 @@ "repoType": "github", "repoHost": "https://github.com", "projectName": "keycloakify", - "projectOwner": "keycloakify" + "projectOwner": "keycloakify", + "commitType": "docs" } From fcb519dac3c42dbb051948479fed9f2d7f6ab7a9 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Wed, 27 Sep 2023 04:08:13 +0200 Subject: [PATCH 05/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 787b2b52..5a91e835 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.1.0", + "version": "8.1.1", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 79007ebd55a2cff9c88092188d8da9da27268be0 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 2 Oct 2023 22:49:04 +0200 Subject: [PATCH 06/39] #427 --- .../downloadKeycloakStaticResources.ts | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts b/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts index 6a798add..5a2d74d1 100644 --- a/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +++ b/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts @@ -1,6 +1,6 @@ import { transformCodebase } from "../../tools/transformCodebase"; import * as fs from "fs"; -import { join as pathJoin, relative as pathRelative } from "path"; +import { join as pathJoin, relative as pathRelative, dirname as pathDirname } from "path"; import type { ThemeType } from "../generateFtl"; import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme"; import { @@ -9,6 +9,7 @@ import { basenameOfKeycloakDirInPublicDir } from "../../mockTestingResourcesPath"; import * as crypto from "crypto"; +import { assert } from "tsafe/assert"; export async function downloadKeycloakStaticResources( // prettier-ignore @@ -23,7 +24,32 @@ export async function downloadKeycloakStaticResources( } | undefined } ) { - const { projectDirPath, themeType, themeDirPath, keycloakVersion, usedResources } = params; + const { projectDirPath, themeType, themeDirPath, keycloakVersion } = params; + + // NOTE: Hack for 427 + const usedResources = (() => { + const { usedResources } = params; + + if (usedResources === undefined) { + return undefined; + } + + assert(usedResources !== undefined); + + return { + "resourcesCommonDirPaths": usedResources.resourcesCommonFilePaths.map(filePath => { + { + const splitArg = "/dist/"; + + if (filePath.includes(splitArg)) { + return filePath.split(splitArg)[0] + splitArg; + } + } + + return pathDirname(filePath); + }) + }; + })(); const tmpDirPath = pathJoin( themeDirPath, @@ -39,17 +65,7 @@ export async function downloadKeycloakStaticResources( transformCodebase({ "srcDirPath": pathJoin(tmpDirPath, "keycloak", themeType, "resources"), - "destDirPath": pathJoin(themeDirPath, pathRelative(basenameOfKeycloakDirInPublicDir, resourcesDirPathRelativeToPublicDir)), - "transformSourceCode": - usedResources === undefined - ? undefined - : ({ fileRelativePath, sourceCode }) => { - if (!usedResources.resourcesFilePaths.includes(fileRelativePath)) { - return undefined; - } - - return { "modifiedSourceCode": sourceCode }; - } + "destDirPath": pathJoin(themeDirPath, pathRelative(basenameOfKeycloakDirInPublicDir, resourcesDirPathRelativeToPublicDir)) }); transformCodebase({ @@ -59,7 +75,7 @@ export async function downloadKeycloakStaticResources( usedResources === undefined ? undefined : ({ fileRelativePath, sourceCode }) => { - if (!usedResources.resourcesCommonFilePaths.includes(fileRelativePath)) { + if (usedResources.resourcesCommonDirPaths.find(dirPath => fileRelativePath.startsWith(dirPath)) === undefined) { return undefined; } From 96d5cfea14ffa3e3a1b20fa53bc8287a9a8cf8b0 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 2 Oct 2023 22:49:31 +0200 Subject: [PATCH 07/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a91e835..5fd69b97 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.1.1", + "version": "8.1.2", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 5398590939c3d586ca98f3ee8b5f3cb13108b369 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 9 Oct 2023 00:49:18 +0200 Subject: [PATCH 08/39] https://github.com/keycloakify/keycloakify/discussions/371#discussioncomment-7223711 --- src/account/pages/Account.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/account/pages/Account.tsx b/src/account/pages/Account.tsx index 19417c74..a93f20e4 100644 --- a/src/account/pages/Account.tsx +++ b/src/account/pages/Account.tsx @@ -51,7 +51,7 @@ export default function Account(props: PageProps @@ -66,7 +66,7 @@ export default function Account(props: PageProps
- +
@@ -79,7 +79,7 @@ export default function Account(props: PageProps
- +
@@ -92,7 +92,7 @@ export default function Account(props: PageProps
- +
From 36f404e17de3d157e903ecb32f490532188d21d9 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 9 Oct 2023 00:49:35 +0200 Subject: [PATCH 09/39] Preserve css order --- src/lib/usePrepareTemplate.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/lib/usePrepareTemplate.ts b/src/lib/usePrepareTemplate.ts index c71726ed..560161fa 100644 --- a/src/lib/usePrepareTemplate.ts +++ b/src/lib/usePrepareTemplate.ts @@ -23,24 +23,21 @@ export function usePrepareTemplate(params: { const removeArray: (() => void)[] = []; (async () => { - const prLoadedArray: Promise[] = []; - - styles.reverse().forEach(href => { + for (const style of [...styles].reverse()) { const { prLoaded, remove } = headInsert({ "type": "css", "position": "prepend", - href + "href": style }); removeArray.push(remove); - prLoadedArray.push(prLoaded); - }); + // TODO: Find a way to do that in parallel (without breaking the order) + await prLoaded; - await Promise.all(prLoadedArray); - - if (isUnmounted) { - return; + if (isUnmounted) { + return; + } } setReady(); From eb64fe60d06238a79e0e0969f062fe48ccfde3bb Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Mon, 9 Oct 2023 00:49:50 +0200 Subject: [PATCH 10/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5fd69b97..7f1f5846 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.1.2", + "version": "8.1.3", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 9f25cddaa46f034708ba7f4043ce9d4e37e99bc2 Mon Sep 17 00:00:00 2001 From: rome-user <114131048+rome-user@users.noreply.github.com> Date: Sun, 8 Oct 2023 18:12:57 -0700 Subject: [PATCH 11/39] Allow "keycloak_theme" as a theme source directory Fixes #429. --- src/bin/getSrcDirPath.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/bin/getSrcDirPath.ts b/src/bin/getSrcDirPath.ts index 893e29b1..115cc89b 100644 --- a/src/bin/getSrcDirPath.ts +++ b/src/bin/getSrcDirPath.ts @@ -4,7 +4,7 @@ import { crawl } from "./tools/crawl"; import { join as pathJoin } from "path"; import { themeTypes } from "./keycloakify/generateFtl"; -const themeSrcDirBasename = "keycloak-theme"; +const themeSrcDirBasenames = ["keycloak-theme", "keycloak_theme"]; /** Can't catch error, if the directory isn't found, this function will just exit the process with an error message. */ export function getThemeSrcDirPath(params: { projectDirPath: string }) { @@ -14,13 +14,13 @@ export function getThemeSrcDirPath(params: { projectDirPath: string }) { const themeSrcDirPath: string | undefined = crawl({ "dirPath": srcDirPath, "returnedPathsType": "relative to dirPath" }) .map(fileRelativePath => { - const split = fileRelativePath.split(themeSrcDirBasename); - - if (split.length !== 2) { - return undefined; + for (const themeSrcDirBasename of themeSrcDirBasenames) { + const split = fileRelativePath.split(themeSrcDirBasename); + if (split.length === 2) { + return pathJoin(srcDirPath, split[0] + themeSrcDirBasename); + } } - - return pathJoin(srcDirPath, split[0] + themeSrcDirBasename); + return undefined; }) .filter(exclude(undefined))[0]; @@ -38,7 +38,7 @@ export function getThemeSrcDirPath(params: { projectDirPath: string }) { console.error( [ "Can't locate your theme source directory. It should be either: ", - "src/ or src/keycloak-theme.", + "src/ or src/keycloak-theme or src/keycloak_theme.", "Example in the starter: https://github.com/keycloakify/keycloakify-starter/tree/main/src/keycloak-theme" ].join("\n") ); From 7fe4eeda575075ddecbe6166fd2ad3f8c4415b4f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:05:33 +0000 Subject: [PATCH 12/39] docs: update README.md [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 900aaddb..ef895752 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d satanshiro
satanshiro

💻 Koen Poelhekke
Koen Poelhekke

💻 Sergey Kupletsky
Sergey Kupletsky

⚠️ 💻 + rome-user
rome-user

💻 From a4ff8607c55a2e5e3a8b499605a267f57214a2c8 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 20 Oct 2023 13:05:34 +0000 Subject: [PATCH 13/39] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f2aad766..b5436d4b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -168,6 +168,15 @@ "test", "code" ] + }, + { + "login": "rome-user", + "name": "rome-user", + "avatar_url": "https://avatars.githubusercontent.com/u/114131048?v=4", + "profile": "https://github.com/rome-user", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 7e932b920efd704bb4431b4d6f261517eddb497c Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Fri, 20 Oct 2023 15:06:29 +0200 Subject: [PATCH 14/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7f1f5846..b16b354f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.1.3", + "version": "8.2.0", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 804abef0dee3e9fae994a77467c40def4040f09d Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 22 Oct 2023 15:58:11 +0200 Subject: [PATCH 15/39] #433 --- .../generateTheme/readStaticResourcesUsage.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts b/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts index 1665961b..d49485ac 100644 --- a/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts +++ b/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts @@ -1,5 +1,5 @@ import { crawl } from "../../tools/crawl"; -import { join as pathJoin } from "path"; +import { join as pathJoin, sep as pathSep } from "path"; import * as fs from "fs"; import type { ThemeType } from "../generateFtl"; @@ -74,10 +74,14 @@ export function readPaths(params: { rawSourceFile: string }): { } } - const removePrefixSlash = (filePath: string) => (filePath.startsWith("/") ? filePath.slice(1) : filePath); + const normalizePath = (filePath: string) => { + filePath = filePath.startsWith("/") ? filePath.slice(1) : filePath; + filePath = filePath.replace(/\//g, pathSep); + return filePath; + }; return { - "resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths).map(removePrefixSlash), - "resourcesFilePaths": Array.from(resourcesFilePaths).map(removePrefixSlash) + "resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths).map(normalizePath), + "resourcesFilePaths": Array.from(resourcesFilePaths).map(normalizePath) }; } From 4506b3f6d495d415d8f2ce600a65f9387f9b81b4 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 22 Oct 2023 16:04:47 +0200 Subject: [PATCH 16/39] Remove some dead code --- .../downloadKeycloakStaticResources.ts | 1 - .../generateTheme/readStaticResourcesUsage.ts | 41 +++++++------------ test/bin/readStaticResourcesUsage.spec.ts | 3 +- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts b/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts index 5a2d74d1..c276a15c 100644 --- a/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +++ b/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts @@ -20,7 +20,6 @@ export async function downloadKeycloakStaticResources( keycloakVersion: string; usedResources: { resourcesCommonFilePaths: string[]; - resourcesFilePaths: string[]; } | undefined } ) { diff --git a/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts b/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts index d49485ac..79a78ca2 100644 --- a/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts +++ b/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts @@ -6,12 +6,10 @@ import type { ThemeType } from "../generateFtl"; /** Assumes the theme type exists */ export function readStaticResourcesUsage(params: { keycloakifySrcDirPath: string; themeSrcDirPath: string; themeType: ThemeType }): { resourcesCommonFilePaths: string[]; - resourcesFilePaths: string[]; } { const { keycloakifySrcDirPath, themeSrcDirPath, themeType } = params; const resourcesCommonFilePaths = new Set(); - const resourcesFilePaths = new Set(); for (const srcDirPath of [pathJoin(keycloakifySrcDirPath, themeType), pathJoin(themeSrcDirPath, themeType)]) { const filePaths = crawl({ "dirPath": srcDirPath, "returnedPathsType": "absolute" }).filter(filePath => /\.(ts|tsx|js|jsx)$/.test(filePath)); @@ -26,51 +24,43 @@ export function readStaticResourcesUsage(params: { keycloakifySrcDirPath: string const wrap = readPaths({ rawSourceFile }); wrap.resourcesCommonFilePaths.forEach(filePath => resourcesCommonFilePaths.add(filePath)); - wrap.resourcesFilePaths.forEach(filePath => resourcesFilePaths.add(filePath)); } } return { - "resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths), - "resourcesFilePaths": Array.from(resourcesFilePaths) + "resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths) }; } /** Exported for testing purpose */ export function readPaths(params: { rawSourceFile: string }): { resourcesCommonFilePaths: string[]; - resourcesFilePaths: string[]; } { const { rawSourceFile } = params; const resourcesCommonFilePaths = new Set(); - const resourcesFilePaths = new Set(); - for (const isCommon of [true, false]) { - const set = isCommon ? resourcesCommonFilePaths : resourcesFilePaths; + { + const regexp = new RegExp(`resourcesCommonPath\\s*}([^\`]+)\``, "g"); - { - const regexp = new RegExp(`resources${isCommon ? "Common" : ""}Path\\s*}([^\`]+)\``, "g"); + const matches = [...rawSourceFile.matchAll(regexp)]; - const matches = [...rawSourceFile.matchAll(regexp)]; + for (const match of matches) { + const filePath = match[1]; - for (const match of matches) { - const filePath = match[1]; - - set.add(filePath); - } + resourcesCommonFilePaths.add(filePath); } + } - { - const regexp = new RegExp(`resources${isCommon ? "Common" : ""}Path\\s*[+,]\\s*["']([^"'\`]+)["'\`]`, "g"); + { + const regexp = new RegExp(`resourcesCommonPath\\s*[+,]\\s*["']([^"'\`]+)["'\`]`, "g"); - const matches = [...rawSourceFile.matchAll(regexp)]; + const matches = [...rawSourceFile.matchAll(regexp)]; - for (const match of matches) { - const filePath = match[1]; + for (const match of matches) { + const filePath = match[1]; - set.add(filePath); - } + resourcesCommonFilePaths.add(filePath); } } @@ -81,7 +71,6 @@ export function readPaths(params: { rawSourceFile: string }): { }; return { - "resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths).map(normalizePath), - "resourcesFilePaths": Array.from(resourcesFilePaths).map(normalizePath) + "resourcesCommonFilePaths": Array.from(resourcesCommonFilePaths).map(normalizePath) }; } diff --git a/test/bin/readStaticResourcesUsage.spec.ts b/test/bin/readStaticResourcesUsage.spec.ts index 74b74db2..a03fdde7 100644 --- a/test/bin/readStaticResourcesUsage.spec.ts +++ b/test/bin/readStaticResourcesUsage.spec.ts @@ -9,8 +9,7 @@ describe("Ensure it's able to extract used Keycloak resources", () => { "node_modules/patternfly/dist/css/patternfly-additions.min.css", "lib/zocial/zocial.css", "node_modules/jquery/dist/jquery.min.js" - ], - "resourcesFilePaths": ["css/login.css"] + ] }; it("works with coding style n°1", () => { From 2a13b314dc541b9f496cb4e0a2717f5b5dede62d Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 22 Oct 2023 16:05:09 +0200 Subject: [PATCH 17/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b16b354f..cadae0d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.2.0", + "version": "8.2.1", "description": "Create Keycloak themes using React", "repository": { "type": "git", From bb6b0267200e322a7408e85dca725d1f5d2863a5 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 22 Oct 2023 16:39:15 +0200 Subject: [PATCH 18/39] https://github.com/keycloakify/keycloakify/discussions/432#discussioncomment-7332729 --- .../ftl_object_to_js_code_declaring_an_object.ftl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl b/src/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl index 06d3f0b5..9a666004 100644 --- a/src/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl +++ b/src/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl @@ -478,6 +478,12 @@ "error.ftl" == pageId && are_same_path(path, ["realm"]) && !["name", "displayName", "displayNameHtml", "internationalizationEnabled", "registrationEmailAsUsername" ]?seq_contains(key) + ) || ( + "applications.ftl" == pageId && + are_same_path(path, ["applications", "applications", "*", "client", "realm"]) + ) || ( + "applications.ftl" == pageId && + "masterAdminClient" == key ) > <#local out_seq += ["/*If you need '" + key + "' on " + pageId + ", please submit an issue to the Keycloakify repo*/"]> From 8a6364833900d16fd90820e435c80f197385ba8e Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 22 Oct 2023 16:39:34 +0200 Subject: [PATCH 19/39] Release candidate --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cadae0d7..18b84eec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.2.1", + "version": "8.2.2-rc.0", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 46e50e622b77fcb579a9cb7f43861df215812a25 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Tue, 24 Oct 2023 16:23:28 +0200 Subject: [PATCH 20/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18b84eec..facef657 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.2.2-rc.0", + "version": "8.2.2", "description": "Create Keycloak themes using React", "repository": { "type": "git", From e0a61b51cb0ba7509a6b60630807a0c69cc2e858 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Thu, 26 Oct 2023 12:50:48 +0200 Subject: [PATCH 21/39] Little fix on LoginConfigTotp.tsx --- src/login/pages/LoginConfigTotp.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/login/pages/LoginConfigTotp.tsx b/src/login/pages/LoginConfigTotp.tsx index d32a34b0..dde1189f 100644 --- a/src/login/pages/LoginConfigTotp.tsx +++ b/src/login/pages/LoginConfigTotp.tsx @@ -32,7 +32,7 @@ export default function LoginConfigTotp(props: PageProps {totp.supportedApplications.map(app => ( -
  • {msgStr(app as MessageKey, app)}
  • +
  • {msg(app as MessageKey)}
  • ))} From 2e31b796f703b3919a578b30b4fea3f1d6b90132 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Thu, 26 Oct 2023 12:52:06 +0200 Subject: [PATCH 22/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cadae0d7..facef657 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.2.1", + "version": "8.2.2", "description": "Create Keycloak themes using React", "repository": { "type": "git", From c122b48e352c0faf7710f29861026d8c710b470c Mon Sep 17 00:00:00 2001 From: Celine Pelletier Date: Fri, 3 Nov 2023 16:06:46 -0400 Subject: [PATCH 23/39] feat: add login-oauth2-device-verify-user-code and login-oauth-grant pages --- src/bin/keycloakify/generateFtl/pageId.ts | 2 + src/login/Fallback.tsx | 6 ++ src/login/TemplateProps.ts | 3 +- src/login/kcContext/KcContext.ts | 23 ++++++ src/login/kcContext/kcContextMocks.ts | 23 +++++- src/login/lib/useGetClassName.ts | 1 + src/login/pages/LoginDeviceVerifyUserCode.tsx | 68 +++++++++++++++++ src/login/pages/LoginOauthGrant.tsx | 73 +++++++++++++++++++ 8 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 src/login/pages/LoginDeviceVerifyUserCode.tsx create mode 100644 src/login/pages/LoginOauthGrant.tsx diff --git a/src/bin/keycloakify/generateFtl/pageId.ts b/src/bin/keycloakify/generateFtl/pageId.ts index fc93e917..da3525f6 100644 --- a/src/bin/keycloakify/generateFtl/pageId.ts +++ b/src/bin/keycloakify/generateFtl/pageId.ts @@ -10,6 +10,8 @@ export const loginThemePageIds = [ "login-reset-password.ftl", "login-verify-email.ftl", "terms.ftl", + "login-oauth2-device-verify-user-code.ftl", + "login-oauth-grant.ftl", "login-otp.ftl", "login-update-profile.ftl", "login-update-password.ftl", diff --git a/src/login/Fallback.tsx b/src/login/Fallback.tsx index bffb3a78..80d5c12b 100644 --- a/src/login/Fallback.tsx +++ b/src/login/Fallback.tsx @@ -12,6 +12,8 @@ const Error = lazy(() => import("keycloakify/login/pages/Error")); const LoginResetPassword = lazy(() => import("keycloakify/login/pages/LoginResetPassword")); const LoginVerifyEmail = lazy(() => import("keycloakify/login/pages/LoginVerifyEmail")); const Terms = lazy(() => import("keycloakify/login/pages/Terms")); +const LoginDeviceVerifyUserCode = lazy(() => import("keycloakify/login/pages/LoginDeviceVerifyUserCode")); +const LoginOauthGrant = lazy(() => import("keycloakify/login/pages/LoginOauthGrant")); const LoginOtp = lazy(() => import("keycloakify/login/pages/LoginOtp")); const LoginPassword = lazy(() => import("keycloakify/login/pages/LoginPassword")); const LoginUsername = lazy(() => import("keycloakify/login/pages/LoginUsername")); @@ -52,6 +54,10 @@ export default function Fallback(props: PageProps) { return ; case "terms.ftl": return ; + case "login-oauth2-device-verify-user-code.ftl": + return ; + case "login-oauth-grant.ftl": + return ; case "login-otp.ftl": return ; case "login-username.ftl": diff --git a/src/login/TemplateProps.ts b/src/login/TemplateProps.ts index 1e50c4a0..22e8cadd 100644 --- a/src/login/TemplateProps.ts +++ b/src/login/TemplateProps.ts @@ -94,4 +94,5 @@ export type ClassKey = | "kcSelectOTPListItemClass" | "kcAuthenticatorOtpCircleClass" | "kcSelectOTPItemHeadingClass" - | "kcFormOptionsWrapperClass"; + | "kcFormOptionsWrapperClass" + | "kcFormButtonsWrapperClass"; diff --git a/src/login/kcContext/KcContext.ts b/src/login/kcContext/KcContext.ts index b7164e58..9b61648d 100644 --- a/src/login/kcContext/KcContext.ts +++ b/src/login/kcContext/KcContext.ts @@ -18,6 +18,8 @@ export type KcContext = | KcContext.LoginResetPassword | KcContext.LoginVerifyEmail | KcContext.Terms + | KcContext.LoginDeviceVerifyUserCode + | KcContext.LoginOauthGrant | KcContext.LoginOtp | KcContext.LoginUsername | KcContext.WebauthnAuthenticate @@ -241,6 +243,27 @@ export declare namespace KcContext { pageId: "terms.ftl"; }; + export type LoginDeviceVerifyUserCode = Common & { + pageId: "login-oauth2-device-verify-user-code.ftl"; + url: { + oauth2DeviceVerificationAction: string; + }; + }; + + export type LoginOauthGrant = Common & { + pageId: "login-oauth-grant.ftl"; + oauth: { + code: string; + client: string; + clientScopesRequested: { + consentScreenText: string; + }[]; + }; + url: { + oauthAction: string; + }; + }; + export type LoginOtp = Common & { pageId: "login-otp.ftl"; otpLogin: { diff --git a/src/login/kcContext/kcContextMocks.ts b/src/login/kcContext/kcContextMocks.ts index 9f054fcc..2ed52faf 100644 --- a/src/login/kcContext/kcContextMocks.ts +++ b/src/login/kcContext/kcContextMocks.ts @@ -240,7 +240,9 @@ export const kcContextCommonMock: KcContext.Common = { const loginUrl = { ...kcContextCommonMock.url, "loginResetCredentialsUrl": "/auth/realms/myrealm/login-actions/reset-credentials?client_id=account&tab_id=HoAx28ja4xg", - "registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg" + "registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg", + "oauth2DeviceVerificationAction": "/auth/realms/myrealm/device", + "oauthAction": "/auth/realms/myrealm/login-actions/consent?client_id=account&tab_id=HoAx28ja4xg" }; export const kcContextMocks = [ @@ -344,6 +346,25 @@ export const kcContextMocks = [ ...kcContextCommonMock, "pageId": "terms.ftl" }), + id({ + ...kcContextCommonMock, + "pageId": "login-oauth2-device-verify-user-code.ftl", + url: loginUrl + }), + id({ + ...kcContextCommonMock, + "pageId": "login-oauth-grant.ftl", + oauth: { + code: "5-1N4CIzfi1aprIQjmylI-9e3spLCWW9i5d-GDcs-Sw", + clientScopesRequested: [ + { consentScreenText: "${profileScopeConsentText}" }, + { consentScreenText: "${rolesScopeConsentText}" }, + { consentScreenText: "${emailScopeConsentText}" } + ], + client: "account" + }, + url: loginUrl + }), id({ ...kcContextCommonMock, "pageId": "login-otp.ftl", diff --git a/src/login/lib/useGetClassName.ts b/src/login/lib/useGetClassName.ts index d81a2c0d..28a71def 100644 --- a/src/login/lib/useGetClassName.ts +++ b/src/login/lib/useGetClassName.ts @@ -45,6 +45,7 @@ export const { useGetClassName } = createUseClassName({ "kcInputClass": "form-control", "kcInputErrorMessageClass": "pf-c-form__helper-text pf-m-error required kc-feedback-text", "kcInputWrapperClass": "col-xs-12 col-sm-12 col-md-12 col-lg-12", + "kcFormButtonsWrapperClass": undefined, "kcFormOptionsClass": "col-xs-12 col-sm-12 col-md-12 col-lg-12", "kcFormButtonsClass": "col-xs-12 col-sm-12 col-md-12 col-lg-12", "kcFormSettingClass": "login-pf-settings", diff --git a/src/login/pages/LoginDeviceVerifyUserCode.tsx b/src/login/pages/LoginDeviceVerifyUserCode.tsx new file mode 100644 index 00000000..4c1a6cab --- /dev/null +++ b/src/login/pages/LoginDeviceVerifyUserCode.tsx @@ -0,0 +1,68 @@ +import { clsx } from "keycloakify/tools/clsx"; +import Template from "../Template"; +import { I18n } from "../i18n"; +import { KcContext } from "../kcContext"; +import { useGetClassName } from "../lib/useGetClassName"; +import { PageProps } from "./PageProps"; + +export default function LoginOauthGrant(props: PageProps, I18n>) { + const { kcContext, i18n, doUseDefaultCss, classes } = props; + const { url } = kcContext; + + const { msg, msgStr } = i18n; + + const { getClassName } = useGetClassName({ + doUseDefaultCss, + classes + }); + + return ( + + ); +} diff --git a/src/login/pages/LoginOauthGrant.tsx b/src/login/pages/LoginOauthGrant.tsx new file mode 100644 index 00000000..cad91da1 --- /dev/null +++ b/src/login/pages/LoginOauthGrant.tsx @@ -0,0 +1,73 @@ +import { clsx } from "keycloakify/tools/clsx"; +import { PageProps } from "./PageProps"; +import { KcContext } from "../kcContext"; +import { I18n } from "../i18n"; +import Template from "../Template"; +import { useGetClassName } from "keycloakify/login/lib/useGetClassName"; + +export default function LoginOauthGrant(props: PageProps, I18n>) { + const { kcContext, i18n, doUseDefaultCss, classes } = props; + const { url, oauth, client } = kcContext; + + const { msg, msgStr, advancedMsg, advancedMsgStr } = i18n; + + const { getClassName } = useGetClassName({ + doUseDefaultCss, + classes + }); + + return ( + + ); +} From 0839859feffc62cb84c30c46343a3823db3ad062 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 20:29:26 +0000 Subject: [PATCH 24/39] docs: update README.md [skip ci] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ef895752..44954cbc 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d Koen Poelhekke
    Koen Poelhekke

    💻 Sergey Kupletsky
    Sergey Kupletsky

    ⚠️ 💻 rome-user
    rome-user

    💻 + Céline Pelletier
    Céline Pelletier

    💻 From fadf4e867caec87ba7cac9aff88caf29718a24ed Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 20:29:27 +0000 Subject: [PATCH 25/39] docs: update .all-contributorsrc [skip ci] --- .all-contributorsrc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index b5436d4b..a4303e1a 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -177,6 +177,15 @@ "contributions": [ "code" ] + }, + { + "login": "celinepelletier", + "name": "Céline Pelletier", + "avatar_url": "https://avatars.githubusercontent.com/u/82821620?v=4", + "profile": "https://github.com/celinepelletier", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, From 5d59e652d705e5d1661770a892d42b3ba4ec87af Mon Sep 17 00:00:00 2001 From: Celine Pelletier Date: Fri, 3 Nov 2023 16:48:40 -0400 Subject: [PATCH 26/39] feat: add login-oauth2-device-verify-user-code and login-oauth-grant in storybook --- .../LoginDeviceVerifyUserCode.stories.tsx | 24 +++++++++++++++++++ .../login/pages/LoginOauthGrant.stories.tsx | 24 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 stories/login/pages/LoginDeviceVerifyUserCode.stories.tsx create mode 100644 stories/login/pages/LoginOauthGrant.stories.tsx diff --git a/stories/login/pages/LoginDeviceVerifyUserCode.stories.tsx b/stories/login/pages/LoginDeviceVerifyUserCode.stories.tsx new file mode 100644 index 00000000..8375cd97 --- /dev/null +++ b/stories/login/pages/LoginDeviceVerifyUserCode.stories.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import type { ComponentMeta } from "@storybook/react"; +import { createPageStory } from "../createPageStory"; + +const pageId = "login-oauth2-device-verify-user-code.ftl"; + +const { PageStory } = createPageStory({ pageId }); + +const meta: ComponentMeta = { + title: `login/${pageId}`, + component: PageStory, + parameters: { + viewMode: "story", + previewTabs: { + "storybook/docs/panel": { + "hidden": true + } + } + } +}; + +export default meta; + +export const Default = () => ; diff --git a/stories/login/pages/LoginOauthGrant.stories.tsx b/stories/login/pages/LoginOauthGrant.stories.tsx new file mode 100644 index 00000000..312c9bfd --- /dev/null +++ b/stories/login/pages/LoginOauthGrant.stories.tsx @@ -0,0 +1,24 @@ +import React from "react"; +import type { ComponentMeta } from "@storybook/react"; +import { createPageStory } from "../createPageStory"; + +const pageId = "login-oauth-grant.ftl"; + +const { PageStory } = createPageStory({ pageId }); + +const meta: ComponentMeta = { + title: `login/${pageId}`, + component: PageStory, + parameters: { + viewMode: "story", + previewTabs: { + "storybook/docs/panel": { + "hidden": true + } + } + } +}; + +export default meta; + +export const Default = () => ; From 1ce666f13612b8514ac578381299f571a9d8b6a6 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sat, 4 Nov 2023 15:50:51 +0100 Subject: [PATCH 27/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index facef657..2d2df32f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.2.2", + "version": "8.3.0", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 481d93ebc404b086a15d94e4657bed1ddd34bc87 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sat, 4 Nov 2023 16:29:09 +0100 Subject: [PATCH 28/39] Create symlink to build in keycloak-resource for test env that better reflect prod --- src/bin/copy-keycloak-resources-to-public.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/bin/copy-keycloak-resources-to-public.ts b/src/bin/copy-keycloak-resources-to-public.ts index 3fec0214..cdb3d588 100644 --- a/src/bin/copy-keycloak-resources-to-public.ts +++ b/src/bin/copy-keycloak-resources-to-public.ts @@ -45,5 +45,19 @@ import * as fs from "fs"; fs.writeFileSync(pathJoin(keycloakDirInPublicDir, ".gitignore"), Buffer.from("*", "utf8")); + const buildDirPath = pathJoin(projectDirPath, "build"); + + if (process.platform === "win32" && !fs.existsSync(buildDirPath)) { + fs.mkdirSync(buildDirPath); + } + + try { + fs.symlinkSync(buildDirPath, pathJoin(keycloakDirInPublicDir, "resources", "build")); + } catch (error) { + if (process.platform !== "win32") { + throw error; + } + } + console.log(`${pathRelative(projectDirPath, keycloakDirInPublicDir)} directory created.`); })(); From b53f4f997cf5843fbc1194b7567b5a15d1311e28 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sat, 4 Nov 2023 16:29:36 +0100 Subject: [PATCH 29/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2d2df32f..162d51fd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.3.0", + "version": "8.3.1", "description": "Create Keycloak themes using React", "repository": { "type": "git", From e918788c3f06c33bd6a219164785c879ff6fbedd Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sat, 4 Nov 2023 16:46:51 +0100 Subject: [PATCH 30/39] Reverse previous change, it breaks cra build --- src/bin/copy-keycloak-resources-to-public.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/bin/copy-keycloak-resources-to-public.ts b/src/bin/copy-keycloak-resources-to-public.ts index cdb3d588..3fec0214 100644 --- a/src/bin/copy-keycloak-resources-to-public.ts +++ b/src/bin/copy-keycloak-resources-to-public.ts @@ -45,19 +45,5 @@ import * as fs from "fs"; fs.writeFileSync(pathJoin(keycloakDirInPublicDir, ".gitignore"), Buffer.from("*", "utf8")); - const buildDirPath = pathJoin(projectDirPath, "build"); - - if (process.platform === "win32" && !fs.existsSync(buildDirPath)) { - fs.mkdirSync(buildDirPath); - } - - try { - fs.symlinkSync(buildDirPath, pathJoin(keycloakDirInPublicDir, "resources", "build")); - } catch (error) { - if (process.platform !== "win32") { - throw error; - } - } - console.log(`${pathRelative(projectDirPath, keycloakDirInPublicDir)} directory created.`); })(); From c8b85c43aad13958fd78efe0bab5b8e35ce748b1 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sat, 4 Nov 2023 16:47:58 +0100 Subject: [PATCH 31/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 162d51fd..30949504 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.3.1", + "version": "8.3.2", "description": "Create Keycloak themes using React", "repository": { "type": "git", From c41eae63e7a8f3b66a0c3440e7c9ad00828396cc Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Tue, 7 Nov 2023 16:33:19 +0100 Subject: [PATCH 32/39] Fix info.ftl page rendering in storybook --- src/login/pages/Info.tsx | 5 ++++- stories/login/pages/Info.stories.tsx | 11 ++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/login/pages/Info.tsx b/src/login/pages/Info.tsx index 20bf0f5c..485dcda5 100644 --- a/src/login/pages/Info.tsx +++ b/src/login/pages/Info.tsx @@ -8,7 +8,10 @@ export default function Info(props: PageProps = { export default meta; -export const Default = () => ; +export const Default = () => ( + +); From 7223409eb1664651e0773577059671a05084967d Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Tue, 7 Nov 2023 16:33:33 +0100 Subject: [PATCH 33/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 30949504..ce0ec39e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.3.2", + "version": "8.3.3", "description": "Create Keycloak themes using React", "repository": { "type": "git", From 2657f0113556b65abcd7898374fc1e02116d2d0d Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 19 Nov 2023 03:27:40 +0100 Subject: [PATCH 34/39] Enable to ignore part of the HTML --- .../keycloakify/generateFtl/generateFtl.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/bin/keycloakify/generateFtl/generateFtl.ts b/src/bin/keycloakify/generateFtl/generateFtl.ts index fd9e704e..dceb9029 100644 --- a/src/bin/keycloakify/generateFtl/generateFtl.ts +++ b/src/bin/keycloakify/generateFtl/generateFtl.ts @@ -124,6 +124,27 @@ export function generateFtlFilesCodeFactory(params: { ].join("\n") ); + // Remove part of the document marked as ignored. + { + const startTags = $('meta[name="keycloakify-ignore-start"]'); + + startTags.each((...[, startTag]) => { + const $startTag = $(startTag); + const $endTag = $startTag.nextAll('meta[name="keycloakify-ignore-end"]').first(); + + if ($endTag.length) { + let currentNode = $startTag.next(); + while (currentNode.length && !currentNode.is($endTag)) { + currentNode.remove(); + currentNode = $startTag.next(); + } + + $startTag.remove(); + $endTag.remove(); + } + }); + } + const partiallyFixedIndexHtmlCode = $.html(); function generateFtlFilesCode(params: { pageId: string }): { From 3c54541a7361503c8250248152cdb4a6085cdda7 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Sun, 19 Nov 2023 03:27:54 +0100 Subject: [PATCH 35/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce0ec39e..49929417 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.3.3", + "version": "8.4.0", "description": "Create Keycloak themes using React", "repository": { "type": "git", From b5dd0317c7110f5face716fd288a8830b9d12e6a Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Wed, 22 Nov 2023 11:39:10 +0100 Subject: [PATCH 36/39] Update README.md --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 44954cbc..18e5fe44 100644 --- a/README.md +++ b/README.md @@ -47,12 +47,13 @@ > 📣 🛑 Account themes generated by Keycloakify are not currently compatible with Keycloak 22. > We are working on a solution. [Follow progress](https://github.com/keycloakify/keycloakify/issues/389). -> Login and email themes are not affected. -> UPDATE: [The PR](https://github.com/keycloak/keycloak/pull/22317) that should future proof Keycloakify account themes has been greenlighted -> by the Keycloak team. Resolution is only a matter of time. +> **Login and email themes are not affected**. +> UPDATE: [The PR](https://github.com/keycloak/keycloak/pull/22317) that should future proof Keycloakify account themes has been +> merged into Keycloak! 🥳 Credit to @xgp. We are now waiting for a new Keycloak release to be published. + Keycloakify is fully compatible with Keycloak, starting from version 11 and is anticipated to maintain compatibility with all future versions. -You can update your Keycloak, your Keycloakify generated theme won't break. +You can update your Keycloak, your Keycloakify generated theme won't break. (Well except for Keycloak 22's Account theme obviously but this was hopefully a one time debacle) To understand the basis of my confidence in this, you can [visit this discussion thread where I've explained in detail](https://github.com/keycloakify/keycloakify/discussions/346#discussioncomment-5889791). ## Sponsor 👼 From bb007ddce526c88ad514428772fb4c8986cebaaf Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Wed, 22 Nov 2023 11:44:58 +0100 Subject: [PATCH 37/39] fmt --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 18e5fe44..e6ca7598 100644 --- a/README.md +++ b/README.md @@ -49,11 +49,10 @@ > We are working on a solution. [Follow progress](https://github.com/keycloakify/keycloakify/issues/389). > **Login and email themes are not affected**. > UPDATE: [The PR](https://github.com/keycloak/keycloak/pull/22317) that should future proof Keycloakify account themes has been -> merged into Keycloak! 🥳 Credit to @xgp. We are now waiting for a new Keycloak release to be published. - +> merged into Keycloak! 🥳 Credit to @xgp. We are now waiting for a new Keycloak release to be published. Keycloakify is fully compatible with Keycloak, starting from version 11 and is anticipated to maintain compatibility with all future versions. -You can update your Keycloak, your Keycloakify generated theme won't break. (Well except for Keycloak 22's Account theme obviously but this was hopefully a one time debacle) +You can update your Keycloak, your Keycloakify generated theme won't break. (Well except for Keycloak 22's Account theme obviously but this was hopefully a one time debacle) To understand the basis of my confidence in this, you can [visit this discussion thread where I've explained in detail](https://github.com/keycloakify/keycloakify/discussions/346#discussioncomment-5889791). ## Sponsor 👼 From e1afc1cf7a7886ec44020854739a50b998a9b011 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Wed, 22 Nov 2023 18:00:29 +0100 Subject: [PATCH 38/39] Add themeVersion in KcContext type --- src/account/kcContext/KcContext.ts | 1 + src/account/kcContext/kcContextMocks.ts | 1 + src/login/kcContext/KcContext.ts | 1 + src/login/kcContext/kcContextMocks.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/src/account/kcContext/KcContext.ts b/src/account/kcContext/KcContext.ts index 0e49c5f2..406568b7 100644 --- a/src/account/kcContext/KcContext.ts +++ b/src/account/kcContext/KcContext.ts @@ -6,6 +6,7 @@ export type KcContext = KcContext.Password | KcContext.Account; export declare namespace KcContext { export type Common = { + themeVersion: string; keycloakifyVersion: string; themeType: "account"; themeName: string; diff --git a/src/account/kcContext/kcContextMocks.ts b/src/account/kcContext/kcContextMocks.ts index 31441113..82d9e3fe 100644 --- a/src/account/kcContext/kcContextMocks.ts +++ b/src/account/kcContext/kcContextMocks.ts @@ -7,6 +7,7 @@ import type { KcContext } from "./KcContext"; const PUBLIC_URL = (typeof process !== "object" ? undefined : process.env?.["PUBLIC_URL"]) || "/"; export const kcContextCommonMock: KcContext.Common = { + "themeVersion": "0.0.0", "keycloakifyVersion": "0.0.0", "themeType": "account", "themeName": "my-theme-name", diff --git a/src/login/kcContext/KcContext.ts b/src/login/kcContext/KcContext.ts index 9b61648d..3dd526d9 100644 --- a/src/login/kcContext/KcContext.ts +++ b/src/login/kcContext/KcContext.ts @@ -39,6 +39,7 @@ export type KcContext = export declare namespace KcContext { export type Common = { + themeVersion: string; keycloakifyVersion: string; themeType: "login"; themeName: string; diff --git a/src/login/kcContext/kcContextMocks.ts b/src/login/kcContext/kcContextMocks.ts index 2ed52faf..6dc1edb4 100644 --- a/src/login/kcContext/kcContextMocks.ts +++ b/src/login/kcContext/kcContextMocks.ts @@ -103,6 +103,7 @@ const attributes: Attribute[] = [ const attributesByName = Object.fromEntries(attributes.map(attribute => [attribute.name, attribute])) as any; export const kcContextCommonMock: KcContext.Common = { + "themeVersion": "0.0.0", "keycloakifyVersion": "0.0.0", "themeType": "login", "themeName": "my-theme-name", From 1a326bf7e418d9fee5651528d34d490dd138b4b2 Mon Sep 17 00:00:00 2001 From: Joseph Garrone Date: Wed, 22 Nov 2023 18:58:04 +0100 Subject: [PATCH 39/39] Bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 49929417..7273fd79 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloakify", - "version": "8.4.0", + "version": "8.4.1", "description": "Create Keycloak themes using React", "repository": { "type": "git",