Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
6e666b6ee2 | |||
4c66c9877a | |||
e8fce5f796 | |||
481131d58b | |||
0a4e71e149 | |||
96f5139421 | |||
1a326bf7e4 | |||
e1afc1cf7a | |||
bb007ddce5 | |||
b5dd0317c7 | |||
3c54541a73 | |||
2657f01135 | |||
7223409eb1 | |||
c41eae63e7 | |||
c8b85c43aa | |||
e918788c3f | |||
b53f4f997c | |||
481d93ebc4 |
2
.github/workflows/ci.yaml
vendored
2
.github/workflows/ci.yaml
vendored
@ -3,7 +3,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v*
|
||||
- v8
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
@ -47,12 +47,12 @@
|
||||
|
||||
> 📣 🛑 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 👼
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "keycloakify",
|
||||
"version": "8.3.0",
|
||||
"version": "8.4.3",
|
||||
"description": "Create Keycloak themes using React",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -408,6 +408,14 @@
|
||||
out["themeName"] = "KEYCLOAKIFY_THEME_NAME_cXxKd3xEer";
|
||||
out["pageId"] = "${pageId}";
|
||||
|
||||
try {
|
||||
|
||||
out["url"]["resourcesCommonPath"] = out["url"]["resourcesPath"] + "/" + "RESOURCES_COMMON_cLsLsMrtDkpVv";
|
||||
|
||||
} catch(error) {
|
||||
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
})()
|
||||
@ -423,7 +431,7 @@
|
||||
<#if isHash>
|
||||
|
||||
<#if path?size gt 10>
|
||||
<#return "ABORT: Too many recursive calls">
|
||||
<#return "ABORT: Too many recursive calls, path: " + path?join(".")>
|
||||
</#if>
|
||||
|
||||
<#local keys = "">
|
||||
@ -455,9 +463,10 @@
|
||||
<#-- https://github.com/keycloakify/keycloakify/issues/91#issue-1212319466 (reports with error.ftl and Kc18) -->
|
||||
<#-- https://github.com/keycloakify/keycloakify/issues/109#issuecomment-1134610163 -->
|
||||
<#-- https://github.com/keycloakify/keycloakify/issues/357 -->
|
||||
<#-- https://github.com/keycloakify/keycloakify/discussions/406#discussioncomment-7514787 -->
|
||||
key == "loginAction" &&
|
||||
are_same_path(path, ["url"]) &&
|
||||
["saml-post-form.ftl", "error.ftl", "info.ftl", "login-oauth-grant.ftl", "logout-confirm.ftl"]?seq_contains(pageId) &&
|
||||
["saml-post-form.ftl", "error.ftl", "info.ftl", "login-oauth-grant.ftl", "logout-confirm.ftl", "login-oauth2-device-verify-user-code.ftl"]?seq_contains(pageId) &&
|
||||
!(auth?has_content && auth.showTryAnotherWayLink())
|
||||
) || (
|
||||
<#-- https://github.com/keycloakify/keycloakify/issues/362 -->
|
||||
@ -480,24 +489,33 @@
|
||||
!["name", "displayName", "displayNameHtml", "internationalizationEnabled", "registrationEmailAsUsername" ]?seq_contains(key)
|
||||
) || (
|
||||
"applications.ftl" == pageId &&
|
||||
are_same_path(path, ["applications", "applications", "*", "client", "realm"])
|
||||
is_subpath(path, ["applications", "applications"]) &&
|
||||
(
|
||||
key == "realm" ||
|
||||
key == "container"
|
||||
)
|
||||
) || (
|
||||
"applications.ftl" == pageId &&
|
||||
"masterAdminClient" == key
|
||||
are_same_path(path, ["user"]) &&
|
||||
key == "delegateForUpdate"
|
||||
)
|
||||
>
|
||||
<#local out_seq += ["/*If you need '" + key + "' on " + pageId + ", please submit an issue to the Keycloakify repo*/"]>
|
||||
<#local out_seq += ["/*If you need '" + path?join(".") + "." + key + "' on " + pageId + ", please submit an issue to the Keycloakify repo*/"]>
|
||||
<#continue>
|
||||
</#if>
|
||||
|
||||
<#if pageId == "register.ftl" && key == "attemptedUsername" && are_same_path(path, ["auth"])>
|
||||
<#-- https://github.com/keycloakify/keycloakify/discussions/406 -->
|
||||
<#if (
|
||||
["register.ftl", "info.ftl", "login.ftl", "login-update-password.ftl", "login-oauth2-device-verify-user-code.ftl"]?seq_contains(pageId) &&
|
||||
key == "attemptedUsername" && are_same_path(path, ["auth"])
|
||||
)>
|
||||
<#attempt>
|
||||
<#-- https://github.com/keycloak/keycloak/blob/3a2bf0c04bcde185e497aaa32d0bb7ab7520cf4a/themes/src/main/resources/theme/base/login/template.ftl#L63 -->
|
||||
<#-- https://github.com/keycloakify/keycloakify/discussions/406 -->
|
||||
<#if !(auth?has_content && auth.showUsername() && !auth.showResetCredentials())>
|
||||
<#local out_seq += ["/*If you need '" + key + "' on " + pageId + ", please submit an issue to the Keycloakify repo*/"]>
|
||||
<#continue>
|
||||
</#if>
|
||||
<#recover>
|
||||
<#local out_seq += ["/*Testing if attemptedUsername should be skipped throwed an exception */"]>
|
||||
</#attempt>
|
||||
</#if>
|
||||
|
||||
@ -650,9 +668,9 @@
|
||||
<#return "ABORT: Couldn't convert into string non hash, non method, non boolean, non enumerable object">
|
||||
|
||||
</#function>
|
||||
<#function are_same_path path searchedPath>
|
||||
<#function is_subpath path searchedPath>
|
||||
|
||||
<#if path?size != searchedPath?size>
|
||||
<#if path?size < searchedPath?size>
|
||||
<#return false>
|
||||
</#if>
|
||||
|
||||
@ -660,8 +678,14 @@
|
||||
|
||||
<#list path as property>
|
||||
|
||||
<#if i == searchedPath?size >
|
||||
<#continue>
|
||||
</#if>
|
||||
|
||||
<#local searchedProperty=searchedPath[i]>
|
||||
|
||||
<#local i+= 1>
|
||||
|
||||
<#if searchedProperty?is_string && searchedProperty == "*">
|
||||
<#continue>
|
||||
</#if>
|
||||
@ -678,11 +702,13 @@
|
||||
<#return false>
|
||||
</#if>
|
||||
|
||||
<#local i+= 1>
|
||||
|
||||
</#list>
|
||||
|
||||
<#return true>
|
||||
|
||||
</#function>
|
||||
|
||||
<#function are_same_path path searchedPath>
|
||||
<#return path?size == searchedPath?size && is_subpath(path, searchedPath)>
|
||||
</#function>
|
||||
</script>
|
@ -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 }): {
|
||||
|
@ -39,6 +39,7 @@ export type KcContext =
|
||||
|
||||
export declare namespace KcContext {
|
||||
export type Common = {
|
||||
themeVersion: string;
|
||||
keycloakifyVersion: string;
|
||||
themeType: "login";
|
||||
themeName: string;
|
||||
|
@ -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",
|
||||
|
@ -8,7 +8,10 @@ export default function Info(props: PageProps<Extract<KcContext, { pageId: "info
|
||||
|
||||
const { msgStr, msg } = i18n;
|
||||
|
||||
assert(kcContext.message !== undefined);
|
||||
assert(
|
||||
kcContext.message !== undefined,
|
||||
"No message in kcContext.message, there will always be a message in production context, add it in your mock"
|
||||
);
|
||||
|
||||
const { messageHeader, message, requiredActions, skipLink, pageRedirectUri, actionUri, client } = kcContext;
|
||||
|
||||
|
@ -21,4 +21,13 @@ const meta: ComponentMeta<any> = {
|
||||
|
||||
export default meta;
|
||||
|
||||
export const Default = () => <PageStory />;
|
||||
export const Default = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
message: {
|
||||
summary: "This is the server message",
|
||||
type: "info"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
Reference in New Issue
Block a user