keycloakify 9.0.0-rc.0 → 9.0.0-rc.1

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 (88) hide show
  1. package/README.md +7 -4
  2. package/account/Template.js +1 -1
  3. package/account/Template.js.map +1 -1
  4. package/account/TemplateProps.d.ts +1 -1
  5. package/account/kcContext/KcContext.d.ts +1 -0
  6. package/account/kcContext/KcContext.js.map +1 -1
  7. package/account/kcContext/kcContextMocks.js +1 -0
  8. package/account/kcContext/kcContextMocks.js.map +1 -1
  9. package/account/lib/useGetClassName.js +1 -0
  10. package/account/lib/useGetClassName.js.map +1 -1
  11. package/account/pages/Account.js +1 -1
  12. package/account/pages/Account.js.map +1 -1
  13. package/bin/getSrcDirPath.js +30 -17
  14. package/bin/getSrcDirPath.js.map +1 -1
  15. package/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl +6 -0
  16. package/bin/keycloakify/generateFtl/generateFtl.js +22 -0
  17. package/bin/keycloakify/generateFtl/generateFtl.js.map +1 -1
  18. package/bin/keycloakify/generateFtl/pageId.d.ts +1 -1
  19. package/bin/keycloakify/generateFtl/pageId.js +2 -0
  20. package/bin/keycloakify/generateFtl/pageId.js.map +1 -1
  21. package/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/resources/account/AccountFormService.java +2 -12
  22. package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js +1 -1
  23. package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js.map +1 -1
  24. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js +1 -1
  25. package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js.map +1 -1
  26. package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.d.ts +0 -1
  27. package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js +22 -13
  28. package/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.js.map +1 -1
  29. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.d.ts +0 -2
  30. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js +37 -51
  31. package/bin/keycloakify/generateTheme/readStaticResourcesUsage.js.map +1 -1
  32. package/bin/keycloakify/keycloakify.js +1 -1
  33. package/bin/keycloakify/keycloakify.js.map +1 -1
  34. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js +7 -3
  35. package/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.js.map +1 -1
  36. package/lib/usePrepareTemplate.js +7 -8
  37. package/lib/usePrepareTemplate.js.map +1 -1
  38. package/login/Fallback.js +6 -0
  39. package/login/Fallback.js.map +1 -1
  40. package/login/Template.js +1 -1
  41. package/login/Template.js.map +1 -1
  42. package/login/TemplateProps.d.ts +1 -1
  43. package/login/kcContext/KcContext.d.ts +21 -1
  44. package/login/kcContext/KcContext.js.map +1 -1
  45. package/login/kcContext/kcContextMocks.d.ts +1 -1
  46. package/login/kcContext/kcContextMocks.js +12 -1
  47. package/login/kcContext/kcContextMocks.js.map +1 -1
  48. package/login/lib/useGetClassName.js +2 -0
  49. package/login/lib/useGetClassName.js.map +1 -1
  50. package/login/pages/Info.js +1 -1
  51. package/login/pages/Info.js.map +1 -1
  52. package/login/pages/LoginConfigTotp.js +1 -1
  53. package/login/pages/LoginConfigTotp.js.map +1 -1
  54. package/login/pages/LoginDeviceVerifyUserCode.d.ts +7 -0
  55. package/login/pages/LoginDeviceVerifyUserCode.js +15 -0
  56. package/login/pages/LoginDeviceVerifyUserCode.js.map +1 -0
  57. package/login/pages/LoginOauthGrant.d.ts +7 -0
  58. package/login/pages/LoginOauthGrant.js +15 -0
  59. package/login/pages/LoginOauthGrant.js.map +1 -0
  60. package/package.json +11 -1
  61. package/src/account/Template.tsx +1 -1
  62. package/src/account/TemplateProps.ts +1 -1
  63. package/src/account/kcContext/KcContext.ts +1 -0
  64. package/src/account/kcContext/kcContextMocks.ts +1 -0
  65. package/src/account/lib/useGetClassName.ts +1 -0
  66. package/src/account/pages/Account.tsx +4 -4
  67. package/src/bin/getSrcDirPath.ts +8 -8
  68. package/src/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl +6 -0
  69. package/src/bin/keycloakify/generateFtl/generateFtl.ts +21 -0
  70. package/src/bin/keycloakify/generateFtl/pageId.ts +2 -0
  71. package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/resources/account/AccountFormService.java +2 -12
  72. package/src/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.ts +1 -1
  73. package/src/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.ts +1 -1
  74. package/src/bin/keycloakify/generateTheme/downloadKeycloakStaticResources.ts +29 -15
  75. package/src/bin/keycloakify/generateTheme/readStaticResourcesUsage.ts +21 -28
  76. package/src/bin/keycloakify/keycloakify.ts +1 -2
  77. package/src/bin/keycloakify/replacers/replaceImportsFromStaticInJsCode.ts +14 -7
  78. package/src/lib/usePrepareTemplate.ts +7 -10
  79. package/src/login/Fallback.tsx +6 -0
  80. package/src/login/Template.tsx +1 -1
  81. package/src/login/TemplateProps.ts +3 -1
  82. package/src/login/kcContext/KcContext.ts +24 -0
  83. package/src/login/kcContext/kcContextMocks.ts +23 -1
  84. package/src/login/lib/useGetClassName.ts +2 -0
  85. package/src/login/pages/Info.tsx +4 -1
  86. package/src/login/pages/LoginConfigTotp.tsx +1 -1
  87. package/src/login/pages/LoginDeviceVerifyUserCode.tsx +68 -0
  88. package/src/login/pages/LoginOauthGrant.tsx +73 -0
