keycloakify 10.0.0-rc.77 → 10.0.0-rc.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/account/i18n/i18n.d.ts +4 -4
- package/account/i18n/i18n.js +12 -34
- package/account/i18n/i18n.js.map +1 -1
- package/account/i18n/index.d.ts +1 -1
- package/account/i18n/index.js +1 -1
- package/account/i18n/index.js.map +1 -1
- package/account/i18n/useI18n.d.ts +13 -0
- package/account/i18n/useI18n.js +26 -0
- package/account/i18n/useI18n.js.map +1 -0
- package/bin/440.index.js +15 -19
- package/bin/751.index.js +0 -2
- package/bin/shared/constants.d.ts +0 -1
- package/bin/shared/constants.js +0 -1
- package/bin/shared/constants.js.map +1 -1
- package/login/KcContext/KcContext.d.ts +5 -1
- package/login/KcContext/KcContext.js +0 -1
- package/login/KcContext/KcContext.js.map +1 -1
- package/login/KcContext/kcContextMocks.js +4 -1
- package/login/KcContext/kcContextMocks.js.map +1 -1
- package/login/i18n/i18n.d.ts +7 -4
- package/login/i18n/i18n.js +23 -38
- package/login/i18n/i18n.js.map +1 -1
- package/login/i18n/index.d.ts +1 -1
- package/login/i18n/index.js +1 -1
- package/login/i18n/index.js.map +1 -1
- package/login/i18n/useI18n.d.ts +13 -0
- package/login/i18n/useI18n.js +26 -0
- package/login/i18n/useI18n.js.map +1 -0
- package/login/lib/useDownloadTerms.d.ts +5 -4
- package/login/lib/useDownloadTerms.js +26 -5
- package/login/lib/useDownloadTerms.js.map +1 -1
- package/login/pages/Register.js +7 -6
- package/login/pages/Register.js.map +1 -1
- package/login/pages/Terms.d.ts +1 -1
- package/login/pages/Terms.js +6 -4
- package/login/pages/Terms.js.map +1 -1
- package/package.json +15 -7
- package/src/account/i18n/i18n.tsx +19 -53
- package/src/account/i18n/index.ts +1 -1
- package/src/account/i18n/useI18n.ts +44 -0
- package/src/bin/keycloakify/generateFtl/generateFtl.ts +1 -6
- package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +8 -1
- package/src/bin/keycloakify/generateResources/generateMessageProperties.ts +23 -17
- package/src/bin/shared/constants.ts +0 -2
- package/src/login/KcContext/KcContext.ts +6 -14
- package/src/login/KcContext/kcContextMocks.ts +4 -1
- package/src/login/i18n/i18n.tsx +37 -58
- package/src/login/i18n/index.ts +1 -1
- package/src/login/i18n/useI18n.ts +44 -0
- package/src/login/lib/useDownloadTerms.tsx +88 -0
- package/src/login/pages/Register.tsx +12 -12
- package/src/login/pages/Terms.tsx +12 -11
- package/src/tools/react-markdown.ts +3 -0
- package/tools/react-markdown.d.ts +3 -0
- package/tools/react-markdown.js +4 -0
- package/tools/react-markdown.js.map +1 -0
- package/vite-plugin/index.js +0 -2
- package/src/login/lib/useDownloadTerms.ts +0 -57
- package/src/tools/Markdown.ts +0 -3
- package/tools/Markdown.d.ts +0 -2
- package/tools/Markdown.js +0 -3
- package/tools/Markdown.js.map +0 -1
@@ -0,0 +1,44 @@
|
|
1
|
+
import { useEffect, useState } from "react";
|
2
|
+
import {
|
3
|
+
createGetI18n,
|
4
|
+
type GenericI18n,
|
5
|
+
type MessageKey,
|
6
|
+
type KcContextLike
|
7
|
+
} from "./i18n";
|
8
|
+
import { Reflect } from "tsafe/Reflect";
|
9
|
+
|
10
|
+
export function createUseI18n<ExtraMessageKey extends string = never>(extraMessages: {
|
11
|
+
[languageTag: string]: { [key in ExtraMessageKey]: string };
|
12
|
+
}) {
|
13
|
+
type I18n = GenericI18n<MessageKey | ExtraMessageKey>;
|
14
|
+
|
15
|
+
const { getI18n } = createGetI18n(extraMessages);
|
16
|
+
|
17
|
+
function useI18n(params: { kcContext: KcContextLike }): { i18n: I18n } {
|
18
|
+
const { kcContext } = params;
|
19
|
+
|
20
|
+
const { i18n, prI18n_currentLanguage } = getI18n({ kcContext });
|
21
|
+
|
22
|
+
const [i18n_toReturn, setI18n_toReturn] = useState<I18n>(i18n);
|
23
|
+
|
24
|
+
useEffect(() => {
|
25
|
+
let isActive = true;
|
26
|
+
|
27
|
+
prI18n_currentLanguage?.then(i18n => {
|
28
|
+
if (!isActive) {
|
29
|
+
return;
|
30
|
+
}
|
31
|
+
|
32
|
+
setI18n_toReturn(i18n);
|
33
|
+
});
|
34
|
+
|
35
|
+
return () => {
|
36
|
+
isActive = false;
|
37
|
+
};
|
38
|
+
}, []);
|
39
|
+
|
40
|
+
return { i18n: i18n_toReturn };
|
41
|
+
}
|
42
|
+
|
43
|
+
return { useI18n, ofTypeI18n: Reflect<I18n>() };
|
44
|
+
}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import { useState, useEffect } from "react";
|
2
|
+
import { fallbackLanguageTag } from "keycloakify/login/i18n";
|
3
|
+
import { assert } from "tsafe/assert";
|
4
|
+
import { createStatefulObservable, useRerenderOnChange } from "keycloakify/tools/StatefulObservable";
|
5
|
+
import { useOnFistMount } from "keycloakify/tools/useOnFirstMount";
|
6
|
+
import { KcContext } from "../KcContext";
|
7
|
+
import type { Options as ReactMarkdownOptions } from "../../tools/react-markdown";
|
8
|
+
|
9
|
+
const obs = createStatefulObservable<
|
10
|
+
| {
|
11
|
+
ReactMarkdown: (props: Readonly<ReactMarkdownOptions>) => JSX.Element;
|
12
|
+
termsMarkdown: string;
|
13
|
+
}
|
14
|
+
| undefined
|
15
|
+
>(() => undefined);
|
16
|
+
|
17
|
+
export type KcContextLike_useDownloadTerms = {
|
18
|
+
pageId: string;
|
19
|
+
locale?: {
|
20
|
+
currentLanguageTag: string;
|
21
|
+
};
|
22
|
+
termsAcceptanceRequired?: boolean;
|
23
|
+
};
|
24
|
+
|
25
|
+
assert<KcContext extends KcContextLike_useDownloadTerms ? true : false>();
|
26
|
+
|
27
|
+
/** Allow to avoid bundling the terms and download it on demand*/
|
28
|
+
export function useDownloadTerms(params: {
|
29
|
+
kcContext: KcContextLike_useDownloadTerms;
|
30
|
+
downloadTermsMarkdown: (params: { currentLanguageTag: string }) => Promise<{ termsMarkdown: string; termsLanguageTag: string | undefined }>;
|
31
|
+
}) {
|
32
|
+
const { kcContext, downloadTermsMarkdown } = params;
|
33
|
+
|
34
|
+
useOnFistMount(async () => {
|
35
|
+
if (kcContext.pageId === "terms.ftl" || kcContext.termsAcceptanceRequired) {
|
36
|
+
const currentLanguageTag = kcContext.locale?.currentLanguageTag ?? fallbackLanguageTag;
|
37
|
+
|
38
|
+
const [ReactMarkdown_base, { termsMarkdown, termsLanguageTag }] = await Promise.all([
|
39
|
+
import("../../tools/react-markdown").then(_ => _.default),
|
40
|
+
downloadTermsMarkdown({ currentLanguageTag })
|
41
|
+
] as const);
|
42
|
+
|
43
|
+
const htmlLang = termsLanguageTag !== currentLanguageTag ? termsLanguageTag : undefined;
|
44
|
+
|
45
|
+
const ReactMarkdown: (props: Readonly<ReactMarkdownOptions>) => JSX.Element =
|
46
|
+
htmlLang === undefined
|
47
|
+
? ReactMarkdown_base
|
48
|
+
: props => {
|
49
|
+
const [anchor, setAnchor] = useState<HTMLDivElement | null>(null);
|
50
|
+
|
51
|
+
useEffect(() => {
|
52
|
+
if (anchor === null) {
|
53
|
+
return;
|
54
|
+
}
|
55
|
+
|
56
|
+
const parent = anchor.parentElement;
|
57
|
+
|
58
|
+
assert(parent !== null);
|
59
|
+
|
60
|
+
parent.setAttribute("lang", htmlLang);
|
61
|
+
|
62
|
+
anchor.remove();
|
63
|
+
}, [anchor]);
|
64
|
+
|
65
|
+
return (
|
66
|
+
<>
|
67
|
+
<ReactMarkdown_base {...props} />
|
68
|
+
<div ref={setAnchor} style={{ display: "none" }} aria-hidden />
|
69
|
+
</>
|
70
|
+
);
|
71
|
+
};
|
72
|
+
|
73
|
+
obs.current = { ReactMarkdown, termsMarkdown };
|
74
|
+
}
|
75
|
+
});
|
76
|
+
}
|
77
|
+
|
78
|
+
export function useTermsMarkdown() {
|
79
|
+
useRerenderOnChange(obs);
|
80
|
+
|
81
|
+
if (obs.current === undefined) {
|
82
|
+
return { isDownloadComplete: false as const };
|
83
|
+
}
|
84
|
+
|
85
|
+
const { ReactMarkdown, termsMarkdown } = obs.current;
|
86
|
+
|
87
|
+
return { isDownloadComplete: true, ReactMarkdown, termsMarkdown };
|
88
|
+
}
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { useState } from "react";
|
2
|
-
import { Markdown } from "keycloakify/tools/Markdown";
|
3
2
|
import type { LazyOrNot } from "keycloakify/tools/LazyOrNot";
|
4
3
|
import { useTermsMarkdown } from "keycloakify/login/lib/useDownloadTerms";
|
5
4
|
import { getKcClsx, type KcClsx } from "keycloakify/login/lib/kcClsx";
|
@@ -78,23 +77,14 @@ export default function Register(props: RegisterProps) {
|
|
78
77
|
function TermsAcceptance(props: { i18n: I18n; kcClsx: KcClsx; messagesPerField: Pick<KcContext["messagesPerField"], "existsError" | "get"> }) {
|
79
78
|
const { i18n, kcClsx, messagesPerField } = props;
|
80
79
|
|
81
|
-
const { msg } = i18n;
|
82
|
-
|
83
|
-
// NOTE: Refer to https://docs.keycloakify.dev/terms-and-conditions to load your terms and conditions.
|
84
|
-
const { termsMarkdown } = useTermsMarkdown();
|
85
|
-
|
86
|
-
if (termsMarkdown === undefined) {
|
87
|
-
return null;
|
88
|
-
}
|
80
|
+
const { msg, msgStr } = i18n;
|
89
81
|
|
90
82
|
return (
|
91
83
|
<>
|
92
84
|
<div className="form-group">
|
93
85
|
<div className={kcClsx("kcInputWrapperClass")}>
|
94
86
|
{msg("termsTitle")}
|
95
|
-
<div id="kc-registration-terms-text">
|
96
|
-
<Markdown>{termsMarkdown}</Markdown>
|
97
|
-
</div>
|
87
|
+
<div id="kc-registration-terms-text">{msgStr("termsText") ? msg("termsText") : <TermsMarkdown />}</div>
|
98
88
|
</div>
|
99
89
|
</div>
|
100
90
|
<div className="form-group">
|
@@ -121,3 +111,13 @@ function TermsAcceptance(props: { i18n: I18n; kcClsx: KcClsx; messagesPerField:
|
|
121
111
|
</>
|
122
112
|
);
|
123
113
|
}
|
114
|
+
|
115
|
+
function TermsMarkdown() {
|
116
|
+
const { isDownloadComplete, termsMarkdown, ReactMarkdown } = useTermsMarkdown();
|
117
|
+
|
118
|
+
if (!isDownloadComplete) {
|
119
|
+
return null;
|
120
|
+
}
|
121
|
+
|
122
|
+
return <ReactMarkdown>{termsMarkdown}</ReactMarkdown>;
|
123
|
+
}
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { Markdown } from "keycloakify/tools/Markdown";
|
2
1
|
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
|
3
2
|
import { useTermsMarkdown } from "keycloakify/login/lib/useDownloadTerms";
|
4
3
|
import type { PageProps } from "keycloakify/login/pages/PageProps";
|
@@ -15,13 +14,7 @@ export default function Terms(props: PageProps<Extract<KcContext, { pageId: "ter
|
|
15
14
|
|
16
15
|
const { msg, msgStr } = i18n;
|
17
16
|
|
18
|
-
const {
|
19
|
-
|
20
|
-
const { isDownloadComplete, termsMarkdown, termsLanguageTag } = useTermsMarkdown();
|
21
|
-
|
22
|
-
if (!isDownloadComplete) {
|
23
|
-
return null;
|
24
|
-
}
|
17
|
+
const { url } = kcContext;
|
25
18
|
|
26
19
|
return (
|
27
20
|
<Template
|
@@ -32,9 +25,7 @@ export default function Terms(props: PageProps<Extract<KcContext, { pageId: "ter
|
|
32
25
|
displayMessage={false}
|
33
26
|
headerNode={msg("termsTitle")}
|
34
27
|
>
|
35
|
-
<div id="kc-terms-text"
|
36
|
-
<Markdown>{termsMarkdown}</Markdown>
|
37
|
-
</div>
|
28
|
+
<div id="kc-terms-text">{msgStr("termsText") ? msg("termsText") : <TermsMarkdown />}</div>
|
38
29
|
<form className="form-actions" action={url.loginAction} method="POST">
|
39
30
|
<input
|
40
31
|
className={kcClsx("kcButtonClass", "kcButtonClass", "kcButtonClass", "kcButtonPrimaryClass", "kcButtonLargeClass")}
|
@@ -55,3 +46,13 @@ export default function Terms(props: PageProps<Extract<KcContext, { pageId: "ter
|
|
55
46
|
</Template>
|
56
47
|
);
|
57
48
|
}
|
49
|
+
|
50
|
+
function TermsMarkdown() {
|
51
|
+
const { isDownloadComplete, termsMarkdown, ReactMarkdown } = useTermsMarkdown();
|
52
|
+
|
53
|
+
if (!isDownloadComplete) {
|
54
|
+
return null;
|
55
|
+
}
|
56
|
+
|
57
|
+
return <ReactMarkdown>{termsMarkdown}</ReactMarkdown>;
|
58
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"react-markdown.js","sourceRoot":"","sources":["../src/tools/react-markdown.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,eAAe,QAAQ,CAAC"}
|
package/vite-plugin/index.js
CHANGED
@@ -4569,12 +4569,10 @@ __nccwpck_require__.r(__webpack_exports__);
|
|
4569
4569
|
/* harmony export */ "keycloak_resources": () => (/* binding */ keycloak_resources),
|
4570
4570
|
/* harmony export */ "lastKeycloakVersionWithAccountV1": () => (/* binding */ lastKeycloakVersionWithAccountV1),
|
4571
4571
|
/* harmony export */ "loginThemePageIds": () => (/* binding */ loginThemePageIds),
|
4572
|
-
/* harmony export */ "nameOfTheLocalizationRealmOverridesUserProfileProperty": () => (/* binding */ nameOfTheLocalizationRealmOverridesUserProfileProperty),
|
4573
4572
|
/* harmony export */ "resources_common": () => (/* binding */ resources_common),
|
4574
4573
|
/* harmony export */ "themeTypes": () => (/* binding */ themeTypes),
|
4575
4574
|
/* harmony export */ "vitePluginSubScriptEnvNames": () => (/* binding */ vitePluginSubScriptEnvNames)
|
4576
4575
|
/* harmony export */ });
|
4577
|
-
const nameOfTheLocalizationRealmOverridesUserProfileProperty = "__localizationRealmOverridesUserProfile";
|
4578
4576
|
const keycloak_resources = "keycloak-resources";
|
4579
4577
|
const resources_common = "resources-common";
|
4580
4578
|
const lastKeycloakVersionWithAccountV1 = "21.1.2";
|
@@ -1,57 +0,0 @@
|
|
1
|
-
import { fallbackLanguageTag } from "keycloakify/login/i18n";
|
2
|
-
import { assert } from "tsafe/assert";
|
3
|
-
import {
|
4
|
-
createStatefulObservable,
|
5
|
-
useRerenderOnChange
|
6
|
-
} from "keycloakify/tools/StatefulObservable";
|
7
|
-
import { useOnFistMount } from "keycloakify/tools/useOnFirstMount";
|
8
|
-
import { KcContext } from "../KcContext";
|
9
|
-
|
10
|
-
const obs = createStatefulObservable<
|
11
|
-
| {
|
12
|
-
termsMarkdown: string;
|
13
|
-
termsLanguageTag: string | undefined;
|
14
|
-
}
|
15
|
-
| undefined
|
16
|
-
>(() => undefined);
|
17
|
-
|
18
|
-
export type KcContextLike = {
|
19
|
-
pageId: string;
|
20
|
-
locale?: {
|
21
|
-
currentLanguageTag: string;
|
22
|
-
};
|
23
|
-
termsAcceptanceRequired?: boolean;
|
24
|
-
};
|
25
|
-
|
26
|
-
assert<KcContext extends KcContextLike ? true : false>();
|
27
|
-
|
28
|
-
/** Allow to avoid bundling the terms and download it on demand*/
|
29
|
-
export function useDownloadTerms(params: {
|
30
|
-
kcContext: KcContextLike;
|
31
|
-
downloadTermsMarkdown: (params: {
|
32
|
-
currentLanguageTag: string;
|
33
|
-
}) => Promise<{ termsMarkdown: string; termsLanguageTag: string | undefined }>;
|
34
|
-
}) {
|
35
|
-
const { kcContext, downloadTermsMarkdown } = params;
|
36
|
-
|
37
|
-
useOnFistMount(async () => {
|
38
|
-
if (kcContext.pageId === "terms.ftl" || kcContext.termsAcceptanceRequired) {
|
39
|
-
obs.current = await downloadTermsMarkdown({
|
40
|
-
currentLanguageTag:
|
41
|
-
kcContext.locale?.currentLanguageTag ?? fallbackLanguageTag
|
42
|
-
});
|
43
|
-
}
|
44
|
-
});
|
45
|
-
}
|
46
|
-
|
47
|
-
export function useTermsMarkdown() {
|
48
|
-
useRerenderOnChange(obs);
|
49
|
-
|
50
|
-
if (obs.current === undefined) {
|
51
|
-
return { isDownloadComplete: false as const };
|
52
|
-
}
|
53
|
-
|
54
|
-
const { termsMarkdown, termsLanguageTag } = obs.current;
|
55
|
-
|
56
|
-
return { isDownloadComplete: true, termsMarkdown, termsLanguageTag };
|
57
|
-
}
|
package/src/tools/Markdown.ts
DELETED
package/tools/Markdown.d.ts
DELETED
package/tools/Markdown.js
DELETED
package/tools/Markdown.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../src/tools/Markdown.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|