keycloakify 6.3.5 → 6.4.0

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 (78) hide show
  1. package/README.md +6 -0
  2. package/lib/components/Error.d.ts +2 -1
  3. package/lib/components/Error.js +2 -2
  4. package/lib/components/Error.js.map +1 -1
  5. package/lib/components/IdpReviewUserProfile.d.ts +2 -1
  6. package/lib/components/IdpReviewUserProfile.js +2 -2
  7. package/lib/components/IdpReviewUserProfile.js.map +1 -1
  8. package/lib/components/Info.d.ts +2 -1
  9. package/lib/components/Info.js +2 -2
  10. package/lib/components/Info.js.map +1 -1
  11. package/lib/components/KcApp.d.ts +1 -0
  12. package/lib/components/KcApp.js.map +1 -1
  13. package/lib/components/Login.d.ts +2 -1
  14. package/lib/components/Login.js +2 -2
  15. package/lib/components/Login.js.map +1 -1
  16. package/lib/components/LoginConfigTotp.d.ts +2 -1
  17. package/lib/components/LoginConfigTotp.js +2 -2
  18. package/lib/components/LoginConfigTotp.js.map +1 -1
  19. package/lib/components/LoginIdpLinkConfirm.d.ts +2 -1
  20. package/lib/components/LoginIdpLinkConfirm.js +2 -2
  21. package/lib/components/LoginIdpLinkConfirm.js.map +1 -1
  22. package/lib/components/LoginIdpLinkEmail.d.ts +2 -1
  23. package/lib/components/LoginIdpLinkEmail.js +2 -2
  24. package/lib/components/LoginIdpLinkEmail.js.map +1 -1
  25. package/lib/components/LoginOtp.d.ts +2 -1
  26. package/lib/components/LoginOtp.js +2 -2
  27. package/lib/components/LoginOtp.js.map +1 -1
  28. package/lib/components/LoginPageExpired.d.ts +2 -1
  29. package/lib/components/LoginPageExpired.js +2 -2
  30. package/lib/components/LoginPageExpired.js.map +1 -1
  31. package/lib/components/LoginResetPassword.d.ts +2 -1
  32. package/lib/components/LoginResetPassword.js +2 -2
  33. package/lib/components/LoginResetPassword.js.map +1 -1
  34. package/lib/components/LoginUpdatePassword.d.ts +2 -1
  35. package/lib/components/LoginUpdatePassword.js +2 -2
  36. package/lib/components/LoginUpdatePassword.js.map +1 -1
  37. package/lib/components/LoginUpdateProfile.d.ts +2 -1
  38. package/lib/components/LoginUpdateProfile.js +2 -2
  39. package/lib/components/LoginUpdateProfile.js.map +1 -1
  40. package/lib/components/LoginVerifyEmail.d.ts +2 -1
  41. package/lib/components/LoginVerifyEmail.js +2 -2
  42. package/lib/components/LoginVerifyEmail.js.map +1 -1
  43. package/lib/components/LogoutConfirm.d.ts +2 -1
  44. package/lib/components/LogoutConfirm.js +2 -2
  45. package/lib/components/LogoutConfirm.js.map +1 -1
  46. package/lib/components/Register.d.ts +2 -1
  47. package/lib/components/Register.js +2 -2
  48. package/lib/components/Register.js.map +1 -1
  49. package/lib/components/RegisterUserProfile.d.ts +2 -1
  50. package/lib/components/RegisterUserProfile.js +2 -2
  51. package/lib/components/RegisterUserProfile.js.map +1 -1
  52. package/lib/components/Terms.d.ts +2 -1
  53. package/lib/components/Terms.js +2 -2
  54. package/lib/components/Terms.js.map +1 -1
  55. package/lib/components/UpdateUserProfile.d.ts +2 -1
  56. package/lib/components/UpdateUserProfile.js +2 -2
  57. package/lib/components/UpdateUserProfile.js.map +1 -1
  58. package/lib/tsconfig.tsbuildinfo +1 -1
  59. package/package.json +3 -3
  60. package/src/lib/components/Error.tsx +30 -24
  61. package/src/lib/components/IdpReviewUserProfile.tsx +41 -30
  62. package/src/lib/components/Info.tsx +41 -35
  63. package/src/lib/components/KcApp.tsx +64 -58
  64. package/src/lib/components/Login.tsx +174 -166
  65. package/src/lib/components/LoginConfigTotp.tsx +158 -152
  66. package/src/lib/components/LoginIdpLinkConfirm.tsx +42 -36
  67. package/src/lib/components/LoginIdpLinkEmail.tsx +30 -24
  68. package/src/lib/components/LoginOtp.tsx +75 -64
  69. package/src/lib/components/LoginPageExpired.tsx +34 -28
  70. package/src/lib/components/LoginResetPassword.tsx +63 -52
  71. package/src/lib/components/LoginUpdatePassword.tsx +101 -95
  72. package/src/lib/components/LoginUpdateProfile.tsx +103 -91
  73. package/src/lib/components/LoginVerifyEmail.tsx +30 -24
  74. package/src/lib/components/LogoutConfirm.tsx +53 -47
  75. package/src/lib/components/Register.tsx +126 -115
  76. package/src/lib/components/RegisterUserProfile.tsx +59 -48
  77. package/src/lib/components/Terms.tsx +51 -45
  78. package/src/lib/components/UpdateUserProfile.tsx +57 -51
