@oussemasahbeni/keycloakify-login-shadcn 250004.0.3 → 250004.0.8

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 (187) hide show
  1. package/keycloak-theme/components/langauges.tsx +1 -1
  2. package/keycloak-theme/components/theme-toggle.tsx +0 -1
  3. package/keycloak-theme/components/ui/alert.tsx +1 -2
  4. package/keycloak-theme/components/ui/button.tsx +1 -2
  5. package/keycloak-theme/components/ui/card.tsx +0 -1
  6. package/keycloak-theme/components/ui/checkbox.tsx +0 -1
  7. package/keycloak-theme/components/ui/dropdown-menu.tsx +14 -4
  8. package/keycloak-theme/components/ui/field.tsx +0 -1
  9. package/keycloak-theme/components/ui/input-otp.tsx +0 -1
  10. package/keycloak-theme/components/ui/input.tsx +0 -1
  11. package/keycloak-theme/components/ui/label.tsx +1 -2
  12. package/keycloak-theme/components/ui/radio-group.tsx +0 -1
  13. package/keycloak-theme/components/ui/select.tsx +12 -4
  14. package/keycloak-theme/components/ui/separator.tsx +0 -1
  15. package/keycloak-theme/components/ui/tooltip.tsx +0 -1
  16. package/keycloak-theme/login/KcContext.ts +23 -23
  17. package/keycloak-theme/login/KcPage.tsx +45 -47
  18. package/keycloak-theme/login/assets/img/auth-logo.svg +100 -100
  19. package/keycloak-theme/login/assets/img/shape.svg +71 -71
  20. package/keycloak-theme/login/components/LogoutOtherSessions.tsx +24 -26
  21. package/keycloak-theme/login/components/PasswordWrapper.tsx +35 -35
  22. package/keycloak-theme/login/components/Template/Template.tsx +279 -227
  23. package/keycloak-theme/login/components/Template/index.ts +1 -1
  24. package/keycloak-theme/login/components/Template/useInitializeTemplate.ts +61 -61
  25. package/keycloak-theme/login/components/UserProfileFormFields/AddRemoveButtonsMultiValuedAttribute.tsx +65 -61
  26. package/keycloak-theme/login/components/UserProfileFormFields/DO_MAKE_USER_CONFIRM_PASSWORD.ts +2 -2
  27. package/keycloak-theme/login/components/UserProfileFormFields/FieldErrors.tsx +33 -29
  28. package/keycloak-theme/login/components/UserProfileFormFields/GroupLabel.tsx +90 -71
  29. package/keycloak-theme/login/components/UserProfileFormFields/InputFieldByType.tsx +66 -59
  30. package/keycloak-theme/login/components/UserProfileFormFields/InputLabel.tsx +0 -1
  31. package/keycloak-theme/login/components/UserProfileFormFields/InputTag.tsx +133 -116
  32. package/keycloak-theme/login/components/UserProfileFormFields/InputTagSelects.tsx +150 -136
  33. package/keycloak-theme/login/components/UserProfileFormFields/SelectTag.tsx +135 -114
  34. package/keycloak-theme/login/components/UserProfileFormFields/TextareaTag.tsx +55 -43
  35. package/keycloak-theme/login/components/UserProfileFormFields/UserProfileFormFields.tsx +133 -127
  36. package/keycloak-theme/login/components/UserProfileFormFields/index.ts +1 -1
  37. package/keycloak-theme/login/i18n.ts +47 -47
  38. package/keycloak-theme/login/mocks/KcPageStory.tsx +6 -2
  39. package/keycloak-theme/login/mocks/getKcContextMock.ts +22 -22
  40. package/keycloak-theme/login/pages/PageIndex.tsx +130 -134
  41. package/keycloak-theme/login/pages/code/Page.stories.tsx +57 -70
  42. package/keycloak-theme/login/pages/code/Page.tsx +89 -89
  43. package/keycloak-theme/login/pages/code/index.ts +3 -3
  44. package/keycloak-theme/login/pages/delete-account-confirm/Page.stories.tsx +37 -46
  45. package/keycloak-theme/login/pages/delete-account-confirm/Page.tsx +60 -63
  46. package/keycloak-theme/login/pages/delete-account-confirm/index.ts +3 -3
  47. package/keycloak-theme/login/pages/delete-credential/Page.stories.tsx +25 -30
  48. package/keycloak-theme/login/pages/delete-credential/Page.tsx +56 -51
  49. package/keycloak-theme/login/pages/delete-credential/index.ts +3 -3
  50. package/keycloak-theme/login/pages/error/Page.stories.tsx +46 -58
  51. package/keycloak-theme/login/pages/error/Page.tsx +43 -42
  52. package/keycloak-theme/login/pages/error/index.ts +3 -3
  53. package/keycloak-theme/login/pages/frontchannel-logout/Page.stories.tsx +25 -32
  54. package/keycloak-theme/login/pages/frontchannel-logout/Page.tsx +82 -84
  55. package/keycloak-theme/login/pages/frontchannel-logout/index.ts +3 -3
  56. package/keycloak-theme/login/pages/idp-review-user-profile/Page.stories.tsx +46 -59
  57. package/keycloak-theme/login/pages/idp-review-user-profile/Page.tsx +49 -52
  58. package/keycloak-theme/login/pages/idp-review-user-profile/index.ts +3 -3
  59. package/keycloak-theme/login/pages/info/Page.stories.tsx +50 -60
  60. package/keycloak-theme/login/pages/info/Page.tsx +94 -92
  61. package/keycloak-theme/login/pages/link-idp-action/Page.stories.tsx +32 -16
  62. package/keycloak-theme/login/pages/link-idp-action/Page.tsx +45 -43
  63. package/keycloak-theme/login/pages/link-idp-action/index.ts +3 -3
  64. package/keycloak-theme/login/pages/login/Form.tsx +242 -242
  65. package/keycloak-theme/login/pages/login/Info.tsx +29 -29
  66. package/keycloak-theme/login/pages/login/Page.stories.tsx +346 -365
  67. package/keycloak-theme/login/pages/login/Page.tsx +43 -44
  68. package/keycloak-theme/login/pages/login/SocialProviders.tsx +93 -107
  69. package/keycloak-theme/login/pages/login/index.ts +3 -3
  70. package/keycloak-theme/login/pages/login/providers/apple.svg +3 -3
  71. package/keycloak-theme/login/pages/login/providers/bitbucket.svg +11 -11
  72. package/keycloak-theme/login/pages/login/providers/discord.svg +4 -4
  73. package/keycloak-theme/login/pages/login/providers/facebook.svg +5 -5
  74. package/keycloak-theme/login/pages/login/providers/github.svg +3 -3
  75. package/keycloak-theme/login/pages/login/providers/gitlab.svg +7 -7
  76. package/keycloak-theme/login/pages/login/providers/google.svg +7 -7
  77. package/keycloak-theme/login/pages/login/providers/instagram.svg +31 -31
  78. package/keycloak-theme/login/pages/login/providers/linkedin.svg +3 -3
  79. package/keycloak-theme/login/pages/login/providers/microsoft.svg +6 -6
  80. package/keycloak-theme/login/pages/login/providers/oidc.svg +5 -5
  81. package/keycloak-theme/login/pages/login/providers/openshift.svg +7 -7
  82. package/keycloak-theme/login/pages/login/providers/paypal.svg +6 -6
  83. package/keycloak-theme/login/pages/login/providers/slack.svg +11 -11
  84. package/keycloak-theme/login/pages/login/providers/stackoverflow.svg +5 -5
  85. package/keycloak-theme/login/pages/login/providers/x.svg +3 -3
  86. package/keycloak-theme/login/pages/login/useProviderLogos.tsx +39 -39
  87. package/keycloak-theme/login/pages/login/useScript.tsx +62 -62
  88. package/keycloak-theme/login/pages/login-config-totp/Page.stories.tsx +45 -60
  89. package/keycloak-theme/login/pages/login-config-totp/Page.tsx +253 -240
  90. package/keycloak-theme/login/pages/login-config-totp/index.ts +3 -3
  91. package/keycloak-theme/login/pages/login-idp-link-confirm/Page.stories.tsx +30 -35
  92. package/keycloak-theme/login/pages/login-idp-link-confirm/Page.tsx +40 -43
  93. package/keycloak-theme/login/pages/login-idp-link-confirm/index.ts +3 -3
  94. package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.stories.tsx +16 -23
  95. package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.tsx +44 -47
  96. package/keycloak-theme/login/pages/login-idp-link-confirm-override/index.ts +3 -3
  97. package/keycloak-theme/login/pages/login-idp-link-email/Page.stories.tsx +54 -63
  98. package/keycloak-theme/login/pages/login-idp-link-email/Page.tsx +51 -54
  99. package/keycloak-theme/login/pages/login-idp-link-email/index.ts +3 -3
  100. package/keycloak-theme/login/pages/login-oauth-grant/Page.stories.tsx +39 -45
  101. package/keycloak-theme/login/pages/login-oauth-grant/Page.tsx +136 -126
  102. package/keycloak-theme/login/pages/login-oauth-grant/index.ts +3 -3
  103. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/Page.stories.tsx +38 -48
  104. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/Page.tsx +56 -58
  105. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/index.ts +3 -3
  106. package/keycloak-theme/login/pages/login-otp/Page.stories.tsx +82 -97
  107. package/keycloak-theme/login/pages/login-otp/Page.tsx +117 -108
  108. package/keycloak-theme/login/pages/login-otp/index.ts +3 -3
  109. package/keycloak-theme/login/pages/login-page-expired/Page.stories.tsx +28 -37
  110. package/keycloak-theme/login/pages/login-page-expired/Page.tsx +45 -47
  111. package/keycloak-theme/login/pages/login-page-expired/index.ts +3 -3
  112. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/Page.stories.tsx +20 -0
  113. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/Page.tsx +290 -233
  114. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/index.ts +3 -3
  115. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/useScript.tsx +63 -63
  116. package/keycloak-theme/login/pages/login-password/Page.stories.tsx +55 -56
  117. package/keycloak-theme/login/pages/login-password/Page.tsx +148 -149
  118. package/keycloak-theme/login/pages/login-password/index.ts +3 -3
  119. package/keycloak-theme/login/pages/login-password/useScript.tsx +62 -63
  120. package/keycloak-theme/login/pages/login-recovery-authn-code-config/Page.stories.tsx +28 -36
  121. package/keycloak-theme/login/pages/login-recovery-authn-code-config/Page.tsx +178 -181
  122. package/keycloak-theme/login/pages/login-recovery-authn-code-config/index.ts +3 -3
  123. package/keycloak-theme/login/pages/login-recovery-authn-code-config/useScript.tsx +145 -145
  124. package/keycloak-theme/login/pages/login-recovery-authn-code-input/Page.stories.tsx +16 -22
  125. package/keycloak-theme/login/pages/login-recovery-authn-code-input/Page.tsx +69 -70
  126. package/keycloak-theme/login/pages/login-recovery-authn-code-input/index.ts +3 -3
  127. package/keycloak-theme/login/pages/login-reset-otp/Page.stories.tsx +62 -75
  128. package/keycloak-theme/login/pages/login-reset-otp/Page.tsx +85 -86
  129. package/keycloak-theme/login/pages/login-reset-otp/index.ts +3 -3
  130. package/keycloak-theme/login/pages/login-reset-password/Form.tsx +67 -68
  131. package/keycloak-theme/login/pages/login-reset-password/Page.stories.tsx +44 -55
  132. package/keycloak-theme/login/pages/login-reset-password/Page.tsx +27 -27
  133. package/keycloak-theme/login/pages/login-reset-password/index.ts +3 -3
  134. package/keycloak-theme/login/pages/login-update-password/Page.stories.tsx +40 -51
  135. package/keycloak-theme/login/pages/login-update-password/Page.tsx +109 -111
  136. package/keycloak-theme/login/pages/login-update-password/index.ts +3 -3
  137. package/keycloak-theme/login/pages/login-update-profile/Page.stories.tsx +28 -37
  138. package/keycloak-theme/login/pages/login-update-profile/Page.tsx +67 -68
  139. package/keycloak-theme/login/pages/login-update-profile/index.ts +3 -3
  140. package/keycloak-theme/login/pages/login-username/Page.stories.tsx +32 -43
  141. package/keycloak-theme/login/pages/login-username/Page.tsx +246 -246
  142. package/keycloak-theme/login/pages/login-username/index.ts +3 -3
  143. package/keycloak-theme/login/pages/login-username/useScript.tsx +62 -62
  144. package/keycloak-theme/login/pages/login-verify-email/Page.stories.tsx +68 -81
  145. package/keycloak-theme/login/pages/login-verify-email/Page.tsx +37 -38
  146. package/keycloak-theme/login/pages/login-verify-email/index.ts +3 -3
  147. package/keycloak-theme/login/pages/login-x509-info/Page.stories.tsx +29 -38
  148. package/keycloak-theme/login/pages/login-x509-info/Page.tsx +72 -75
  149. package/keycloak-theme/login/pages/login-x509-info/index.ts +3 -3
  150. package/keycloak-theme/login/pages/logout-confirm/Page.stories.tsx +34 -43
  151. package/keycloak-theme/login/pages/logout-confirm/Page.tsx +50 -53
  152. package/keycloak-theme/login/pages/logout-confirm/index.ts +3 -3
  153. package/keycloak-theme/login/pages/register/Form.tsx +107 -106
  154. package/keycloak-theme/login/pages/register/Page.stories.tsx +40 -14
  155. package/keycloak-theme/login/pages/register/Page.tsx +26 -26
  156. package/keycloak-theme/login/pages/register/TermsAcceptance.tsx +55 -56
  157. package/keycloak-theme/login/pages/register/index.ts +3 -3
  158. package/keycloak-theme/login/pages/saml-post-form/Page.stories.tsx +16 -23
  159. package/keycloak-theme/login/pages/saml-post-form/Page.tsx +64 -66
  160. package/keycloak-theme/login/pages/saml-post-form/index.ts +3 -3
  161. package/keycloak-theme/login/pages/select-authenticator/Page.stories.tsx +83 -96
  162. package/keycloak-theme/login/pages/select-authenticator/Page.tsx +97 -100
  163. package/keycloak-theme/login/pages/select-authenticator/index.ts +3 -3
  164. package/keycloak-theme/login/pages/select-organization/Page.stories.tsx +62 -49
  165. package/keycloak-theme/login/pages/select-organization/Page.tsx +123 -126
  166. package/keycloak-theme/login/pages/select-organization/index.ts +3 -3
  167. package/keycloak-theme/login/pages/terms/Page.stories.tsx +15 -0
  168. package/keycloak-theme/login/pages/terms/Page.tsx +49 -51
  169. package/keycloak-theme/login/pages/terms/index.ts +3 -3
  170. package/keycloak-theme/login/pages/update-email/Page.stories.tsx +27 -36
  171. package/keycloak-theme/login/pages/update-email/Page.tsx +61 -62
  172. package/keycloak-theme/login/pages/update-email/index.ts +3 -3
  173. package/keycloak-theme/login/pages/webauthn-authenticate/Page.stories.tsx +112 -127
  174. package/keycloak-theme/login/pages/webauthn-authenticate/Page.tsx +206 -202
  175. package/keycloak-theme/login/pages/webauthn-authenticate/index.ts +3 -3
  176. package/keycloak-theme/login/pages/webauthn-authenticate/useScript.tsx +55 -55
  177. package/keycloak-theme/login/pages/webauthn-error/Page.stories.tsx +52 -67
  178. package/keycloak-theme/login/pages/webauthn-error/Page.tsx +70 -73
  179. package/keycloak-theme/login/pages/webauthn-error/index.ts +3 -3
  180. package/keycloak-theme/login/pages/webauthn-register/Page.stories.tsx +39 -50
  181. package/keycloak-theme/login/pages/webauthn-register/Page.tsx +78 -78
  182. package/keycloak-theme/login/pages/webauthn-register/index.ts +3 -3
  183. package/keycloak-theme/login/pages/webauthn-register/useScript.tsx +62 -62
  184. package/keycloak-theme/login/shared/getColorScheme.ts +45 -45
  185. package/keycloak-theme/login/styleLevelCustomization.tsx +34 -36
  186. package/keycloak-theme/public/site.webmanifest +11 -1
  187. package/package.json +6 -2
