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