@@ -7,189 +7,197 @@ import { useConstCallback } from "powerhooks/useConstCallback";
7
7
  import type { FormEventHandler } from "react";
8
8
  import type { I18n } from "../i18n";
9
9
 
10
- const Login = memo(({ kcContext, i18n, ...props }: { kcContext: KcContextBase.Login; i18n: I18n } & KcProps) => {
11
- const { social, realm, url, usernameEditDisabled, login, auth, registrationDisabled } = kcContext;
10
+ const Login = memo(
11
+ ({
12
+ kcContext,
13
+ i18n,
14
+ doFetchDefaultThemeResources = true,
15
+ ...props
16
+ }: { kcContext: KcContextBase.Login; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
17
+ const { social, realm, url, usernameEditDisabled, login, auth, registrationDisabled } = kcContext;
12
18
 
13
- const { msg, msgStr } = i18n;
19
+ const { msg, msgStr } = i18n;
14
20
 
15
- const { cx } = useCssAndCx();
21
+ const { cx } = useCssAndCx();
16
22
 
17
- const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
23
+ const [isLoginButtonDisabled, setIsLoginButtonDisabled] = useState(false);
18
24
 
19
- const onSubmit = useConstCallback<FormEventHandler<HTMLFormElement>>(e => {
20
- e.preventDefault();
25
+ const onSubmit = useConstCallback<FormEventHandler<HTMLFormElement>>(e => {
26
+ e.preventDefault();
21
27
 
22
- setIsLoginButtonDisabled(true);
28
+ setIsLoginButtonDisabled(true);
23
29
 
24
- const formElement = e.target as HTMLFormElement;
30
+ const formElement = e.target as HTMLFormElement;
25
31
 
26
- //NOTE: Even if we login with email Keycloak expect username and password in
27
- //the POST request.
28
- formElement.querySelector("input[name='email']")?.setAttribute("name", "username");
32
+ //NOTE: Even if we login with email Keycloak expect username and password in
33
+ //the POST request.
34
+ formElement.querySelector("input[name='email']")?.setAttribute("name", "username");
29
35
 
30
- formElement.submit();
31
- });
36
+ formElement.submit();
37
+ });
32
38
 
33
- return (
34
- <Template
35
- {...{ kcContext, i18n, ...props }}
36
- doFetchDefaultThemeResources={true}
37
- displayInfo={social.displayInfo}
38
- displayWide={realm.password && social.providers !== undefined}
39
- headerNode={msg("doLogIn")}
40
- formNode={
41
- <div id="kc-form" className={cx(realm.password && social.providers !== undefined && props.kcContentWrapperClass)}>
42
- <div
43
- id="kc-form-wrapper"
44
- className={cx(realm.password && social.providers && [props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass])}
45
- >
46
- {realm.password && (
47
- <form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
48
- <div className={cx(props.kcFormGroupClass)}>
49
- {(() => {
50
- const label = !realm.loginWithEmailAllowed
51
- ? "username"
52
- : realm.registrationEmailAsUsername
53
- ? "email"
54
- : "usernameOrEmail";
39
+ return (
40
+ <Template
41
+ {...{ kcContext, i18n, doFetchDefaultThemeResources, ...props }}
42
+ displayInfo={social.displayInfo}
43
+ displayWide={realm.password && social.providers !== undefined}
44
+ headerNode={msg("doLogIn")}
45
+ formNode={
46
+ <div id="kc-form" className={cx(realm.password && social.providers !== undefined && props.kcContentWrapperClass)}>
47
+ <div
48
+ id="kc-form-wrapper"
49
+ className={cx(
50
+ realm.password && social.providers && [props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass]
51
+ )}
52
+ >
53
+ {realm.password && (
54
+ <form id="kc-form-login" onSubmit={onSubmit} action={url.loginAction} method="post">
55
+ <div className={cx(props.kcFormGroupClass)}>
56
+ {(() => {
57
+ const label = !realm.loginWithEmailAllowed
58
+ ? "username"
59
+ : realm.registrationEmailAsUsername
60
+ ? "email"
61
+ : "usernameOrEmail";
55
62
 
56
- const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
63
+ const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
57
64
 
58
- return (
59
- <>
60
- <label htmlFor={autoCompleteHelper} className={cx(props.kcLabelClass)}>
61
- {msg(label)}
62
- </label>
63
- <input
64
- tabIndex={1}
65
- id={autoCompleteHelper}
66
- className={cx(props.kcInputClass)}
67
- //NOTE: This is used by Google Chrome auto fill so we use it to tell
68
- //the browser how to pre fill the form but before submit we put it back
69
- //to username because it is what keycloak expects.
70
- name={autoCompleteHelper}
71
- defaultValue={login.username ?? ""}
72
- type="text"
73
- {...(usernameEditDisabled
74
- ? { "disabled": true }
75
- : {
76
- "autoFocus": true,
77
- "autoComplete": "off"
78
- })}
79
- />
80
- </>
81
- );
82
- })()}
83
- </div>
84
- <div className={cx(props.kcFormGroupClass)}>
85
- <label htmlFor="password" className={cx(props.kcLabelClass)}>
86
- {msg("password")}
87
- </label>
88
- <input
89
- tabIndex={2}
90
- id="password"
91
- className={cx(props.kcInputClass)}
92
- name="password"
93
- type="password"
94
- autoComplete="off"
95
- />
96
- </div>
97
- <div className={cx(props.kcFormGroupClass, props.kcFormSettingClass)}>
98
- <div id="kc-form-options">
99
- {realm.rememberMe && !usernameEditDisabled && (
100
- <div className="checkbox">
101
- <label>
65
+ return (
66
+ <>
67
+ <label htmlFor={autoCompleteHelper} className={cx(props.kcLabelClass)}>
68
+ {msg(label)}
69
+ </label>
102
70
  <input
103
- tabIndex={3}
104
- id="rememberMe"
105
- name="rememberMe"
106
- type="checkbox"
107
- {...(login.rememberMe
108
- ? {
109
- "checked": true
110
- }
111
- : {})}
71
+ tabIndex={1}
72
+ id={autoCompleteHelper}
73
+ className={cx(props.kcInputClass)}
74
+ //NOTE: This is used by Google Chrome auto fill so we use it to tell
75
+ //the browser how to pre fill the form but before submit we put it back
76
+ //to username because it is what keycloak expects.
77
+ name={autoCompleteHelper}
78
+ defaultValue={login.username ?? ""}
79
+ type="text"
80
+ {...(usernameEditDisabled
81
+ ? { "disabled": true }
82
+ : {
83
+ "autoFocus": true,
84
+ "autoComplete": "off"
85
+ })}
112
86
  />
113
- {msg("rememberMe")}
114
- </label>
115
- </div>
116
- )}
87
+ </>
88
+ );
89
+ })()}
117
90
  </div>
118
- <div className={cx(props.kcFormOptionsWrapperClass)}>
119
- {realm.resetPasswordAllowed && (
120
- <span>
121
- <a tabIndex={5} href={url.loginResetCredentialsUrl}>
122
- {msg("doForgotPassword")}
123
- </a>
124
- </span>
125
- )}
91
+ <div className={cx(props.kcFormGroupClass)}>
92
+ <label htmlFor="password" className={cx(props.kcLabelClass)}>
93
+ {msg("password")}
94
+ </label>
95
+ <input
96
+ tabIndex={2}
97
+ id="password"
98
+ className={cx(props.kcInputClass)}
99
+ name="password"
100
+ type="password"
101
+ autoComplete="off"
102
+ />
126
103
  </div>
127
- </div>
128
- <div id="kc-form-buttons" className={cx(props.kcFormGroupClass)}>
129
- <input
130
- type="hidden"
131
- id="id-hidden-input"
132
- name="credentialId"
133
- {...(auth?.selectedCredential !== undefined
134
- ? {
135
- "value": auth.selectedCredential
136
- }
137
- : {})}
138
- />
139
- <input
140
- tabIndex={4}
141
- className={cx(
142
- props.kcButtonClass,
143
- props.kcButtonPrimaryClass,
144
- props.kcButtonBlockClass,
145
- props.kcButtonLargeClass
146
- )}
147
- name="login"
148
- id="kc-login"
149
- type="submit"
150
- value={msgStr("doLogIn")}
151
- disabled={isLoginButtonDisabled}
152
- />
153
- </div>
154
- </form>
104
+ <div className={cx(props.kcFormGroupClass, props.kcFormSettingClass)}>
105
+ <div id="kc-form-options">
106
+ {realm.rememberMe && !usernameEditDisabled && (
107
+ <div className="checkbox">
108
+ <label>
109
+ <input
110
+ tabIndex={3}
111
+ id="rememberMe"
112
+ name="rememberMe"
113
+ type="checkbox"
114
+ {...(login.rememberMe
115
+ ? {
116
+ "checked": true
117
+ }
118
+ : {})}
119
+ />
120
+ {msg("rememberMe")}
121
+ </label>
122
+ </div>
123
+ )}
124
+ </div>
125
+ <div className={cx(props.kcFormOptionsWrapperClass)}>
126
+ {realm.resetPasswordAllowed && (
127
+ <span>
128
+ <a tabIndex={5} href={url.loginResetCredentialsUrl}>
129
+ {msg("doForgotPassword")}
130
+ </a>
131
+ </span>
132
+ )}
133
+ </div>
134
+ </div>
135
+ <div id="kc-form-buttons" className={cx(props.kcFormGroupClass)}>
136
+ <input
137
+ type="hidden"
138
+ id="id-hidden-input"
139
+ name="credentialId"
140
+ {...(auth?.selectedCredential !== undefined
141
+ ? {
142
+ "value": auth.selectedCredential
143
+ }
144
+ : {})}
145
+ />
146
+ <input
147
+ tabIndex={4}
148
+ className={cx(
149
+ props.kcButtonClass,
150
+ props.kcButtonPrimaryClass,
151
+ props.kcButtonBlockClass,
152
+ props.kcButtonLargeClass
153
+ )}
154
+ name="login"
155
+ id="kc-login"
156
+ type="submit"
157
+ value={msgStr("doLogIn")}
158
+ disabled={isLoginButtonDisabled}
159
+ />
160
+ </div>
161
+ </form>
162
+ )}
163
+ </div>
164
+ {realm.password && social.providers !== undefined && (
165
+ <div id="kc-social-providers" className={cx(props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass)}>
166
+ <ul
167
+ className={cx(
168
+ props.kcFormSocialAccountListClass,
169
+ social.providers.length > 4 && props.kcFormSocialAccountDoubleListClass
170
+ )}
171
+ >
172
+ {social.providers.map(p => (
173
+ <li key={p.providerId} className={cx(props.kcFormSocialAccountListLinkClass)}>
174
+ <a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
175
+ <span>{p.displayName}</span>
176
+ </a>
177
+ </li>
178
+ ))}
179
+ </ul>
180
+ </div>
155
181
  )}
156
182
  </div>
157
- {realm.password && social.providers !== undefined && (
158
- <div id="kc-social-providers" className={cx(props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass)}>
159
- <ul
160
- className={cx(
161
- props.kcFormSocialAccountListClass,
162
- social.providers.length > 4 && props.kcFormSocialAccountDoubleListClass
163
- )}
164
- >
165
- {social.providers.map(p => (
166
- <li key={p.providerId} className={cx(props.kcFormSocialAccountListLinkClass)}>
167
- <a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
168
- <span>{p.displayName}</span>
169
- </a>
170
- </li>
171
- ))}
172
- </ul>
183
+ }
184
+ infoNode={
185
+ realm.password &&
186
+ realm.registrationAllowed &&
187
+ !registrationDisabled && (
188
+ <div id="kc-registration">
189
+ <span>
190
+ {msg("noAccount")}
191
+ <a tabIndex={6} href={url.registrationUrl}>
192
+ {msg("doRegister")}
193
+ </a>
194
+ </span>
173
195
  </div>
174
- )}
175
- </div>
176
- }
177
- infoNode={
178
- realm.password &&
179
- realm.registrationAllowed &&
180
- !registrationDisabled && (
181
- <div id="kc-registration">
182
- <span>
183
- {msg("noAccount")}
184
- <a tabIndex={6} href={url.registrationUrl}>
185
- {msg("doRegister")}
186
- </a>
187
- </span>
188
- </div>
189
- )
190
- }
191
- />
192
- );
193
- });
196
+ )
197
+ }
198
+ />
199
+ );
200
+ }
201
+ );
194
202
 
195
203
  export default Login;