@@ -1,51 +1,49 @@
1
- import { Button } from '@/components/ui/button';
2
- import { assert } from "tsafe/assert";
3
- import { useKcContext } from "../../KcContext";
4
- import { Template } from "../../components/Template";
5
- import { useI18n } from "../../i18n";
6
-
7
- export function Page() {
8
- const { kcContext } = useKcContext();
9
- assert(kcContext.pageId === "terms.ftl");
10
-
11
-
12
- const { msg, msgStr } = useI18n();
13
-
14
- const { url } = kcContext;
15
-
16
- return (
17
- <Template displayMessage={false} headerNode={msg("termsTitle")}>
18
- <div className="space-y-6">
19
- <div
20
- id="kc-terms-text"
21
- className="p-4 bg-muted/50 rounded-lg max-h-64 overflow-y-auto text-sm leading-relaxed"
22
- >
23
- {msg("termsText")}
24
- </div>
25
-
26
- <form className="space-y-4" action={url.loginAction} method="POST">
27
- <div className="flex flex-col sm:flex-row gap-3 sm:justify-between">
28
- <Button
29
- variant="outline"
30
- name="cancel"
31
- id="kc-decline"
32
- type="submit"
33
- className="sm:flex-1"
34
- >
35
- {msgStr("doDecline")}
36
- </Button>
37
- <Button
38
- name="accept"
39
- id="kc-accept"
40
- type="submit"
41
- className="sm:flex-1"
42
- >
43
- {msgStr("doAccept")}
44
- </Button>
45
-
46
- </div>
47
- </form>
48
- </div>
49
- </Template>
50
- );
51
- }
1
+ import { Button } from "@/components/ui/button";
2
+ import { assert } from "tsafe/assert";
3
+ import { useKcContext } from "../../KcContext";
4
+ import { Template } from "../../components/Template";
5
+ import { useI18n } from "../../i18n";
6
+
7
+ export function Page() {
8
+ const { kcContext } = useKcContext();
9
+ assert(kcContext.pageId === "terms.ftl");
10
+
11
+ const { msg, msgStr } = useI18n();
12
+
13
+ const { url } = kcContext;
14
+
15
+ return (
16
+ <Template displayMessage={false} headerNode={msg("termsTitle")}>
17
+ <div className="space-y-6">
18
+ <div
19
+ id="kc-terms-text"
20
+ className="p-4 bg-muted/50 rounded-lg max-h-64 overflow-y-auto text-sm leading-relaxed"
21
+ >
22
+ {msg("termsText")}
23
+ </div>
24
+
25
+ <form className="space-y-4" action={url.loginAction} method="POST">
26
+ <div className="flex flex-col sm:flex-row gap-3 sm:justify-between">
27
+ <Button
28
+ variant="outline"
29
+ name="cancel"
30
+ id="kc-decline"
31
+ type="submit"
32
+ className="sm:flex-1"
33
+ >
34
+ {msgStr("doDecline")}
35
+ </Button>
36
+ <Button
37
+ name="accept"
38
+ id="kc-accept"
39
+ type="submit"
40
+ className="sm:flex-1"
41
+ >
42
+ {msgStr("doAccept")}
43
+ </Button>
44
+ </div>
45
+ </form>
46
+ </div>
47
+ </Template>
48
+ );
49
+ }
@@ -1,3 +1,3 @@
1
- import { Page } from "./Page";
2
-
3
- export default Page;
1
+ import { Page } from "./Page";
2
+
3
+ export default Page;
@@ -1,6 +1,5 @@
1
1
  import { createKcPageStory, type Meta, type StoryObj } from "../../mocks/KcPageStory";