@@ -12,6 +12,8 @@ const Error = lazy(() => import("keycloakify/login/pages/Error"));
12
12
  const LoginResetPassword = lazy(() => import("keycloakify/login/pages/LoginResetPassword"));
13
13
  const LoginVerifyEmail = lazy(() => import("keycloakify/login/pages/LoginVerifyEmail"));
14
14
  const Terms = lazy(() => import("keycloakify/login/pages/Terms"));
15
+ const LoginDeviceVerifyUserCode = lazy(() => import("keycloakify/login/pages/LoginDeviceVerifyUserCode"));
16
+ const LoginOauthGrant = lazy(() => import("keycloakify/login/pages/LoginOauthGrant"));
15
17
  const LoginOtp = lazy(() => import("keycloakify/login/pages/LoginOtp"));
16
18
  const LoginPassword = lazy(() => import("keycloakify/login/pages/LoginPassword"));
17
19
  const LoginUsername = lazy(() => import("keycloakify/login/pages/LoginUsername"));
@@ -52,6 +54,10 @@ export default function Fallback(props: PageProps<KcContext, I18n>) {
52
54
  return <LoginVerifyEmail kcContext={kcContext} {...rest} />;
53
55
  case "terms.ftl":
54
56
  return <Terms kcContext={kcContext} {...rest} />;
57
+ case "login-oauth2-device-verify-user-code.ftl":
58
+ return <LoginDeviceVerifyUserCode kcContext={kcContext} {...rest} />;
59
+ case "login-oauth-grant.ftl":
60
+ return <LoginOauthGrant kcContext={kcContext} {...rest} />;
55
61
  case "login-otp.ftl":
56
62
  return <LoginOtp kcContext={kcContext} {...rest} />;
57
63
  case "login-username.ftl":
@@ -38,7 +38,7 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
38
38
  `${url.resourcesPath}/css/login.css`
39
39
  ],
40
40
  "htmlClassName": getClassName("kcHtmlClass"),
41
- "bodyClassName": undefined
41
+ "bodyClassName": getClassName("kcBodyClass")
42
42
  });
43
43
 
44
44
  if (!isReady) {
@@ -21,6 +21,7 @@ export type TemplateProps<KcContext extends KcContext.Common, I18nExtended exten
21
21
  };
22
22
 
23
23
  export type ClassKey =
24
+ | "kcBodyClass"
24
25
  | "kcHtmlClass"
25
26
  | "kcLoginClass"
26
27
  | "kcHeaderClass"
@@ -93,4 +94,5 @@ export type ClassKey =
93
94
  | "kcSelectOTPListItemClass"
