Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
2f16a09ab8 | |||
183ae98c30 | |||
ba15e63879 | |||
654277feda | |||
81279a5cc5 | |||
59f0a843b0 | |||
c094f70171 | |||
0858fe6319 | |||
5012ec0ccc | |||
990a24fab2 | |||
036b6bf82a | |||
8272a02b52 | |||
e346b1d9d2 | |||
2309bd21c6 | |||
7d6476c1b5 | |||
e892a0e7e6 | |||
ca5b41e730 |
20
CHANGELOG.md
20
CHANGELOG.md
@ -1,3 +1,23 @@
|
||||
### **0.3.19** (2021-04-01)
|
||||
|
||||
- Fix previous release
|
||||
|
||||
### **0.3.18** (2021-04-01)
|
||||
|
||||
- Fix error.ftt, Adopt best effort strategy to convert ftl values into JS
|
||||
|
||||
### **0.3.17** (2021-03-29)
|
||||
|
||||
- Use push instead of replace in keycloak-js adapter to enable going back
|
||||
|
||||
### **0.3.15** (2021-03-28)
|
||||
|
||||
- Remove all reference to --external-assets, broken feature
|
||||
|
||||
### **0.3.14** (2021-03-28)
|
||||
|
||||
- Fix standalone mode: imports from js
|
||||
|
||||
### **0.3.13** (2021-03-26)
|
||||
|
||||
|
||||
|
51
README.md
51
README.md
@ -41,7 +41,6 @@ Here is `yarn add keycloakify` for you 🍸
|
||||
- [Motivations](#motivations)
|
||||
- [How to use](#how-to-use)
|
||||
- [Setting up the build tool](#setting-up-the-build-tool)
|
||||
- [Specify from where the resources should be downloaded.](#specify-from-where-the-resources-should-be-downloaded)
|
||||
- [Developing your login and register pages in your React app](#developing-your-login-and-register-pages-in-your-react-app)
|
||||
- [Just changing the look](#just-changing-the-look)
|
||||
- [Changing the look **and** feel](#changing-the-look-and-feel)
|
||||
@ -70,10 +69,8 @@ Here is `yarn add keycloakify` for you 🍸
|
||||
"keycloak": "yarn build && build-keycloak-theme",
|
||||
},
|
||||
```
|
||||
`"homepage"` must be specified only if the theme is build using
|
||||
`--external-assets`(#specify-from-where-the-resources-should-be-downloaded) or if
|
||||
the url path is not `/` (only the url path will be considered so it doesn't matter if the
|
||||
base url is wrong)
|
||||
`"homepage"` must be specified only if the url path is not `/`
|
||||
(Onl `/YOUR-APP` matters `URL.OF` don't have to be the actual domain)
|
||||
|
||||
It is mandatory that you specify the url where your app will be available
|
||||
using the `homepage` field.
|
||||
@ -85,46 +82,6 @@ dependency with `yarn install` and build the keycloak theme with
|
||||
Once the build is complete instructions about how to load
|
||||
the theme into Keycloak are printed in the console.
|
||||
|
||||
### Specify from where the resources should be downloaded.
|
||||
|
||||
*TL;DR*: Building the theme with the `--external-assets` option enables the login
|
||||
page to load faster for first time users but it also implies that:
|
||||
- If the app is down, your Keycloak login and register pages are down as well.
|
||||
- Each time the app is updated, the theme must be updated.
|
||||
- CORS must be enabled for fonts.
|
||||
- You must know at build time what will be the url of your app (`"homepage"` in `package.json`).
|
||||
|
||||
<details>
|
||||
<summary>Click to expand</summary>
|
||||
|
||||
When you run `npx build-keycloak-theme` without arguments, Keycloakify will build
|
||||
a standalone version of the Keycloak theme. That is to say even if your app, the
|
||||
one hosted at the url specified as `homepage`, is down the Keycloak theme will still work.
|
||||
It also mean that you won't have to update your theme on your Keycloak server each time
|
||||
your app is updated.
|
||||
In this mode, the default, every asset are served by the keycloak server.
|
||||
The drawback of this approach is that when users access the login page for the first time
|
||||
they have to download the whole app again.
|
||||
You probably have [long-term asset caching](https://create-react-app.dev/docs/production-build/#static-file-caching)
|
||||
enabled in the server that host your app ([example](https://github.com/garronej/keycloakify-demo-app/blob/224c43383548635a463fa68e8909c147ac189f0e/nginx.conf#L14))
|
||||
so it can be interesting to only serve the html from Keycloak server and everything
|
||||
else, your JS bundles, your CSS ect from the server that host your app.
|
||||
|
||||
To enable this behavior you car run:
|
||||
```bash
|
||||
npx build-keycloak-theme --external-assets
|
||||
```
|
||||
(instead of `npx build-keycloak-theme`)
|
||||
|
||||
This is something you probably want to do in your CI pipeline. [Example](https://github.com/garronej/keycloakify-demo-app/blob/224c43383548635a463fa68e8909c147ac189f0e/.github/workflows/ci.yaml#L112)
|
||||
|
||||
Also note that there is [a same-origin policy exception for fonts](https://en.wikipedia.org/wiki/Same-origin_policy#cite_note-3) so you must enabled
|
||||
CORS for fonts on the server hosting your app. Concretely this mean that your server should add a `Access-Control-Allow-Origin: *` response header to
|
||||
GET request on *.woff2?. [Example with Nginx](https://github.com/garronej/keycloakify-demo-app/blob/224c43383548635a463fa68e8909c147ac189f0e/nginx.conf#L18-L20)
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
## Developing your login and register pages in your React app
|
||||
|
||||
### Just changing the look
|
||||
@ -240,8 +197,6 @@ NOTE: This build tool has only be tested on MacOS.
|
||||
You won't be able to [import things from your public directory in your JavaScript code](https://create-react-app.dev/docs/using-the-public-folder/#adding-assets-outside-of-the-module-system). (This isn't recommended anyway).
|
||||
|
||||
## `@font-face` importing fonts from the `src/` dir
|
||||
|
||||
**If you are building the theme with `--external-assets` this limitation doesn't apply.**
|
||||
### Example of setup that **won't** work
|
||||
|
||||
- We have a `fonts/` directory in `src/`
|
||||
@ -322,5 +277,5 @@ flash of the blank html before the js bundle have been evaluated
|
||||
|
||||
Part of the lib that runs with node, at build time.
|
||||
|
||||
- `npx build-keycloak-theme [--external-assets]`: Builds the theme, the CWD is assumed to be the root of your react project.
|
||||
- `npx build-keycloak-theme`: Builds the theme, the CWD is assumed to be the root of your react project.
|
||||
- `npx download-sample-keycloak-themes`: Downloads the keycloak default themes (for development purposes)
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "keycloakify",
|
||||
"version": "0.3.13",
|
||||
"version": "0.3.19",
|
||||
"description": "Keycloak theme generator for Reacts app",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -14,8 +14,7 @@
|
||||
"grant-exec-perms": "node dist/bin/tools/grant-exec-perms.js",
|
||||
"test": "node dist/test",
|
||||
"copy-files": "copyfiles -u 1 src/**/*.ftl src/**/*.xml src/**/*.js dist/",
|
||||
"generate-messages": "node dist/bin/generate-i18n-messages.js",
|
||||
"watch": "tsc -w"
|
||||
"generate-messages": "node dist/bin/generate-i18n-messages.js"
|
||||
},
|
||||
"bin": {
|
||||
"build-keycloak-theme": "dist/bin/build-keycloak-theme/index.js",
|
||||
|
@ -1,17 +1,27 @@
|
||||
<script>const _=
|
||||
{
|
||||
"url": {
|
||||
"loginAction": "${url.loginAction?no_esc}",
|
||||
"resourcesPath": "${url.resourcesPath?no_esc}",
|
||||
"resourcesCommonPath": "${url.resourcesCommonPath?no_esc}",
|
||||
"loginRestartFlowUrl": "${url.loginRestartFlowUrl?no_esc}",
|
||||
"loginUrl": "${url.loginUrl?no_esc}"
|
||||
},
|
||||
"url": (function (){
|
||||
|
||||
<#if url?has_content>
|
||||
|
||||
return {
|
||||
"loginAction": "${(url.loginAction!'')?no_esc}",
|
||||
"resourcesPath": "${(url.resourcesPath!'')?no_esc}",
|
||||
"resourcesCommonPath": "${(url.resourcesCommonPath!'')?no_esc}",
|
||||
"loginRestartFlowUrl": "${(url.loginRestartFlowUrl!'')?no_esc}",
|
||||
"loginUrl": "${(url.loginUrl!'')?no_esc}"
|
||||
};
|
||||
|
||||
</#if>
|
||||
|
||||
return undefined;
|
||||
|
||||
})(),
|
||||
"realm": {
|
||||
"displayName": "${realm.displayName!''}" || undefined,
|
||||
"displayNameHtml": "${realm.displayNameHtml!''}" || undefined,
|
||||
"internationalizationEnabled": ${realm.internationalizationEnabled?c},
|
||||
"registrationEmailAsUsername": ${realm.registrationEmailAsUsername?c},
|
||||
"internationalizationEnabled": ${(realm.internationalizationEnabled!false)?c},
|
||||
"registrationEmailAsUsername": ${(realm.registrationEmailAsUsername!false)?c},
|
||||
},
|
||||
"locale": (function (){
|
||||
|
||||
@ -20,23 +30,17 @@
|
||||
return {
|
||||
"supported": (function(){
|
||||
|
||||
<#if realm.internationalizationEnabled>
|
||||
var out= [];
|
||||
|
||||
var out= [];
|
||||
<#list locale.supported as lng>
|
||||
out.push({
|
||||
"url": "${lng.url?no_esc}",
|
||||
"label": "${lng.label}",
|
||||
"languageTag": "${lng.languageTag}"
|
||||
});
|
||||
</#list>
|
||||
|
||||
<#list locale.supported as lng>
|
||||
out.push({
|
||||
"url": "${lng.url?no_esc}",
|
||||
"label": "${lng.label}",
|
||||
"languageTag": "${lng.languageTag}"
|
||||
});
|
||||
</#list>
|
||||
|
||||
return out;
|
||||
|
||||
</#if>
|
||||
|
||||
return undefined;
|
||||
return out;
|
||||
|
||||
})(),
|
||||
"current": "${locale.current}"
|
||||
@ -46,10 +50,10 @@
|
||||
|
||||
return undefined;
|
||||
|
||||
|
||||
})(),
|
||||
"auth": (function (){
|
||||
|
||||
|
||||
<#if auth?has_content>
|
||||
|
||||
var out= {
|
||||
@ -71,9 +75,9 @@
|
||||
|
||||
</#if>
|
||||
|
||||
|
||||
return undefined;
|
||||
|
||||
|
||||
})(),
|
||||
"scripts": (function(){
|
||||
|
@ -19,7 +19,7 @@ function loadAdjacentFile(fileBasename: string) {
|
||||
.toString("utf8");
|
||||
};
|
||||
|
||||
function loadFtlFile(ftlFileBasename: PageId | "template.ftl") {
|
||||
function loadFtlFile(ftlFileBasename: PageId | "common.ftl") {
|
||||
try {
|
||||
|
||||
return loadAdjacentFile(ftlFileBasename)
|
||||
@ -37,12 +37,7 @@ export function generateFtlFilesCodeFactory(
|
||||
cssGlobalsToDefine: Record<string, string>;
|
||||
indexHtmlCode: string;
|
||||
urlPathname: string;
|
||||
} & ({
|
||||
mode: "standalone";
|
||||
} | {
|
||||
mode: "external assets";
|
||||
urlOrigin: string;
|
||||
})
|
||||
}
|
||||
) {
|
||||
|
||||
const { ftlValuesGlobalName, cssGlobalsToDefine, indexHtmlCode, urlPathname } = params;
|
||||
@ -53,19 +48,7 @@ export function generateFtlFilesCodeFactory(
|
||||
|
||||
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
|
||||
ftlValuesGlobalName,
|
||||
"jsCode": $(element).html()!,
|
||||
...(() => {
|
||||
switch (params.mode) {
|
||||
case "standalone": return {
|
||||
"mode": params.mode
|
||||
};
|
||||
case "external assets": return {
|
||||
"mode": params.mode,
|
||||
"urlOrigin": params.urlOrigin,
|
||||
"urlPathname": params.urlPathname,
|
||||
};
|
||||
}
|
||||
})()
|
||||
"jsCode": $(element).html()!
|
||||
});
|
||||
|
||||
$(element).text(fixedJsCode);
|
||||
@ -76,18 +59,7 @@ export function generateFtlFilesCodeFactory(
|
||||
|
||||
const { fixedCssCode } = replaceImportsInInlineCssCode({
|
||||
"cssCode": $(element).html()!,
|
||||
"urlPathname": params.urlPathname,
|
||||
...(() => {
|
||||
switch (params.mode) {
|
||||
case "standalone": return {
|
||||
"mode": params.mode
|
||||
};
|
||||
case "external assets": return {
|
||||
"mode": params.mode,
|
||||
"urlOrigin": params.urlOrigin,
|
||||
};
|
||||
}
|
||||
})()
|
||||
"urlPathname": params.urlPathname
|
||||
});
|
||||
|
||||
$(element).text(fixedCssCode);
|
||||
@ -106,31 +78,20 @@ export function generateFtlFilesCodeFactory(
|
||||
return;
|
||||
}
|
||||
|
||||
switch (params.mode) {
|
||||
case "external assets":
|
||||
$(element).attr(
|
||||
attrName,
|
||||
href.replace(/^\//, `${params.urlOrigin}/`)
|
||||
);
|
||||
break;
|
||||
case "standalone":
|
||||
$(element).attr(
|
||||
attrName,
|
||||
href.replace(
|
||||
new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`),
|
||||
"${url.resourcesPath}/build/"
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
$(element).attr(
|
||||
attrName,
|
||||
href.replace(
|
||||
new RegExp(`^${urlPathname.replace(/\//g, "\\/")}`),
|
||||
"${url.resourcesPath}/build/"
|
||||
)
|
||||
);
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
|
||||
const ftlCommonPlaceholders = {
|
||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadFtlFile("template.ftl"),
|
||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadFtlFile("common.ftl"),
|
||||
'<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->':
|
||||
[
|
||||
'<#if scripts??>',
|
||||
|
@ -21,12 +21,7 @@ export function generateKeycloakThemeResources(
|
||||
reactAppBuildDirPath: string;
|
||||
keycloakThemeBuildingDirPath: string;
|
||||
urlPathname: string;
|
||||
} & ({
|
||||
mode: "standalone";
|
||||
} | {
|
||||
mode: "external assets";
|
||||
urlOrigin: string;
|
||||
})
|
||||
}
|
||||
) {
|
||||
|
||||
const { themeName, reactAppBuildDirPath, keycloakThemeBuildingDirPath, urlPathname } = params;
|
||||
@ -50,34 +45,31 @@ export function generateKeycloakThemeResources(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (params.mode === "standalone") {
|
||||
|
||||
if (/\.css?$/i.test(filePath)) {
|
||||
if (/\.css?$/i.test(filePath)) {
|
||||
|
||||
const { cssGlobalsToDefine, fixedCssCode } = replaceImportsInCssCode(
|
||||
{ "cssCode": sourceCode.toString("utf8") }
|
||||
);
|
||||
const { cssGlobalsToDefine, fixedCssCode } = replaceImportsInCssCode(
|
||||
{ "cssCode": sourceCode.toString("utf8") }
|
||||
);
|
||||
|
||||
allCssGlobalsToDefine = {
|
||||
...allCssGlobalsToDefine,
|
||||
...cssGlobalsToDefine
|
||||
};
|
||||
allCssGlobalsToDefine = {
|
||||
...allCssGlobalsToDefine,
|
||||
...cssGlobalsToDefine
|
||||
};
|
||||
|
||||
return { "modifiedSourceCode": Buffer.from(fixedCssCode, "utf8") };
|
||||
return { "modifiedSourceCode": Buffer.from(fixedCssCode, "utf8") };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (/\.js?$/i.test(filePath)) {
|
||||
|
||||
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
|
||||
"jsCode": sourceCode.toString("utf8"),
|
||||
ftlValuesGlobalName,
|
||||
"mode": params.mode
|
||||
});
|
||||
if (/\.js?$/i.test(filePath)) {
|
||||
|
||||
return { "modifiedSourceCode": Buffer.from(fixedJsCode, "utf8") };
|
||||
const { fixedJsCode } = replaceImportsFromStaticInJsCode({
|
||||
"jsCode": sourceCode.toString("utf8"),
|
||||
ftlValuesGlobalName
|
||||
});
|
||||
|
||||
}
|
||||
return { "modifiedSourceCode": Buffer.from(fixedJsCode, "utf8") };
|
||||
|
||||
}
|
||||
|
||||
@ -92,18 +84,7 @@ export function generateKeycloakThemeResources(
|
||||
"indexHtmlCode": fs.readFileSync(
|
||||
pathJoin(reactAppBuildDirPath, "index.html")
|
||||
).toString("utf8"),
|
||||
urlPathname,
|
||||
...(() => {
|
||||
switch (params.mode) {
|
||||
case "external assets": return {
|
||||
"mode": params.mode,
|
||||
"urlOrigin": params.urlOrigin
|
||||
};
|
||||
case "standalone": return {
|
||||
"mode": params.mode
|
||||
};
|
||||
}
|
||||
})()
|
||||
urlPathname
|
||||
});
|
||||
|
||||
pageIds.forEach(pageId => {
|
||||
|
@ -11,8 +11,6 @@ import { URL } from "url";
|
||||
|
||||
const reactProjectDirPath = process.cwd();
|
||||
|
||||
const doUseExternalAssets = process.argv[2]?.toLowerCase() === "--external-assets";
|
||||
|
||||
const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPath, "package.json"));
|
||||
|
||||
export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak");
|
||||
@ -26,8 +24,7 @@ if (require.main === module) {
|
||||
keycloakThemeBuildingDirPath,
|
||||
"reactAppBuildDirPath": pathJoin(reactProjectDirPath, "build"),
|
||||
"themeName": parsedPackageJson.name,
|
||||
...(() => {
|
||||
|
||||
"urlPathname": (() => {
|
||||
|
||||
const url = (() => {
|
||||
|
||||
@ -39,35 +36,12 @@ if (require.main === module) {
|
||||
|
||||
})();
|
||||
|
||||
const urlPathname =
|
||||
url === undefined ?
|
||||
"/" :
|
||||
url.pathname.replace(/([^/])$/, "$1/");
|
||||
return url === undefined ?
|
||||
"/" :
|
||||
url.pathname.replace(/([^/])$/, "$1/");
|
||||
|
||||
return !doUseExternalAssets ?
|
||||
{
|
||||
"mode": "standalone",
|
||||
urlPathname
|
||||
} as const
|
||||
:
|
||||
{
|
||||
"mode": "external assets",
|
||||
urlPathname,
|
||||
"urlOrigin": (() => {
|
||||
|
||||
if (url === undefined) {
|
||||
console.error("ERROR: You must specify 'homepage' in your package.json");
|
||||
process.exit(-1);
|
||||
}
|
||||
|
||||
return url.origin;
|
||||
|
||||
})()
|
||||
|
||||
} as const;
|
||||
|
||||
})()
|
||||
|
||||
});
|
||||
|
||||
const { jarFilePath } = generateJavaStackFiles({
|
||||
|
@ -5,27 +5,14 @@ export function replaceImportsFromStaticInJsCode(
|
||||
params: {
|
||||
ftlValuesGlobalName: string;
|
||||
jsCode: string;
|
||||
} & ({
|
||||
mode: "standalone";
|
||||
} | {
|
||||
mode: "external assets";
|
||||
urlOrigin: string;
|
||||
urlPathname: string;
|
||||
})
|
||||
}
|
||||
): { fixedJsCode: string; } {
|
||||
|
||||
const { jsCode, ftlValuesGlobalName } = params;
|
||||
|
||||
const fixedJsCode = jsCode.replace(
|
||||
/[a-z]+\.[a-z]+\+"static\//g,
|
||||
(() => {
|
||||
switch (params.mode) {
|
||||
case "standalone":
|
||||
return `window.${ftlValuesGlobalName}.url.resourcesPath + "/build/static/`;
|
||||
case "external assets":
|
||||
return `"${params.urlOrigin}${params.urlPathname}static/`;
|
||||
}
|
||||
})()
|
||||
`window.${ftlValuesGlobalName}.url.resourcesPath + "/build/static/`
|
||||
);
|
||||
|
||||
return { fixedJsCode };
|
||||
@ -36,12 +23,7 @@ export function replaceImportsInInlineCssCode(
|
||||
params: {
|
||||
cssCode: string;
|
||||
urlPathname: string;
|
||||
} & ({
|
||||
mode: "standalone";
|
||||
} | {
|
||||
mode: "external assets";
|
||||
urlOrigin: string;
|
||||
})
|
||||
}
|
||||
): { fixedCssCode: string; } {
|
||||
|
||||
const { cssCode, urlPathname } = params;
|
||||
@ -50,13 +32,7 @@ export function replaceImportsInInlineCssCode(
|
||||
urlPathname === "/" ?
|
||||
/url\(\/([^/][^)]+)\)/g :
|
||||
new RegExp(`url\\(${urlPathname}([^)]+)\\)`, "g"),
|
||||
(...[, group]) => `url(${(() => {
|
||||
switch (params.mode) {
|
||||
case "standalone": return "${url.resourcesPath}/build/" + group;
|
||||
case "external assets": return params.urlOrigin + urlPathname + group
|
||||
}
|
||||
})()
|
||||
})`
|
||||
(...[, group]) => `url(${"${url.resourcesPath}/build/" + group})`
|
||||
);
|
||||
|
||||
return { fixedCssCode };
|
||||
|
@ -25,7 +25,7 @@ export type TemplateProps = {
|
||||
showUsernameNode?: ReactNode;
|
||||
formNode: ReactNode;
|
||||
infoNode?: ReactNode;
|
||||
} & { kcContext: KcContext.Template; } & KcTemplateProps;
|
||||
} & { kcContext: KcContext; } & KcTemplateProps;
|
||||
|
||||
export const Template = memo((props: TemplateProps) => {
|
||||
|
||||
|
@ -10,12 +10,17 @@ import type { LanguageLabel } from "./i18n/KcLanguageTag";
|
||||
type ExtractAfterStartingWith<Prefix extends string, StrEnum> =
|
||||
StrEnum extends `${Prefix}${infer U}` ? U : never;
|
||||
|
||||
/** Take theses type definition with a grain of salt.
|
||||
* Some values might be undefined on some pages.
|
||||
* (ex: url.loginAction is undefined on error.ftl)
|
||||
*/
|
||||
export type KcContext =
|
||||
KcContext.Login | KcContext.Register | KcContext.Info |
|
||||
KcContext.Error | KcContext.LoginResetPassword | KcContext.LoginVerifyEmail;
|
||||
|
||||
export declare namespace KcContext {
|
||||
|
||||
export type Template = {
|
||||
export type Common = {
|
||||
url: {
|
||||
loginAction: string;
|
||||
resourcesPath: string;
|
||||
@ -27,7 +32,7 @@ export declare namespace KcContext {
|
||||
displayName?: string;
|
||||
displayNameHtml?: string;
|
||||
internationalizationEnabled: boolean;
|
||||
registrationEmailAsUsername: boolean; //<---
|
||||
registrationEmailAsUsername: boolean;
|
||||
};
|
||||
/** Undefined if !realm.internationalizationEnabled */
|
||||
locale?: {
|
||||
@ -55,7 +60,7 @@ export declare namespace KcContext {
|
||||
isAppInitiatedAction: boolean;
|
||||
};
|
||||
|
||||
export type Login = Template & {
|
||||
export type Login = Common & {
|
||||
pageId: "login.ftl";
|
||||
url: {
|
||||
loginResetCredentialsUrl: string;
|
||||
@ -88,7 +93,7 @@ export declare namespace KcContext {
|
||||
};
|
||||
};
|
||||
|
||||
export type Register = Template & {
|
||||
export type Register = Common & {
|
||||
pageId: "register.ftl";
|
||||
url: {
|
||||
registrationAction: string;
|
||||
@ -120,7 +125,7 @@ export declare namespace KcContext {
|
||||
recaptchaSiteKey?: string;
|
||||
};
|
||||
|
||||
export type Info = Template & {
|
||||
export type Info = Common & {
|
||||
pageId: "info.ftl";
|
||||
messageHeader?: string;
|
||||
requiredActions?: ExtractAfterStartingWith<"requiredAction.", MessageKey>[];
|
||||
@ -132,21 +137,21 @@ export declare namespace KcContext {
|
||||
}
|
||||
};
|
||||
|
||||
export type Error = Template & {
|
||||
export type Error = Common & {
|
||||
pageId: "error.ftl";
|
||||
client?: {
|
||||
baseUrl?: string;
|
||||
}
|
||||
};
|
||||
|
||||
export type LoginResetPassword = Template & {
|
||||
export type LoginResetPassword = Common & {
|
||||
pageId: "login-reset-password.ftl";
|
||||
realm: {
|
||||
loginWithEmailAllowed: boolean;
|
||||
}
|
||||
};
|
||||
|
||||
export type LoginVerifyEmail = Template & {
|
||||
export type LoginVerifyEmail = Common & {
|
||||
pageId: "login-verify-email.ftl";
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { getKcLanguageTagLabel } from "../i18n/KcLanguageTag";
|
||||
//NOTE: Aside because we want to be able to import them from node
|
||||
import { resourcesCommonPath, resourcesPath } from "./urlResourcesPath";
|
||||
|
||||
export const kcTemplateContext: KcContext.Template = {
|
||||
const kcCommonContext: KcContext.Common = {
|
||||
"url": {
|
||||
"loginAction": "#",
|
||||
"resourcesPath": `${process.env["PUBLIC_URL"]}/${resourcesPath}`,
|
||||
@ -111,7 +111,7 @@ export const kcTemplateContext: KcContext.Template = {
|
||||
};
|
||||
|
||||
Object.defineProperty(
|
||||
kcTemplateContext.locale!,
|
||||
kcCommonContext.locale!,
|
||||
"current",
|
||||
{
|
||||
"get": () => getKcLanguageTagLabel(getEvtKcLanguage().state),
|
||||
@ -120,22 +120,22 @@ Object.defineProperty(
|
||||
);
|
||||
|
||||
export const kcLoginContext: KcContext.Login = {
|
||||
...kcTemplateContext,
|
||||
...kcCommonContext,
|
||||
"pageId": "login.ftl",
|
||||
"url": {
|
||||
...kcTemplateContext.url,
|
||||
...kcCommonContext.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"
|
||||
},
|
||||
"realm": {
|
||||
...kcTemplateContext.realm,
|
||||
...kcCommonContext.realm,
|
||||
"loginWithEmailAllowed": true,
|
||||
"rememberMe": true,
|
||||
"password": true,
|
||||
"resetPasswordAllowed": true,
|
||||
"registrationAllowed": true
|
||||
},
|
||||
"auth": kcTemplateContext.auth!,
|
||||
"auth": kcCommonContext.auth!,
|
||||
"social": {
|
||||
"displayInfo": true
|
||||
},
|
||||
@ -147,7 +147,7 @@ export const kcLoginContext: KcContext.Login = {
|
||||
};
|
||||
|
||||
export const kcRegisterContext: KcContext.Register = {
|
||||
...kcTemplateContext,
|
||||
...kcCommonContext,
|
||||
"url": {
|
||||
...kcLoginContext.url,
|
||||
"registrationAction": "http://localhost:8080/auth/realms/myrealm/login-actions/registration?session_code=gwZdUeO7pbYpFTRxiIxRg_QtzMbtFTKrNu6XW_f8asM&execution=12146ce0-b139-4bbd-b25b-0eccfee6577e&client_id=account&tab_id=uS8lYfebLa0"
|
||||
@ -166,7 +166,7 @@ export const kcRegisterContext: KcContext.Register = {
|
||||
};
|
||||
|
||||
export const kcInfoContext: KcContext.Info ={
|
||||
...kcTemplateContext,
|
||||
...kcCommonContext,
|
||||
"pageId": "info.ftl",
|
||||
"messageHeader": "<Message header>",
|
||||
"requiredActions": undefined,
|
||||
@ -178,7 +178,7 @@ export const kcInfoContext: KcContext.Info ={
|
||||
};
|
||||
|
||||
export const kcErrorContext: KcContext.Error = {
|
||||
...kcTemplateContext,
|
||||
...kcCommonContext,
|
||||
"pageId": "error.ftl",
|
||||
"client": {
|
||||
"baseUrl": "#"
|
||||
@ -186,16 +186,16 @@ export const kcErrorContext: KcContext.Error = {
|
||||
};
|
||||
|
||||
export const kcLoginResetPasswordContext: KcContext.LoginResetPassword = {
|
||||
...kcTemplateContext,
|
||||
...kcCommonContext,
|
||||
"pageId": "login-reset-password.ftl",
|
||||
"realm":{
|
||||
...kcTemplateContext.realm,
|
||||
...kcCommonContext.realm,
|
||||
"loginWithEmailAllowed": false
|
||||
}
|
||||
};
|
||||
|
||||
export const kcLoginVerifyEmailContext: KcContext.LoginVerifyEmail = {
|
||||
...kcTemplateContext,
|
||||
...kcCommonContext,
|
||||
"pageId": "login-verify-email.ftl"
|
||||
};
|
||||
|
||||
|
@ -66,13 +66,12 @@ export function createKeycloakAdapter(
|
||||
|
||||
return {
|
||||
"login": options => {
|
||||
window.location.replace(
|
||||
window.location.href=
|
||||
transformUrlBeforeRedirect(
|
||||
keycloakInstance.createLoginUrl(
|
||||
options
|
||||
)
|
||||
)
|
||||
);
|
||||
);
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"logout": options => {
|
||||
@ -86,13 +85,13 @@ export function createKeycloakAdapter(
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"register": options => {
|
||||
window.location.replace(
|
||||
window.location.href =
|
||||
transformUrlBeforeRedirect(
|
||||
keycloakInstance.createRegisterUrl(
|
||||
options
|
||||
)
|
||||
)
|
||||
);
|
||||
);
|
||||
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"accountManagement": () => {
|
||||
|
@ -12,7 +12,6 @@ generateKeycloakThemeResources({
|
||||
"themeName": "keycloakify-demo-app",
|
||||
"reactAppBuildDirPath": pathJoin(sampleReactProjectDirPath, "build"),
|
||||
"keycloakThemeBuildingDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak_theme"),
|
||||
"mode": "standalone",
|
||||
"urlPathname": "/keycloakify-demo-app/"
|
||||
});
|
||||
|
||||
|
@ -19,8 +19,7 @@ const { fixedJsCode } = replaceImportsFromStaticInJsCode({
|
||||
3: "0664cdc0"
|
||||
}[e] + ".chunk.js"
|
||||
}
|
||||
`,
|
||||
"mode": "standalone"
|
||||
`
|
||||
});
|
||||
|
||||
console.log({ fixedJsCode });
|
||||
|
Reference in New Issue
Block a user