2
2
 
3
-
4
3
  const { KcPageStory } = createKcPageStory({ pageId: "update-email.ftl" });
5
4
 
6
5
  const meta = {
@@ -12,32 +11,26 @@ export default meta;
12
11
 
13
12
  type Story = StoryObj<typeof meta>;
14
13
 
15
- export const Default: Story = {
16
- render: () => <KcPageStory />
17
- };
14
+ export const Default: Story = {};
18
15
 
19
16
  export const Arabic: Story = {
20
- render: () => (
21
- <KcPageStory
22
- kcContext={{
23
- locale: {
24
- currentLanguageTag: "ar",
25
- rtl: true
26
- }
27
- }}
28
- />
29
- )
17
+ args: {
18
+ kcContext: {
19
+ locale: {
20
+ currentLanguageTag: "ar",
21
+ rtl: true
22
+ }
23
+ }
24
+ }
30
25
  };
31
26
  export const French: Story = {
32
- render: () => (
33
- <KcPageStory
34
- kcContext={{
35
- locale: {
36
- currentLanguageTag: "fr"
37
- }
38
- }}
39
- />
40
- )
27
+ args: {
28
+ kcContext: {
29
+ locale: {
30
+ currentLanguageTag: "fr"
31
+ }
32
+ }
33
+ }
41
34
  };
42
35
 
43
36
  /**
@@ -47,17 +40,15 @@ export const French: Story = {
47
40
  * - Key Aspect: Ensures the "Cancel" button is visible and functional during app-initiated actions.
48
41
  */
49
42
  export const WithAppInitiatedAction: Story = {
50
- render: () => (
51
- <KcPageStory
52
- kcContext={{
53
- url: {
54
- loginAction: "/mock-login-action"
55
- },
56
- messagesPerField: {
57
- exists: () => false
58
- },
59
- isAppInitiatedAction: true
60
- }}
61
- />
62
- )
43
+ args: {
44
+ kcContext: {
45
+ url: {
46
+ loginAction: "/mock-login-action"
47
+ },
48
+ messagesPerField: {
49
+ exists: () => false
50
+ },
51
+ isAppInitiatedAction: true
52
+ }
53
+ }
63
54
  };
@@ -1,62 +1,61 @@
1
- import { Button } from "@/components/ui/button";
2
- import { LogoutOtherSessions } from '@/login/components/LogoutOtherSessions';
3
- import { useI18n } from '@/login/i18n';
4
- import { useKcContext } from '@/login/KcContext';
5
- import { useState } from "react";
6
- import { assert } from "tsafe/assert";
7
- import { Template } from "../../components/Template";
8
- import { UserProfileFormFields } from "../../components/UserProfileFormFields";
9
-
10
-
11
- export function Page() {
12
-
13
- const { kcContext } = useKcContext();
14
- assert(kcContext.pageId === "update-email.ftl");
15
-
16
-
17
- const { msg, msgStr } = useI18n();
18
-
19
- const [isFormSubmittable, setIsFormSubmittable] = useState(false);
20
-
21
- const { url, messagesPerField, isAppInitiatedAction } = kcContext;
22
-
23
- return (
24
- <Template
25
- displayMessage={messagesPerField.exists("global")}
26
- displayRequiredFields
27
- headerNode={msg("updateEmailTitle")}
28
- >
29
- <form
30
- id="kc-update-email-form"
31
- className="space-y-6"
32
- action={url.loginAction}
33
- method="post"
34
- >
35
- <UserProfileFormFields onIsFormSubmittableValueChange={setIsFormSubmittable} />
36
-
37
- <LogoutOtherSessions />
38
-
39
- <div className="space-y-3">
40
- <Button
41
- disabled={!isFormSubmittable}
42
- className="w-full"
43
- type="submit"
44
- >
45
- {msgStr("doSubmit")}
46
- </Button>
47
- {isAppInitiatedAction && (
48
- <Button
49
- variant="outline"
50
- className="w-full"
51
- type="submit"
52
- name="cancel-aia"
53
- value="true"
54
- >
55
- {msg("doCancel")}
56
- </Button>
57
- )}
58
- </div>
59
- </form>
60
- </Template>
61
- );
62
- }
1
+ import { Button } from "@/components/ui/button";
2
+ import { LogoutOtherSessions } from "@/login/components/LogoutOtherSessions";
3
+ import { useI18n } from "@/login/i18n";
4
+ import { useKcContext } from "@/login/KcContext";
5
+ import { useState } from "react";
6
+ import { assert } from "tsafe/assert";
7
+ import { Template } from "../../components/Template";
8
+ import { UserProfileFormFields } from "../../components/UserProfileFormFields";
9
+
10
+ export function Page() {
11
+ const { kcContext } = useKcContext();
12
+ assert(kcContext.pageId === "update-email.ftl");
13
+
14
+ const { msg, msgStr } = useI18n();
15
+
16
+ const [isFormSubmittable, setIsFormSubmittable] = useState(false);
17
+
18
+ const { url, messagesPerField, isAppInitiatedAction } = kcContext;
19
+
20
+ return (
21
+ <Template
22
+ displayMessage={messagesPerField.exists("global")}
23
+ displayRequiredFields
24
+ headerNode={msg("updateEmailTitle")}
25
+ >
26
+ <form
27
+ id="kc-update-email-form"
28
+ className="space-y-6"
29
+ action={url.loginAction}
30
+ method="post"
31
+ >
32
+ <UserProfileFormFields
33
+ onIsFormSubmittableValueChange={setIsFormSubmittable}
34
+ />
35
+
36
+ <LogoutOtherSessions />
37
+
38
+ <div className="space-y-3">
39
+ <Button
40
+ disabled={!isFormSubmittable}
41
+ className="w-full"
42
+ type="submit"
43
+ >
44
+ {msgStr("doSubmit")}
45
+ </Button>
46
+ {isAppInitiatedAction && (
47
+ <Button
48
+ variant="outline"
49
+ className="w-full"
50
+ type="submit"
51
+ name="cancel-aia"
52
+ value="true"
53
+ >
54
+ {msg("doCancel")}
55
+ </Button>
56
+ )}
57
+ </div>
58
+ </form>
59
+ </Template>
60
+ );
61
+ }
@@ -1,3 +1,3 @@
1
- import { Page } from "./Page";
2
-
3
- export default Page;
1
+ import { Page } from "./Page";
2
+
3
+ export default Page;
@@ -1,6 +1,5 @@
1
1
  import { createKcPageStory, type Meta, type StoryObj } from "../../mocks/KcPageStory";
2
2
 
3
-
4
3
  const { KcPageStory } = createKcPageStory({ pageId: "webauthn-authenticate.ftl" });
5
4
 
6
5
  const meta = {
@@ -12,32 +11,26 @@ export default meta;
12
11
 
13
12
  type Story = StoryObj<typeof meta>;
14
13
 
15
- export const Default: Story = {
16
- render: () => <KcPageStory />
17
- };
14
+ export const Default: Story = {};
18
15
 
19
16
  export const Arabic: Story = {
20
- render: () => (
21
- <KcPageStory
22
- kcContext={{
23
- locale: {
24
- currentLanguageTag: "ar",
25
- rtl: true
26
- }
27
- }}
28
- />
29
- )
17
+ args: {
18
+ kcContext: {
19
+ locale: {
20
+ currentLanguageTag: "ar",
21
+ rtl: true
22
+ }
23
+ }
24
+ }
30
25
  };
31
26
  export const French: Story = {
32
- render: () => (
33
- <KcPageStory
34
- kcContext={{
35
- locale: {
36
- currentLanguageTag: "fr"
37
- }
38
- }}
39
- />
40
- )
27
+ args: {
28
+ kcContext: {
29
+ locale: {
30
+ currentLanguageTag: "fr"
31
+ }
32
+ }
33
+ }
41
34
  };
42
35
 
43
36
  /**
@@ -47,38 +40,36 @@ export const French: Story = {
47
40
  * - Key Aspect: Ensures that the available authenticators are displayed, and the user can select one.
48
41
  */
49
42
  export const WithMultipleAuthenticators: Story = {
50
- render: () => (
51
- <KcPageStory
52
- kcContext={{
53
- url: {
54
- loginAction: "/mock-login-action"
55
- },
56
- authenticators: {
57
- authenticators: [
58
- {
59
- credentialId: "authenticator-1",
60
- label: "Security Key 1",
61
- transports: {
62
- iconClass: "kcAuthenticatorUsbIcon",
63
- displayNameProperties: ["USB"]
64
- },
65
- createdAt: "2023-01-01"
43
+ args: {
44
+ kcContext: {
45
+ url: {
46
+ loginAction: "/mock-login-action"
47
+ },
48
+ authenticators: {
49
+ authenticators: [
50
+ {
51
+ credentialId: "authenticator-1",
52
+ label: "Security Key 1",
53
+ transports: {
54
+ iconClass: "kcAuthenticatorUsbIcon",
55
+ displayNameProperties: ["USB"]
56
+ },
57
+ createdAt: "2023-01-01"
58
+ },
59
+ {
60
+ credentialId: "authenticator-2",
61
+ label: "Security Key 2",
62
+ transports: {
63
+ iconClass: "kcAuthenticatorNfcIcon",
64
+ displayNameProperties: ["NFC"]
66
65
  },
67
- {
68
- credentialId: "authenticator-2",
69
- label: "Security Key 2",
70
- transports: {
71
- iconClass: "kcAuthenticatorNfcIcon",
72
- displayNameProperties: ["NFC"]
73
- },
74
- createdAt: "2023-02-01"
75
- }
76
- ]
77
- },
78
- shouldDisplayAuthenticators: true
79
- }}
80
- />
81
- )
66
+ createdAt: "2023-02-01"
67
+ }
68
+ ]
69
+ },
70
+ shouldDisplayAuthenticators: true
71
+ }
72
+ }
82
73
  };
83
74
 
84
75
  /**
@@ -88,29 +79,27 @@ export const WithMultipleAuthenticators: Story = {
88
79
  * - Key Aspect: Ensures the form renders correctly when there is only one authenticator available.
89
80
  */
90
81
  export const WithSingleAuthenticator: Story = {
91
- render: () => (
92
- <KcPageStory
93
- kcContext={{
94
- url: {
95
- loginAction: "/mock-login-action"
96
- },
97
- authenticators: {
98
- authenticators: [
99
- {
100
- credentialId: "authenticator-1",
101
- label: "My Security Key",
102
- transports: {
103
- iconClass: "kcAuthenticatorUsbIcon",
104
- displayNameProperties: ["USB"]
105
- },
106
- createdAt: "2023-01-01"
107
- }
108
- ]
109
- },
110
- shouldDisplayAuthenticators: true
111
- }}
112
- />
113
- )
82
+ args: {
83
+ kcContext: {
84
+ url: {
85
+ loginAction: "/mock-login-action"
86
+ },
87
+ authenticators: {
88
+ authenticators: [
89
+ {
90
+ credentialId: "authenticator-1",
91
+ label: "My Security Key",
92
+ transports: {
93
+ iconClass: "kcAuthenticatorUsbIcon",
94
+ displayNameProperties: ["USB"]
95
+ },
96
+ createdAt: "2023-01-01"
97
+ }
98
+ ]
99
+ },
100
+ shouldDisplayAuthenticators: true
101
+ }
102
+ }
114
103
  };
115
104
 
116
105
  /**
@@ -120,33 +109,31 @@ export const WithSingleAuthenticator: Story = {
120
109
  * - Key Aspect: Ensures the form handles authentication errors and displays a relevant message.
121
110
  */
122
111
  export const WithErrorDuringAuthentication: Story = {
123
- render: () => (
124
- <KcPageStory
125
- kcContext={{
126
- url: {
127
- loginAction: "/mock-login-action"
128
- },
129
- authenticators: {
130
- authenticators: [
131
- {
132
- credentialId: "authenticator-1",
133
- label: "My Security Key",
134
- transports: {
135
- iconClass: "kcAuthenticatorUsbIcon",
136
- displayNameProperties: ["USB"]
137
- },
138
- createdAt: "2023-01-01"
139
- }
140
- ]
141
- },
142
- shouldDisplayAuthenticators: true,
143
- message: {
144
- summary: "An error occurred during WebAuthn authentication.",
145
- type: "error"
146
- }
147
- }}
148
- />
149
- )
112
+ args: {
113
+ kcContext: {
114
+ url: {
115
+ loginAction: "/mock-login-action"
116
+ },
117
+ authenticators: {
118
+ authenticators: [
119
+ {
120
+ credentialId: "authenticator-1",
121
+ label: "My Security Key",
122
+ transports: {
123
+ iconClass: "kcAuthenticatorUsbIcon",
124
+ displayNameProperties: ["USB"]
125
+ },
126
+ createdAt: "2023-01-01"
127
+ }
128
+ ]
129
+ },
130
+ shouldDisplayAuthenticators: true,
131
+ message: {
132
+ summary: "An error occurred during WebAuthn authentication.",
133
+ type: "error"
134
+ }
135
+ }
136
+ }
150
137
  };
151
138
 
152
139
  /**
@@ -156,27 +143,25 @@ export const WithErrorDuringAuthentication: Story = {
156
143
  * - Key Aspect: Ensures the form provides a clear message when JavaScript is required but unavailable.
157
144
  */
158
145
  export const WithJavaScriptDisabled: Story = {
159
- render: () => (
160
- <KcPageStory
161
- kcContext={{
162
- url: {
163
- loginAction: "/mock-login-action"
164
- },
165
- authenticators: {
166
- authenticators: [
167
- {
168
- credentialId: "authenticator-1",
169
- label: "My Security Key",
170
- transports: {
171
- iconClass: "kcAuthenticatorUsbIcon",
172
- displayNameProperties: ["USB"]
173
- },
174
- createdAt: "2023-01-01"
175
- }
176
- ]
177
- },
178
- shouldDisplayAuthenticators: true
179
- }}
180
- />
181
- )
146
+ args: {
147
+ kcContext: {
148
+ url: {
149
+ loginAction: "/mock-login-action"
150
+ },
151
+ authenticators: {
152
+ authenticators: [
153
+ {
154
+ credentialId: "authenticator-1",
155
+ label: "My Security Key",
156
+ transports: {
157
+ iconClass: "kcAuthenticatorUsbIcon",
158
+ displayNameProperties: ["USB"]
159
+ },
160
+ createdAt: "2023-01-01"
161
+ }
162
+ ]
163
+ },
164
+ shouldDisplayAuthenticators: true
165
+ }
166
+ }
182
167
  };