diff --git a/src/bin/build-keycloak-theme/generateFtl/ftl2js.ftl b/src/bin/build-keycloak-theme/generateFtl/ftl2js.ftl
deleted file mode 100644
index 5c060197..00000000
--- a/src/bin/build-keycloak-theme/generateFtl/ftl2js.ftl
+++ /dev/null
@@ -1,214 +0,0 @@
-
\ No newline at end of file
diff --git a/src/bin/build-keycloak-theme/generateFtl/index.ts b/src/bin/build-keycloak-theme/generateFtl/index.ts
index 3f906039..e4052bb6 100644
--- a/src/bin/build-keycloak-theme/generateFtl/index.ts
+++ b/src/bin/build-keycloak-theme/generateFtl/index.ts
@@ -7,7 +7,14 @@ import {
} from "../replaceImportFromStatic";
import fs from "fs";
import { join as pathJoin } from "path";
-import { objectKeys } from "evt/tools/typeSafety/objectKeys";
+import { objectKeys } from "evt/tools/typeSafety/objectKeys";
+
+function loadFtlFile(ftlFileBasename: "template.ftl" | "login.ftl" | "register.ftl") {
+ return fs.readFileSync(pathJoin(__dirname, ftlFileBasename))
+ .toString("utf8")
+ .match(/^',
'',
- objectKeys(ftlPlaceholders)[1],
+ objectKeys(ftlCommonPlaceholders)[1],
''
].join("\n"),
);
@@ -102,11 +106,42 @@ export function generateFtlFilesCodeFactory(
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
+ const ftlPlaceholders = {
+ '{ "x": "kxOlLqMeOed9sdLdIdOxd444" }': loadFtlFile(pageBasename),
+ ...ftlCommonPlaceholders
+ };
+
$("head").prepend(
[
'',
'',
''
].join("\n")
diff --git a/src/bin/build-keycloak-theme/generateFtl/login.ftl b/src/bin/build-keycloak-theme/generateFtl/login.ftl
new file mode 100644
index 00000000..5169ddbd
--- /dev/null
+++ b/src/bin/build-keycloak-theme/generateFtl/login.ftl
@@ -0,0 +1,81 @@
+
\ No newline at end of file
diff --git a/src/bin/build-keycloak-theme/generateFtl/register.ftl b/src/bin/build-keycloak-theme/generateFtl/register.ftl
new file mode 100644
index 00000000..ff491d9e
--- /dev/null
+++ b/src/bin/build-keycloak-theme/generateFtl/register.ftl
@@ -0,0 +1,46 @@
+
\ No newline at end of file
diff --git a/src/bin/build-keycloak-theme/generateFtl/template.ftl b/src/bin/build-keycloak-theme/generateFtl/template.ftl
new file mode 100644
index 00000000..5764bafa
--- /dev/null
+++ b/src/bin/build-keycloak-theme/generateFtl/template.ftl
@@ -0,0 +1,115 @@
+
\ No newline at end of file
diff --git a/src/lib/components/KcApp.tsx b/src/lib/components/KcApp.tsx
index c4275aa0..d8352acb 100644
--- a/src/lib/components/KcApp.tsx
+++ b/src/lib/components/KcApp.tsx
@@ -1,7 +1,7 @@
import { memo } from "react";
import { kcContext } from "../kcContext";
-import { assert } from "evt/tools/typeSafety/assert";
+import { assert } from "../tools/assert";
import type { KcPagesProperties } from "./KcProperties";
import { Login } from "./Login";
import { Register } from "./Register";
diff --git a/src/lib/components/Login.tsx b/src/lib/components/Login.tsx
index a4bdb663..ddcd60b5 100644
--- a/src/lib/components/Login.tsx
+++ b/src/lib/components/Login.tsx
@@ -3,8 +3,8 @@ import { useState, memo } from "react";
import { Template } from "./Template";
import type { KcPagesProperties } from "./KcProperties";
import { defaultKcPagesProperties } from "./KcProperties";
-import { assert } from "evt/tools/typeSafety/assert";
-import { kcContext } from "../kcContext";
+import { assert } from "../tools/assert";
+import { kcContext } from "../kcContext";
import { useKcTranslation } from "../i18n/useKcTranslation";
import { cx } from "tss-react";
import { useConstCallback } from "powerhooks";
@@ -25,13 +25,16 @@ export const Login = memo((props: LoginProps) => {
social, realm, url,
usernameEditDisabled, login,
auth, registrationDisabled
- }] = useState(() => (
+ }] = useState(() => {
+
assert(
- kcContext !== undefined,
- "App is currently being served by keycloak"
- ),
- kcContext
- ));
+ kcContext !== undefined &&
+ kcContext.pageBasename === "login.ftl"
+ );
+
+ return kcContext;
+
+ });
const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
diff --git a/src/lib/components/Register.tsx b/src/lib/components/Register.tsx
index 061c9596..03563961 100644
--- a/src/lib/components/Register.tsx
+++ b/src/lib/components/Register.tsx
@@ -4,7 +4,7 @@ import { useState, memo } from "react";
import { Template } from "./Template";
import type { KcPagesProperties } from "./KcProperties";
import { defaultKcPagesProperties } from "./KcProperties";
-import { assert } from "evt/tools/typeSafety/assert";
+import { assert } from "../tools/assert";
import { kcContext } from "../kcContext";
import { useKcTranslation } from "../i18n/useKcTranslation";
import { cx } from "tss-react";
@@ -29,13 +29,16 @@ export const Register = memo((props: RegisterPageProps) => {
passwordRequired,
recaptchaRequired,
recaptchaSiteKey
- }] = useState(() => (
+ }] = useState(() => {
+
assert(
- kcContext !== undefined,
- "App is currently being served by keycloak"
- ),
- kcContext
- ));
+ kcContext !== undefined &&
+ kcContext.pageBasename === "register.ftl"
+ );
+
+ return kcContext;
+
+ });
return (
["generateFtlFilesCode"]>[0]["pageBasename"];
- url: {
- loginAction: string;
- resourcesPath: string;
- resourcesCommonPath: string;
- loginRestartFlowUrl: string;
- loginResetCredentialsUrl: string;
- registrationUrl: string;
- //Specific to register
- registrationAction: string;
- loginUrl: string;
- };
- realm: {
- displayName?: string;
- displayNameHtml?: string;
- internationalizationEnabled: boolean;
- password: boolean;
- loginWithEmailAllowed: boolean;
- registrationEmailAsUsername: boolean;
- rememberMe: boolean;
- resetPasswordAllowed: boolean;
- };
- /** Undefined if !realm.internationalizationEnabled */
- locale?: {
- supported: {
- //url: string;
- languageTag: KcLanguageTag;
- /** Is determined by languageTag. Ex: languageTag === "en" => label === "English"
- * or getLanguageLabel(languageTag) === label
- */
- //label: LanguageLabel;
- }[];
- //NOTE: We do not expose this because the language is managed
- //client side. We use this value however to set the default.
- //current: LanguageLabel;
- },
- auth?: {
- showUsername: boolean;
- showResetCredentials: boolean;
- showTryAnotherWayLink: boolean;
- attemptedUsername?: boolean;
- selectedCredential?: string;
- };
- scripts: string[];
- message?: {
- type: "success" | "warning" | "error" | "info";
- summary: string;
- };
- isAppInitiatedAction: boolean;
- social: {
- displayInfo: boolean;
- providers?: {
+export declare namespace KcContext {
+
+ export type Template = {
+ url: {
+ loginAction: string;
+ resourcesPath: string;
+ resourcesCommonPath: string;
+ loginRestartFlowUrl: string;
loginUrl: string;
- alias: string;
- providerId: string;
- displayName: string;
- }[]
- };
- usernameEditDisabled: boolean;
- login: {
- username?: string;
- rememberMe: boolean;
- };
- registrationDisabled: boolean;
- //Specific to register
- messagesPerField: {
- printIfExists(
- key:
- "userLabel" |
- "username" |
- "email" |
- "firstName" |
- "lastName" |
- "password" |
- "password-confirm",
- x: T
- ): T | undefined;
- };
- register: {
- formData: {
- firstName?: string;
+ };
+ realm: {
displayName?: string;
- lastName?: string;
- email?: string;
- username?: string;
- }
+ displayNameHtml?: string;
+ internationalizationEnabled: boolean;
+ password: boolean;
+ registrationEmailAsUsername: boolean;
+ };
+ /** Undefined if !realm.internationalizationEnabled */
+ locale?: {
+ supported: {
+ //url: string;
+ languageTag: KcLanguageTag;
+ /** Is determined by languageTag. Ex: languageTag === "en" => label === "English"
+ * or getLanguageLabel(languageTag) === label
+ */
+ //label: LanguageLabel;
+ }[];
+ //NOTE: We do not expose this because the language is managed
+ //client side. We use this value however to set the default.
+ //current: LanguageLabel;
+ },
+ auth?: {
+ showUsername: boolean;
+ showResetCredentials: boolean;
+ showTryAnotherWayLink: boolean;
+ attemptedUsername?: boolean;
+ };
+ scripts: string[];
+ message?: {
+ type: "success" | "warning" | "error" | "info";
+ summary: string;
+ };
+ isAppInitiatedAction: boolean;
};
- passwordRequired: boolean;
- recaptchaRequired: boolean;
- recaptchaSiteKey: string;
-};
+
+ export type Login = Template & {
+ pageBasename: "login.ftl";
+ url: {
+ loginResetCredentialsUrl: string;
+ registrationUrl: string;
+ };
+ realm: {
+ loginWithEmailAllowed: boolean;
+ rememberMe: boolean;
+ resetPasswordAllowed: boolean;
+ };
+ auth: {
+ selectedCredential?: string;
+ };
+ registrationDisabled: boolean;
+ login: {
+ username?: string;
+ rememberMe: boolean;
+ };
+ usernameEditDisabled: boolean;
+ social: {
+ displayInfo: boolean;
+ providers?: {
+ loginUrl: string;
+ alias: string;
+ providerId: string;
+ displayName: string;
+ }[]
+ };
+ };
+
+ export type Register = Template & {
+ pageBasename: "register.ftl";
+ url: {
+ registrationAction: string;
+ };
+ messagesPerField: {
+ printIfExists(
+ key:
+ "userLabel" |
+ "username" |
+ "email" |
+ "firstName" |
+ "lastName" |
+ "password" |
+ "password-confirm",
+ x: T
+ ): T | undefined;
+ };
+ register: {
+ formData: {
+ firstName?: string;
+ displayName?: string;
+ lastName?: string;
+ email?: string;
+ username?: string;
+ }
+ };
+ passwordRequired: boolean;
+ recaptchaRequired: boolean;
+ recaptchaSiteKey: string;
+ };
+
+}
+
+{
+ type T = KcContext["pageBasename"];
+ type U = Parameters["generateFtlFilesCode"]>[0]["pageBasename"];
+
+ doExtends();
+ doExtends();
+}
export const kcContext = id((window as any)[ftlValuesGlobalName]);
diff --git a/src/lib/kcContext.ts.disabled b/src/lib/kcContext.ts.disabled
deleted file mode 100644
index 2f02aca8..00000000
--- a/src/lib/kcContext.ts.disabled
+++ /dev/null
@@ -1,125 +0,0 @@
-
-import { ftlValuesGlobalName } from "../bin/build-keycloak-theme/ftlValuesGlobalName";
-import type { generateFtlFilesCodeFactory } from "../bin/build-keycloak-theme/generateFtl";
-import { id } from "evt/tools/typeSafety/id";
-import type { KcLanguageTag } from "./i18n/KcLanguageTag";
-import { doExtends } from "evt/tools/typeSafety/doExtends";
-
-export type KcContext = KcContext.Login | KcContext.Register;
-
-export declare namespace KcContext {
-
- export type Template = {};
-
- export type Login = Template & {
- pageBasename: "login.ftl";
- };
-
- export type Register = Template & {
- pageBasename: "register.ftl";
- };
-
-}
-
-{
- type T = KcContext["pageBasename"];
- type U = Parameters["generateFtlFilesCode"]>[0]["pageBasename"];
-
- doExtends();
- doExtends();
-
-}
-
-
-export type KcContext = {
- pageBasename: Parameters["generateFtlFilesCode"]>[0]["pageBasename"];
- url: {
- loginAction: string;
- resourcesPath: string;
- resourcesCommonPath: string;
- loginRestartFlowUrl: string;
- loginResetCredentialsUrl: string;
- registrationUrl: string;
- registrationAction: string;
- loginUrl: string;
- };
- realm: {
- displayName?: string;
- displayNameHtml?: string;
- internationalizationEnabled: boolean;
- password: boolean;
- loginWithEmailAllowed: boolean;
- registrationEmailAsUsername: boolean;
- rememberMe: boolean;
- resetPasswordAllowed: boolean;
- };
- /** Undefined if !realm.internationalizationEnabled */
- locale?: {
- supported: {
- //url: string;
- languageTag: KcLanguageTag;
- /** Is determined by languageTag. Ex: languageTag === "en" => label === "English"
- * or getLanguageLabel(languageTag) === label
- */
- //label: LanguageLabel;
- }[];
- //NOTE: We do not expose this because the language is managed
- //client side. We use this value however to set the default.
- //current: LanguageLabel;
- },
- auth?: {
- showUsername: boolean;
- showResetCredentials: boolean;
- showTryAnotherWayLink: boolean;
- attemptedUsername?: boolean;
- selectedCredential?: string;
- };
- scripts: string[];
- message?: {
- type: "success" | "warning" | "error" | "info";
- summary: string;
- };
- isAppInitiatedAction: boolean;
- social: {
- displayInfo: boolean;
- providers?: {
- loginUrl: string;
- alias: string;
- providerId: string;
- displayName: string;
- }[]
- };
- usernameEditDisabled: boolean;
- login: {
- username?: string;
- rememberMe: boolean;
- };
- registrationDisabled: boolean;
- messagesPerField: {
- printIfExists(
- key:
- "userLabel" |
- "username" |
- "email" |
- "firstName" |
- "lastName" |
- "password" |
- "password-confirm",
- x: T
- ): T | undefined;
- };
- register: {
- formData: {
- firstName?: string;
- displayName?: string;
- lastName?: string;
- email?: string;
- username?: string;
- }
- };
- passwordRequired: boolean;
- recaptchaRequired: boolean;
- recaptchaSiteKey: string;
-};
-
-export const kcContext = id((window as any)[ftlValuesGlobalName]);
diff --git a/src/lib/tools/assert.ts b/src/lib/tools/assert.ts
new file mode 100644
index 00000000..bd770e8d
--- /dev/null
+++ b/src/lib/tools/assert.ts
@@ -0,0 +1,2 @@
+
+export { assert } from "evt/tools/typeSafety/assert";
\ No newline at end of file