keycloakify 10.0.0-rc.106 → 10.0.0-rc.108

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.
Files changed (34) hide show
  1. package/bin/622.index.js +15 -14
  2. package/bin/shared/downloadKeycloakDefaultTheme.js.map +1 -1
  3. package/login/KcContext/KcContext.d.ts +7 -9
  4. package/login/KcContext/KcContext.js.map +1 -1
  5. package/login/KcContext/kcContextMocks.js +1 -2
  6. package/login/KcContext/kcContextMocks.js.map +1 -1
  7. package/login/i18n/i18n.d.ts +3 -4
  8. package/login/i18n/i18n.js +15 -12
  9. package/login/i18n/i18n.js.map +1 -1
  10. package/login/i18n/useI18n.d.ts +2 -2
  11. package/login/pages/Info.js +2 -2
  12. package/login/pages/Info.js.map +1 -1
  13. package/login/pages/SelectAuthenticator.js +2 -2
  14. package/login/pages/SelectAuthenticator.js.map +1 -1
  15. package/login/pages/WebauthnAuthenticate.js +3 -3
  16. package/login/pages/WebauthnAuthenticate.js.map +1 -1
  17. package/package.json +1 -5
  18. package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +84 -29
  19. package/src/bin/shared/downloadKeycloakDefaultTheme.ts +44 -24
  20. package/src/login/KcContext/KcContext.ts +7 -26
  21. package/src/login/KcContext/kcContextMocks.ts +1 -2
  22. package/src/login/i18n/i18n.tsx +19 -17
  23. package/src/login/pages/Info.tsx +2 -2
  24. package/src/login/pages/SelectAuthenticator.tsx +4 -4
  25. package/src/login/pages/WebauthnAuthenticate.tsx +5 -5
  26. package/stories/login/pages/Info.stories.tsx +7 -2
  27. package/stories/login/pages/Register.stories.tsx +5 -3
  28. package/stories/login/pages/SelectAuthenticator.stories.tsx +26 -0
  29. package/stories/login/pages/Terms.stories.tsx +6 -2
  30. package/vite-plugin/index.js +15 -14
  31. package/src/tools/ExtractAfterStartingWith.ts +0 -4
  32. package/tools/ExtractAfterStartingWith.d.ts +0 -1
  33. package/tools/ExtractAfterStartingWith.js +0 -2
  34. package/tools/ExtractAfterStartingWith.js.map +0 -1
@@ -162,8 +162,7 @@ export const kcContextCommonMock: KcContext.Common = {
162
162
  isAppInitiatedAction: false,
163
163
  properties: {},
164
164
  "x-keycloakify": {
165
- realmMessageBundleUserProfile: undefined,
166
- realmMessageBundleTermsText: undefined
165
+ messages: {}
167
166
  }
168
167
  };
169
168
 
@@ -11,8 +11,7 @@ export type KcContextLike = {
11
11
  supported: { languageTag: string; url: string; label: string }[];
12
12
  };
13
13
  "x-keycloakify": {
14
- realmMessageBundleUserProfile: Record<string, string> | undefined;
15
- realmMessageBundleTermsText: string | undefined;
14
+ messages: Record<string, string>;
16
15
  };
17
16
  };
18
17
 
@@ -131,8 +130,7 @@ export function createGetI18n<ExtraMessageKey extends string = never>(messageBun
131
130
  messages_fallbackLanguage,
132
131
  messageBundle_fallbackLanguage: messageBundle[fallbackLanguageTag],
133
132
  messageBundle_currentLanguage: messageBundle[partialI18n.currentLanguageTag],
134
- realmMessageBundleUserProfile: kcContext["x-keycloakify"].realmMessageBundleUserProfile,
135
- realmMessageBundleTermsText: kcContext["x-keycloakify"].realmMessageBundleTermsText
133
+ messageBundle_realm: kcContext["x-keycloakify"].messages
136
134
  });
137
135
 
138
136
  const isCurrentLanguageFallbackLanguage = partialI18n.currentLanguageTag === fallbackLanguageTag;