94
95
  | "kcAuthenticatorOtpCircleClass"
95
96
  | "kcSelectOTPItemHeadingClass"
96
- | "kcFormOptionsWrapperClass";
97
+ | "kcFormOptionsWrapperClass"
98
+ | "kcFormButtonsWrapperClass";
@@ -19,6 +19,8 @@ export type KcContext =
19
19
  | KcContext.LoginResetPassword
20
20
  | KcContext.LoginVerifyEmail
21
21
  | KcContext.Terms
22
+ | KcContext.LoginDeviceVerifyUserCode
23
+ | KcContext.LoginOauthGrant
22
24
  | KcContext.LoginOtp
23
25
  | KcContext.LoginUsername
24
26
  | KcContext.WebauthnAuthenticate
@@ -38,6 +40,7 @@ export type KcContext =
38
40
 
39
41
  export declare namespace KcContext {
40
42
  export type Common = {
43
+ themeVersion: string;
41
44
  keycloakifyVersion: string;
42
45
  themeType: "login";
43
46
  themeName: string;
@@ -242,6 +245,27 @@ export declare namespace KcContext {
242
245
  pageId: "terms.ftl";
243
246
  };
244
247
 
248
+ export type LoginDeviceVerifyUserCode = Common & {
249
+ pageId: "login-oauth2-device-verify-user-code.ftl";
250
+ url: {
251
+ oauth2DeviceVerificationAction: string;
252
+ };
253
+ };
254
+
255
+ export type LoginOauthGrant = Common & {
256
+ pageId: "login-oauth-grant.ftl";
257
+ oauth: {
258
+ code: string;
259
+ client: string;
260
+ clientScopesRequested: {
261
+ consentScreenText: string;
262
+ }[];
263
+ };
264
+ url: {
265
+ oauthAction: string;
266
+ };
267
+ };
268
+
245
269
  export type LoginOtp = Common & {
246
270
  pageId: "login-otp.ftl";
247
271
  otpLogin: {
@@ -105,6 +105,7 @@ const PUBLIC_URL = (typeof process !== "object" ? undefined : process.env?.["PUB
105
105
  const resourcesPath = pathJoin(PUBLIC_URL, keycloak_resources, "login", "resources");
106
106
 
107
107
  export const kcContextCommonMock: KcContext.Common = {
108
+ "themeVersion": "0.0.0",
108
109
  "keycloakifyVersion": "0.0.0",
109
110
  "themeType": "login",
110
111
  "themeName": "my-theme-name",
@@ -242,7 +243,9 @@ export const kcContextCommonMock: KcContext.Common = {
242
243
  const loginUrl = {
243
244
  ...kcContextCommonMock.url,
244
245
  "loginResetCredentialsUrl": "/auth/realms/myrealm/login-actions/reset-credentials?client_id=account&tab_id=HoAx28ja4xg",
245
- "registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg"
246
+ "registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg",
247
+ "oauth2DeviceVerificationAction": "/auth/realms/myrealm/device",
248
+ "oauthAction": "/auth/realms/myrealm/login-actions/consent?client_id=account&tab_id=HoAx28ja4xg"
246
249
  };
247
250
 
248
251
  export const kcContextMocks = [
@@ -346,6 +349,25 @@ export const kcContextMocks = [
346
349
  ...kcContextCommonMock,
347
350
  "pageId": "terms.ftl"
348
351
  }),
352
+ id<KcContext.LoginDeviceVerifyUserCode>({
353
+ ...kcContextCommonMock,
354
+ "pageId": "login-oauth2-device-verify-user-code.ftl",
355
+ url: loginUrl
356
+ }),
357
+ id<KcContext.LoginOauthGrant>({
358
+ ...kcContextCommonMock,
359
+ "pageId": "login-oauth-grant.ftl",
360
+ oauth: {
361
+ code: "5-1N4CIzfi1aprIQjmylI-9e3spLCWW9i5d-GDcs-Sw",
362
+ clientScopesRequested: [
363
+ { consentScreenText: "${profileScopeConsentText}" },
364
+ { consentScreenText: "${rolesScopeConsentText}" },
365
+ { consentScreenText: "${emailScopeConsentText}" }
366
+ ],
367
+ client: "account"
368
+ },
369
+ url: loginUrl
370
+ }),
349
371
  id<KcContext.LoginOtp>({
350
372
  ...kcContextCommonMock,
351
373
  "pageId": "login-otp.ftl",
@@ -3,6 +3,7 @@ import type { ClassKey } from "keycloakify/login/TemplateProps";
3
3
 
4
4
  export const { useGetClassName } = createUseClassName<ClassKey>({
5
5
  "defaultClasses": {
6
+ "kcBodyClass": undefined,
6
7
  "kcHtmlClass": "login-pf",
7
8
  "kcLoginClass": "login-pf-page",
8
9
  "kcContentWrapperClass": "row",
@@ -44,6 +45,7 @@ export const { useGetClassName } = createUseClassName<ClassKey>({
44
45
  "kcInputClass": "form-control",
45
46
  "kcInputErrorMessageClass": "pf-c-form__helper-text pf-m-error required kc-feedback-text",
46
47
  "kcInputWrapperClass": "col-xs-12 col-sm-12 col-md-12 col-lg-12",
48
+ "kcFormButtonsWrapperClass": undefined,
47
49
  "kcFormOptionsClass": "col-xs-12 col-sm-12 col-md-12 col-lg-12",
48
50
  "kcFormButtonsClass": "col-xs-12 col-sm-12 col-md-12 col-lg-12",
49
51
  "kcFormSettingClass": "login-pf-settings",
@@ -8,7 +8,10 @@ export default function Info(props: PageProps<Extract<KcContext, { pageId: "info
8
8
 
9
9
  const { msgStr, msg } = i18n;
10
10
 
11
- assert(kcContext.message !== undefined);
11
+ assert(
12
+ kcContext.message !== undefined,
13
+ "No message in kcContext.message, there will always be a message in production context, add it in your mock"
14
+ );
12
15
 
13
16
  const { messageHeader, message, requiredActions, skipLink, pageRedirectUri, actionUri, client } = kcContext;
14
17
 
@@ -32,7 +32,7 @@ export default function LoginConfigTotp(props: PageProps<Extract<KcContext, { pa
32
32
 
33
33
  <ul id="kc-totp-supported-apps">
34
34
  {totp.supportedApplications.map(app => (
35
- <li>{msgStr(app as MessageKey, app)}</li>
35
+ <li>{msg(app as MessageKey)}</li>
36
36
  ))}
37
37
  </ul>
38
38
  </li>
@@ -0,0 +1,68 @@
1
+ import { clsx } from "keycloakify/tools/clsx";
2
+ import Template from "../Template";
3
+ import { I18n } from "../i18n";
4
+ import { KcContext } from "../kcContext";
5
+ import { useGetClassName } from "../lib/useGetClassName";
6
+ import { PageProps } from "./PageProps";
7
+
8
+ export default function LoginOauthGrant(props: PageProps<Extract<KcContext, { pageId: "login-oauth2-device-verify-user-code.ftl" }>, I18n>) {
9
+ const { kcContext, i18n, doUseDefaultCss, classes } = props;
10
+ const { url } = kcContext;
11
+
12
+ const { msg, msgStr } = i18n;
13
+
14
+ const { getClassName } = useGetClassName({
15
+ doUseDefaultCss,
16
+ classes
17
+ });
18
+
19
+ return (
20
+ <Template {...{ kcContext, i18n, doUseDefaultCss, classes }} headerNode={msg("oauth2DeviceVerificationTitle")}>
21
+ <form
22
+ id="kc-user-verify-device-user-code-form"
23
+ className={getClassName("kcFormClass")}
24
+ action={url.oauth2DeviceVerificationAction}
25
+ method="post"
26
+ >
27
+ <div className={getClassName("kcFormGroupClass")}>
28
+ <div className={getClassName("kcLabelWrapperClass")}>
29
+ <label htmlFor="device-user-code" className={getClassName("kcLabelClass")}>
30
+ {msg("verifyOAuth2DeviceUserCode")}
31
+ </label>
32
+ </div>
33
+
34
+ <div className={getClassName("kcInputWrapperClass")}>
35
+ <input
36
+ id="device-user-code"
37
+ name="device_user_code"
38
+ autoComplete="off"
39
+ type="text"
40
+ className={getClassName("kcInputClass")}
41
+ autoFocus
42
+ />
43
+ </div>
44
+ </div>
45
+
46
+ <div className={getClassName("kcFormGroupClass")}>
47
+ <div id="kc-form-options" className={getClassName("kcFormOptionsClass")}>
48
+ <div className={getClassName("kcFormOptionsWrapperClass")}></div>
49
+ </div>
50
+
51
+ <div id="kc-form-buttons" className={getClassName("kcFormButtonsClass")}>
52
+ <div className={getClassName("kcFormButtonsWrapperClass")}>
53
+ <input
54
+ className={clsx(
55
+ getClassName("kcButtonClass"),
56
+ getClassName("kcButtonPrimaryClass"),
57
+ getClassName("kcButtonLargeClass")
58
+ )}
59
+ type="submit"
60
+ value={msgStr("doSubmit")}
61
+ />
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </form>
66
+ </Template>
67
+ );
68
+ }
@@ -0,0 +1,73 @@
1
+ import { clsx } from "keycloakify/tools/clsx";
2
+ import { PageProps } from "./PageProps";
3
+ import { KcContext } from "../kcContext";
4
+ import { I18n } from "../i18n";
5
+ import Template from "../Template";
6
+ import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
7
+
8
+ export default function LoginOauthGrant(props: PageProps<Extract<KcContext, { pageId: "login-oauth-grant.ftl" }>, I18n>) {
9
+ const { kcContext, i18n, doUseDefaultCss, classes } = props;
10
+ const { url, oauth, client } = kcContext;
11
+
12
+ const { msg, msgStr, advancedMsg, advancedMsgStr } = i18n;
13
+
14
+ const { getClassName } = useGetClassName({
15
+ doUseDefaultCss,
16
+ classes
17
+ });
18
+
19
+ return (
20
+ <Template
21
+ {...{ kcContext, i18n, doUseDefaultCss, classes }}
22
+ headerNode={msg("oauthGrantTitle", client.name ? advancedMsgStr(client.name) : client.clientId)}
23
+ >
24
+ <div id="kc-oauth" className="content-area">
25
+ <h3>{msg("oauthGrantRequest")}</h3>
26
+ <ul>
27
+ {oauth.clientScopesRequested.map(clientScope => (
28
+ <li key={clientScope.consentScreenText}>
29
+ <span>{advancedMsg(clientScope.consentScreenText)}</span>
30
+ </li>
31
+ ))}
32
+ </ul>
33
+
34
+ <form className="form-actions" action={url.oauthAction} method="POST">
35
+ <input type="hidden" name="code" value={oauth.code} />
36
+ <div className={getClassName("kcFormGroupClass")}>
37
+ <div id="kc-form-options">
38
+ <div className={getClassName("kcFormOptionsWrapperClass")}></div>
39
+ </div>
40
+
41
+ <div id="kc-form-buttons">
42
+ <div className={getClassName("kcFormButtonsWrapperClass")}>
43
+ <input
44
+ className={clsx(
45
+ getClassName("kcButtonClass"),
46
+ getClassName("kcButtonPrimaryClass"),
47
+ getClassName("kcButtonLargeClass")
48
+ )}
49
+ name="accept"
50
+ id="kc-login"
51
+ type="submit"
52
+ value={msgStr("doYes")}
53
+ />
54
+ <input
55
+ className={clsx(
56
+ getClassName("kcButtonClass"),
57
+ getClassName("kcButtonDefaultClass"),
58
+ getClassName("kcButtonLargeClass")
59
+ )}
60
+ name="cancel"
61
+ id="kc-cancel"
62
+ type="submit"
63
+ value={msgStr("doNo")}
64
+ />
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </form>
69
+ <div className="clearfix"></div>
70
+ </div>
71
+ </Template>
72
+ );
73
+ }