@@ -179,10 +177,9 @@ function createI18nTranslationFunctionsFactory<MessageKey extends string, ExtraM
179
177
  messages_fallbackLanguage: Record<MessageKey, string>;
180
178
  messageBundle_fallbackLanguage: Record<ExtraMessageKey, string> | undefined;
181
179
  messageBundle_currentLanguage: Partial<Record<ExtraMessageKey, string>> | undefined;
182
- realmMessageBundleUserProfile: Record<string, string> | undefined;
183
- realmMessageBundleTermsText: string | undefined;
180
+ messageBundle_realm: Record<string, string>;
184
181
  }) {
185
- const { messageBundle_currentLanguage, realmMessageBundleUserProfile, realmMessageBundleTermsText } = params;
182
+ const { messageBundle_currentLanguage, messageBundle_realm } = params;
186
183
 
187
184
  const messages_fallbackLanguage = {
188
185
  ...params.messages_fallbackLanguage,
@@ -201,12 +198,21 @@ function createI18nTranslationFunctionsFactory<MessageKey extends string, ExtraM
201
198
  const { key, args, doRenderAsHtml } = props;
202
199
 
203
200
  const messageOrUndefined: string | undefined = (() => {
204
- const messageOrUndefined = (messages_currentLanguage as any)[key] ?? (messages_fallbackLanguage as any)[key];
201
+ terms_text: {
202
+ if (key !== "termsText") {
203
+ break terms_text;
204
+ }
205
+ const termsTextMessage = messageBundle_realm[key];
206
+
207
+ if (termsTextMessage === undefined) {
208
+ break terms_text;
209
+ }
205
210
 
206
- if (key === "termsText" && realmMessageBundleTermsText !== undefined) {
207
- return realmMessageBundleTermsText;
211
+ return termsTextMessage;
208
212
  }
209
213
 
214
+ const messageOrUndefined = (messages_currentLanguage as any)[key] ?? (messages_fallbackLanguage as any)[key];
215
+
210
216
  return messageOrUndefined;
211
217
  })();
212
218
 
@@ -259,15 +265,11 @@ function createI18nTranslationFunctionsFactory<MessageKey extends string, ExtraM
259
265
  function resolveMsgAdvanced(props: { key: string; args: (string | undefined)[]; doRenderAsHtml: boolean }): JSX.Element | string {
260
266
  const { key, args, doRenderAsHtml } = props;
261
267
 
262
- user_profile: {
263
- if (realmMessageBundleUserProfile === undefined) {
264
- break user_profile;
265
- }
266
-
267
- const resolvedMessage = realmMessageBundleUserProfile[key] ?? realmMessageBundleUserProfile["${" + key + "}"];
268
+ realm_messages: {
269
+ const resolvedMessage = messageBundle_realm[key] ?? messageBundle_realm["${" + key + "}"];
268
270
 
269
271
  if (resolvedMessage === undefined) {
270
- break user_profile;
272
+ break realm_messages;
271
273
  }
272
274
 
273
275
  return doRenderAsHtml ? (
@@ -5,7 +5,7 @@ import type { I18n } from "../i18n";
5
5
  export default function Info(props: PageProps<Extract<KcContext, { pageId: "info.ftl" }>, I18n>) {
6
6
  const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
7
7
 
8
- const { msgStr, msg } = i18n;
8
+ const { advancedMsgStr, msg } = i18n;
9
9
 
10
10
  const { messageHeader, message, requiredActions, skipLink, pageRedirectUri, actionUri, client } = kcContext;
11
11
 
@@ -34,7 +34,7 @@ export default function Info(props: PageProps<Extract<KcContext, { pageId: "info
34
34
  if (requiredActions) {
35
35
  html += "<b>";
36
36
 
37
- html += requiredActions.map(requiredAction => msgStr(`requiredAction.${requiredAction}` as const)).join(",");
37
+ html += requiredActions.map(requiredAction => advancedMsgStr(`requiredAction.${requiredAction}`)).join(",");
38
38
 
39
39
  html += "</b>";
40
40
  }
@@ -8,7 +8,7 @@ export default function SelectAuthenticator(props: PageProps<Extract<KcContext,
8
8
  const { url, auth } = kcContext;
9
9
 
10
10
  const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
11
- const { msg } = i18n;
11
+ const { msg, advancedMsg } = i18n;
12
12
 
13
13
  return (
14
14
  <Template
@@ -30,11 +30,11 @@ export default function SelectAuthenticator(props: PageProps<Extract<KcContext,
30
30
  value={authenticationSelection.authExecId}
31
31
  >
32
32
  <div className={kcClsx("kcSelectAuthListItemIconClass")}>
33
- <i className={kcClsx(authenticationSelection.iconCssClass, "kcSelectAuthListItemIconPropertyClass")} />
33
+ <i className={kcClsx("kcSelectAuthListItemIconPropertyClass", authenticationSelection.iconCssClass)} />
34
34
  </div>
35
35
  <div className={kcClsx("kcSelectAuthListItemBodyClass")}>
36
- <div className={kcClsx("kcSelectAuthListItemHeadingClass")}>{msg(authenticationSelection.displayName)}</div>
37
- <div className={kcClsx("kcSelectAuthListItemDescriptionClass")}>{msg(authenticationSelection.helpText)}</div>
36
+ <div className={kcClsx("kcSelectAuthListItemHeadingClass")}>{advancedMsg(authenticationSelection.displayName)}</div>
37
+ <div className={kcClsx("kcSelectAuthListItemDescriptionClass")}>{advancedMsg(authenticationSelection.helpText)}</div>
38
38
  </div>
39
39
  <div className={kcClsx("kcSelectAuthListItemFillClass")} />
40
40
  <div className={kcClsx("kcSelectAuthListItemArrowClass")}>
@@ -204,13 +204,13 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
204
204
  className={kcClsx("kcSelectAuthListItemDescriptionClass")}
205
205
  >
206
206
  {authenticator.transports.displayNameProperties
207
- .map((nameProperty, i, arr) => ({
208
- nameProperty,
207
+ .map((displayNameProperty, i, arr) => ({
208
+ displayNameProperty,
209
209
  hasNext: i !== arr.length - 1
210
210
  }))
211
- .map(({ nameProperty, hasNext }) => (
212
- <Fragment key={nameProperty}>
213
- <span>{msg(nameProperty)}</span>
211
+ .map(({ displayNameProperty, hasNext }) => (
212
+ <Fragment key={displayNameProperty}>
213
+ {advancedMsg(displayNameProperty)}
214
214
  {hasNext && <span>, </span>}
215
215
  </Fragment>
216
216
  ))}
@@ -43,9 +43,14 @@ export const WithRequiredActions: Story = {
43
43
  <KcPageStory
44
44
  kcContext={{
45
45
  message: {
46
- summary: "Server message"
46
+ summary: "Required actions: "
47
47
  },
48
- requiredActions: ["CONFIGURE_TOTP", "UPDATE_PROFILE", "VERIFY_EMAIL"]
48
+ requiredActions: ["CONFIGURE_TOTP", "UPDATE_PROFILE", "VERIFY_EMAIL", "CUSTOM_ACTION"],
49
+ "x-keycloakify": {
50
+ messages: {
51
+ "requiredAction.CUSTOM_ACTION": "Custom action"
52
+ }
53
+ }
49
54
  }}
50
55
  />
51
56
  )
@@ -69,7 +69,7 @@ export const WithRestrictedToMITStudents: Story = {
69
69
  }
70
70
  },
71
71
  "x-keycloakify": {
72
- realmMessageBundleUserProfile: {
72
+ messages: {
73
73
  "${profile.attributes.email.inputHelperTextBefore}": "Please use your MIT or Berkeley email.",
74
74
  "${profile.attributes.email.pattern.error}":
75
75
  "This is not an MIT (<strong>@mit.edu</strong>) nor a Berkeley (<strong>@berkeley.edu</strong>) email."
@@ -103,7 +103,7 @@ export const WithFavoritePet: Story = {
103
103
  }
104
104
  },
105
105
  "x-keycloakify": {
106
- realmMessageBundleUserProfile: {
106
+ messages: {
107
107
  "${profile.attributes.favoritePet}": "Favorite Pet",
108
108
  "${profile.attributes.favoritePet.options.cat}": "Fluffy Cat",
109
109
  "${profile.attributes.favoritePet.options.dog}": "Loyal Dog",
@@ -177,7 +177,9 @@ export const WithTermsAcceptance: Story = {
177
177
  kcContext={{
178
178
  termsAcceptanceRequired: true,
179
179
  "x-keycloakify": {
180
- realmMessageBundleTermsText: "<a href='https://example.com/terms'>Service Terms of Use</a>"
180
+ messages: {
181
+ termsText: "<a href='https://example.com/terms'>Service Terms of Use</a>"
182
+ }
181
183
  }
182
184
  }}
183
185
  />
@@ -41,3 +41,29 @@ export const WithDifferentAuthenticationMethods: Story = {
41
41
  />
42
42
  )
43
43
  };
44
+
45
+ export const WithRealmTranslations: Story = {
46
+ render: () => (
47
+ <KcPageStory
48
+ kcContext={{
49
+ auth: {
50
+ authenticationSelections: [
51
+ {
52
+ authExecId: "f0c22855-eda7-4092-8565-0c22f77d2ffb",
53
+ displayName: "home-idp-discovery-display-name",
54
+ helpText: "home-idp-discovery-help-text",
55
+ iconCssClass: "kcAuthenticatorDefaultClass"
56
+ }
57
+ ]
58
+ },
59
+ ["x-keycloakify"]: {
60
+ messages: {
61
+ "${home-idp-discovery-display-name}": "Home identity provider",
62
+ "${home-idp-discovery-help-text}":
63
+ "Sign in via your home identity provider which will be automatically determined based on your provided email address."
64
+ }
65
+ }
66
+ }}
67
+ />
68
+ )
69
+ };
@@ -18,7 +18,9 @@ export const Default: Story = {
18
18
  <KcPageStory
19
19
  kcContext={{
20
20
  "x-keycloakify": {
21
- realmMessageBundleTermsText: "<p>My terms in <strong>English</strong></p>"
21
+ messages: {
22
+ termsText: "<p>My terms in <strong>English</strong></p>"
23
+ }
22
24
  }
23
25
  }}
24
26
  />
@@ -34,7 +36,9 @@ export const French: Story = {
34
36
  },
35
37
  "x-keycloakify": {
36
38
  // cSpell: disable
37
- realmMessageBundleTermsText: "<p>Mes terme en <strong>Français</strong></p>"
39
+ messages: {
40
+ termsText: "<p>Mes terme en <strong>Français</strong></p>"
41
+ }
38
42
  // cSpell: enable
39
43
  }
40
44
  }}
@@ -5135,11 +5135,12 @@ async function downloadKeycloakDefaultTheme(params) {
5135
5135
  return;
5136
5136
  }
5137
5137
  skip_node_modules: {
5138
- if (!fileRelativePath.startsWith((0,external_path_.join)("keycloak", "common", "resources", "node_modules"))) {
5138
+ const nodeModulesRelativeDirPath = (0,external_path_.join)("keycloak", "common", "resources", "node_modules");
5139
+ if (!fileRelativePath.startsWith(nodeModulesRelativeDirPath)) {
5139
5140
  break skip_node_modules;
5140
5141
  }
5141
5142
  if (kcNodeModulesKeepFilePaths_lastAccountV1 === undefined) {
5142
- kcNodeModulesKeepFilePaths_lastAccountV1 = [
5143
+ kcNodeModulesKeepFilePaths_lastAccountV1 = new Set([
5143
5144
  (0,external_path_.join)("patternfly", "dist", "css", "patternfly.min.css"),
5144
5145
  (0,external_path_.join)("patternfly", "dist", "css", "patternfly-additions.min.css"),
5145
5146
  (0,external_path_.join)("patternfly", "dist", "fonts", "OpenSans-Regular-webfont.woff2"),
@@ -5148,12 +5149,11 @@ async function downloadKeycloakDefaultTheme(params) {
5148
5149
  (0,external_path_.join)("patternfly", "dist", "fonts", "OpenSans-Semibold-webfont.woff2"),
5149
5150
  (0,external_path_.join)("patternfly", "dist", "fonts", "PatternFlyIcons-webfont.ttf"),
5150
5151
  (0,external_path_.join)("patternfly", "dist", "fonts", "PatternFlyIcons-webfont.woff")
5151
- ];
5152
+ ]);
5152
5153
  }
5153
- for (const keepPath of kcNodeModulesKeepFilePaths_lastAccountV1) {
5154
- if (fileRelativePath.endsWith(keepPath)) {
5155
- break skip_node_modules;
5156
- }
5154
+ const fileRelativeToNodeModulesPath = fileRelativePath.substring(nodeModulesRelativeDirPath.length + 1);
5155
+ if (kcNodeModulesKeepFilePaths_lastAccountV1.has(fileRelativeToNodeModulesPath)) {
5156
+ break skip_node_modules;
5157
5157
  }
5158
5158
  return;
5159
5159
  }
@@ -5176,11 +5176,12 @@ async function downloadKeycloakDefaultTheme(params) {
5176
5176
  break skip_unused_resources;
5177
5177
  }
5178
5178
  skip_node_modules: {
5179
- if (!fileRelativePath.startsWith((0,external_path_.join)("keycloak", "common", "resources", "node_modules"))) {
5179
+ const nodeModulesRelativeDirPath = (0,external_path_.join)("keycloak", "common", "resources", "node_modules");
5180
+ if (!fileRelativePath.startsWith(nodeModulesRelativeDirPath)) {
5180
5181
  break skip_node_modules;
5181
5182
  }
5182
5183
  if (kcNodeModulesKeepFilePaths === undefined) {
5183
- kcNodeModulesKeepFilePaths = [
5184
+ kcNodeModulesKeepFilePaths = new Set([
5184
5185
  (0,external_path_.join)("@patternfly", "patternfly", "patternfly.min.css"),
5185
5186
  (0,external_path_.join)("patternfly", "dist", "css", "patternfly.min.css"),
5186
5187
  (0,external_path_.join)("patternfly", "dist", "css", "patternfly-additions.min.css"),
@@ -5192,14 +5193,14 @@ async function downloadKeycloakDefaultTheme(params) {
5192
5193
  (0,external_path_.join)("patternfly", "dist", "fonts", "fontawesome-webfont.woff2"),
5193
5194
  (0,external_path_.join)("patternfly", "dist", "fonts", "PatternFlyIcons-webfont.ttf"),
5194
5195
  (0,external_path_.join)("patternfly", "dist", "fonts", "PatternFlyIcons-webfont.woff"),
5196
+ (0,external_path_.join)("patternfly", "dist", "fonts", "OpenSans-Semibold-webfont.woff2"),
5195
5197
  (0,external_path_.join)("patternfly", "dist", "img", "bg-login.jpg"),
5196
5198
  (0,external_path_.join)("jquery", "dist", "jquery.min.js")
5197
- ];
5199
+ ]);
5198
5200
  }
5199
- for (const keepPath of kcNodeModulesKeepFilePaths) {
5200
- if (fileRelativePath.endsWith(keepPath)) {
5201
- break skip_node_modules;
5202
- }
5201
+ const fileRelativeToNodeModulesPath = fileRelativePath.substring(nodeModulesRelativeDirPath.length + 1);
5202
+ if (kcNodeModulesKeepFilePaths.has(fileRelativeToNodeModulesPath)) {
5203
+ break skip_node_modules;
5203
5204
  }
5204
5205
  return;
5205
5206
  }
@@ -1,4 +0,0 @@
1
- export type ExtractAfterStartingWith<
2
- Prefix extends string,
3
- StrEnum
4
- > = StrEnum extends `${Prefix}${infer U}` ? U : never;
@@ -1 +0,0 @@
1
- export type ExtractAfterStartingWith<Prefix extends string, StrEnum> = StrEnum extends `${Prefix}${infer U}` ? U : never;
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=ExtractAfterStartingWith.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ExtractAfterStartingWith.js","sourceRoot":"","sources":["../src/tools/ExtractAfterStartingWith.ts"],"names":[],"mappings":""}