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,162 +8,164 @@ import { useConstCallback } from "powerhooks/useConstCallback";
7
8
  import type { FormEventHandler } from "react";
8
9
  import type { I18n } from "../i18n";
9
10
 
10
- const LoginUsername = memo(
11
- ({
12
- kcContext,
13
- i18n,
14
- doFetchDefaultThemeResources = true,
15
- ...props
16
- }: { kcContext: KcContextBase.LoginUsername; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
17
- const { social, realm, url, usernameHidden, login, registrationDisabled } = kcContext;
11
+ export type LoginUsernameProps = KcProps & {
12
+ kcContext: KcContextBase.LoginUsername;
13
+ i18n: I18n;
14
+ doFetchDefaultThemeResources?: boolean;
15
+ Template?: (props: TemplateProps) => JSX.Element | null;
16
+ };
18
17
 
19
- const { msg, msgStr } = i18n;
18
+ const LoginUsername = memo((props: LoginUsernameProps) => {
19
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
20
20
 
21
- const { cx } = useCssAndCx();
21
+ const { social, realm, url, usernameHidden, login, 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
- {!usernameHidden &&
57
- (() => {
58
- const label = !realm.loginWithEmailAllowed
59
- ? "username"
60
- : realm.registrationEmailAsUsername
61
- ? "email"
62
- : "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");
63
39
 
64
- const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
40
+ formElement.submit();
41
+ });
65
42
 
66
- return (
67
- <>
68
- <label htmlFor={autoCompleteHelper} className={cx(props.kcLabelClass)}>
69
- {msg(label)}
70
- </label>
71
- <input
72
- tabIndex={1}
73
- id={autoCompleteHelper}
74
- className={cx(props.kcInputClass)}
75
- //NOTE: This is used by Google Chrome auto fill so we use it to tell
76
- //the browser how to pre fill the form but before submit we put it back
77
- //to username because it is what keycloak expects.
78
- name={autoCompleteHelper}
79
- defaultValue={login.username ?? ""}
80
- type="text"
81
- autoFocus={true}
82
- autoComplete="off"
83
- />
84
- </>
85
- );
86
- })()}
87
- </div>
88
- <div className={cx(props.kcFormGroupClass, props.kcFormSettingClass)}>
89
- <div id="kc-form-options">
90
- {realm.rememberMe && !usernameHidden && (
91
- <div className="checkbox">
92
- <label>
93
- <input
94
- tabIndex={3}
95
- id="rememberMe"
96
- name="rememberMe"
97
- type="checkbox"
98
- {...(login.rememberMe
99
- ? {
100
- "checked": true
101
- }
102
- : {})}
103
- />
104
- {msg("rememberMe")}
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
+ {!usernameHidden &&
61
+ (() => {
62
+ const label = !realm.loginWithEmailAllowed
63
+ ? "username"
64
+ : realm.registrationEmailAsUsername
65
+ ? "email"
66
+ : "usernameOrEmail";
67
+
68
+ const autoCompleteHelper: typeof label = label === "usernameOrEmail" ? "username" : label;
69
+
70
+ return (
71
+ <>
72
+ <label htmlFor={autoCompleteHelper} className={cx(kcProps.kcLabelClass)}>
73
+ {msg(label)}
105
74
  </label>
106
- </div>
107
- )}
108
- </div>
75
+ <input
76
+ tabIndex={1}
77
+ id={autoCompleteHelper}
78
+ className={cx(kcProps.kcInputClass)}
79
+ //NOTE: This is used by Google Chrome auto fill so we use it to tell
80
+ //the browser how to pre fill the form but before submit we put it back
81
+ //to username because it is what keycloak expects.
82
+ name={autoCompleteHelper}
83
+ defaultValue={login.username ?? ""}
84
+ type="text"
85
+ autoFocus={true}
86
+ autoComplete="off"
87
+ />
88
+ </>
89
+ );
90
+ })()}
91
+ </div>
92
+ <div className={cx(kcProps.kcFormGroupClass, kcProps.kcFormSettingClass)}>
93
+ <div id="kc-form-options">
94
+ {realm.rememberMe && !usernameHidden && (
95
+ <div className="checkbox">
96
+ <label>
97
+ <input
98
+ tabIndex={3}
99
+ id="rememberMe"
100
+ name="rememberMe"
101
+ type="checkbox"
102
+ {...(login.rememberMe
103
+ ? {
104
+ "checked": true
105
+ }
106
+ : {})}
107
+ />
108
+ {msg("rememberMe")}
109
+ </label>
110
+ </div>
111
+ )}
109
112
  </div>
110
- <div id="kc-form-buttons" className={cx(props.kcFormGroupClass)}>
111
- <input
112
- tabIndex={4}
113
- className={cx(
114
- props.kcButtonClass,
115
- props.kcButtonPrimaryClass,
116
- props.kcButtonBlockClass,
117
- props.kcButtonLargeClass
118
- )}
119
- name="login"
120
- id="kc-login"
121
- type="submit"
122
- value={msgStr("doLogIn")}
123
- disabled={isLoginButtonDisabled}
124
- />
125
- </div>
126
- </form>
127
- )}
128
- </div>
129
- {realm.password && social.providers !== undefined && (
130
- <div id="kc-social-providers" className={cx(props.kcFormSocialAccountContentClass, props.kcFormSocialAccountClass)}>
131
- <ul
132
- className={cx(
133
- props.kcFormSocialAccountListClass,
134
- social.providers.length > 4 && props.kcFormSocialAccountDoubleListClass
135
- )}
136
- >
137
- {social.providers.map(p => (
138
- <li key={p.providerId} className={cx(props.kcFormSocialAccountListLinkClass)}>
139
- <a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
140
- <span>{p.displayName}</span>
141
- </a>
142
- </li>
143
- ))}
144
- </ul>
145
- </div>
113
+ </div>
114
+ <div id="kc-form-buttons" className={cx(kcProps.kcFormGroupClass)}>
115
+ <input
116
+ tabIndex={4}
117
+ className={cx(
118
+ kcProps.kcButtonClass,
119
+ kcProps.kcButtonPrimaryClass,
120
+ kcProps.kcButtonBlockClass,
121
+ kcProps.kcButtonLargeClass
122
+ )}
123
+ name="login"
124
+ id="kc-login"
125
+ type="submit"
126
+ value={msgStr("doLogIn")}
127
+ disabled={isLoginButtonDisabled}
128
+ />
129
+ </div>
130
+ </form>
146
131
  )}
147
132
  </div>
148
- }
149
- infoNode={
150
- realm.password &&
151
- realm.registrationAllowed &&
152
- !registrationDisabled && (
153
- <div id="kc-registration">
154
- <span>
155
- {msg("noAccount")}
156
- <a tabIndex={6} href={url.registrationUrl}>
157
- {msg("doRegister")}
158
- </a>
159
- </span>
133
+ {realm.password && social.providers !== undefined && (
134
+ <div id="kc-social-providers" className={cx(kcProps.kcFormSocialAccountContentClass, kcProps.kcFormSocialAccountClass)}>
135
+ <ul
136
+ className={cx(
137
+ kcProps.kcFormSocialAccountListClass,
138
+ social.providers.length > 4 && kcProps.kcFormSocialAccountDoubleListClass
139
+ )}
140
+ >
141
+ {social.providers.map(p => (
142
+ <li key={p.providerId} className={cx(kcProps.kcFormSocialAccountListLinkClass)}>
143
+ <a href={p.loginUrl} id={`zocial-${p.alias}`} className={cx("zocial", p.providerId)}>
144
+ <span>{p.displayName}</span>
145
+ </a>
146
+ </li>
147
+ ))}
148
+ </ul>
160
149
  </div>
161
- )
162
- }
163
- />
164
- );
165
- }
166
- );
150
+ )}
151
+ </div>
152
+ }
153
+ infoNode={
154
+ realm.password &&
155
+ realm.registrationAllowed &&
156
+ !registrationDisabled && (
157
+ <div id="kc-registration">
158
+ <span>
159
+ {msg("noAccount")}
160
+ <a tabIndex={6} href={url.registrationUrl}>
161
+ {msg("doRegister")}
162
+ </a>
163
+ </span>
164
+ </div>
165
+ )
166
+ }
167
+ />
168
+ );
169
+ });
167
170
 
168
171
  export default LoginUsername;
@@ -1,40 +1,43 @@
1
1
  import React, { 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 type { I18n } from "../i18n";
6
7
 
7
- const LoginVerifyEmail = memo(
8
- ({
9
- kcContext,
10
- i18n,
11
- doFetchDefaultThemeResources = true,
12
- ...props
13
- }: { kcContext: KcContextBase.LoginVerifyEmail; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
14
- const { msg } = i18n;
8
+ export type LoginVerifyEmailProps = KcProps & {
9
+ kcContext: KcContextBase.LoginVerifyEmail;
10
+ i18n: I18n;
11
+ doFetchDefaultThemeResources?: boolean;
12
+ Template?: (props: TemplateProps) => JSX.Element | null;
13
+ };
15
14
 
16
- const { url, user } = kcContext;
15
+ const LoginVerifyEmail = memo((props: LoginVerifyEmailProps) => {
16
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
17
17
 
18
- return (
19
- <Template
20
- {...{ kcContext, i18n, doFetchDefaultThemeResources, ...props }}
21
- displayMessage={false}
22
- headerNode={msg("emailVerifyTitle")}
23
- formNode={
24
- <>
25
- <p className="instruction">{msg("emailVerifyInstruction1", user?.email)}</p>
26
- <p className="instruction">
27
- {msg("emailVerifyInstruction2")}
28
- <br />
29
- <a href={url.loginAction}>{msg("doClickHere")}</a>
30
- &nbsp;
31
- {msg("emailVerifyInstruction3")}
32
- </p>
33
- </>
34
- }
35
- />
36
- );
37
- }
38
- );
18
+ const { msg } = i18n;
19
+
20
+ const { url, user } = kcContext;
21
+
22
+ return (
23
+ <Template
24
+ {...{ kcContext, i18n, doFetchDefaultThemeResources, ...kcProps }}
25
+ displayMessage={false}
26
+ headerNode={msg("emailVerifyTitle")}
27
+ formNode={
28
+ <>
29
+ <p className="instruction">{msg("emailVerifyInstruction1", user?.email)}</p>
30
+ <p className="instruction">
31
+ {msg("emailVerifyInstruction2")}
32
+ <br />
33
+ <a href={url.loginAction}>{msg("doClickHere")}</a>
34
+ &nbsp;
35
+ {msg("emailVerifyInstruction3")}
36
+ </p>
37
+ </>
38
+ }
39
+ />
40
+ );
41
+ });
39
42
 
40
43
  export default LoginVerifyEmail;
@@ -1,68 +1,71 @@
1
1
  import React, { memo } from "react";
2
2
  import { useCssAndCx } from "../tools/useCssAndCx";
3
- import Template from "./Template";
3
+ import DefaultTemplate from "./Template";
4
+ import type { TemplateProps } from "./Template";
4
5
  import type { KcProps } from "./KcProps";
5
6
  import type { KcContextBase } from "../getKcContext/KcContextBase";
6
7
  import type { I18n } from "../i18n";
7
8
 
8
- const LogoutConfirm = memo(
9
- ({
10
- kcContext,
11
- i18n,
12
- doFetchDefaultThemeResources = true,
13
- ...props
14
- }: { kcContext: KcContextBase.LogoutConfirm; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
15
- const { url, client, logoutConfirm } = kcContext;
9
+ export type LogoutConfirmProps = KcProps & {
10
+ kcContext: KcContextBase.LogoutConfirm;
11
+ i18n: I18n;
12
+ doFetchDefaultThemeResources?: boolean;
13
+ Template?: (props: TemplateProps) => JSX.Element | null;
14
+ };
16
15
 
17
- const { cx } = useCssAndCx();
16
+ const LogoutConfirm = memo((props: LogoutConfirmProps) => {
17
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
18
18
 
19
- const { msg, msgStr } = i18n;
19
+ const { url, client, logoutConfirm } = kcContext;
20
20
 
21
- return (
22
- <Template
23
- {...{ kcContext, i18n, doFetchDefaultThemeResources, ...props }}
24
- displayMessage={false}
25
- headerNode={msg("logoutConfirmTitle")}
26
- formNode={
27
- <>
28
- <div id="kc-logout-confirm" className="content-area">
29
- <p className="instruction">{msg("logoutConfirmHeader")}</p>
30
- <form className="form-actions" action={url.logoutConfirmAction} method="POST">
31
- <input type="hidden" name="session_code" value={logoutConfirm.code} />
32
- <div className={cx(props.kcFormGroupClass)}>
33
- <div id="kc-form-options">
34
- <div className={cx(props.kcFormOptionsWrapperClass)}></div>
35
- </div>
36
- <div id="kc-form-buttons" className={cx(props.kcFormGroupClass)}>
37
- <input
38
- tabIndex={4}
39
- className={cx(
40
- props.kcButtonClass,
41
- props.kcButtonPrimaryClass,
42
- props.kcButtonBlockClass,
43
- props.kcButtonLargeClass
44
- )}
45
- name="confirmLogout"
46
- id="kc-logout"
47
- type="submit"
48
- value={msgStr("doLogout")}
49
- />
50
- </div>
21
+ const { cx } = useCssAndCx();
22
+
23
+ const { msg, msgStr } = i18n;
24
+
25
+ return (
26
+ <Template
27
+ {...{ kcContext, i18n, doFetchDefaultThemeResources, ...kcProps }}
28
+ displayMessage={false}
29
+ headerNode={msg("logoutConfirmTitle")}
30
+ formNode={
31
+ <>
32
+ <div id="kc-logout-confirm" className="content-area">
33
+ <p className="instruction">{msg("logoutConfirmHeader")}</p>
34
+ <form className="form-actions" action={url.logoutConfirmAction} method="POST">
35
+ <input type="hidden" name="session_code" value={logoutConfirm.code} />
36
+ <div className={cx(kcProps.kcFormGroupClass)}>
37
+ <div id="kc-form-options">
38
+ <div className={cx(kcProps.kcFormOptionsWrapperClass)}></div>
39
+ </div>
40
+ <div id="kc-form-buttons" className={cx(kcProps.kcFormGroupClass)}>
41
+ <input
42
+ tabIndex={4}
43
+ className={cx(
44
+ kcProps.kcButtonClass,
45
+ kcProps.kcButtonPrimaryClass,
46
+ kcProps.kcButtonBlockClass,
47
+ kcProps.kcButtonLargeClass
48
+ )}
49
+ name="confirmLogout"
50
+ id="kc-logout"
51
+ type="submit"
52
+ value={msgStr("doLogout")}
53
+ />
51
54
  </div>
52
- </form>
53
- <div id="kc-info-message">
54
- {!logoutConfirm.skipLink && client.baseUrl && (
55
- <p>
56
- <a href={client.baseUrl} dangerouslySetInnerHTML={{ __html: msgStr("backToApplication") }} />
57
- </p>
58
- )}
59
55
  </div>
56
+ </form>
57
+ <div id="kc-info-message">
58
+ {!logoutConfirm.skipLink && client.baseUrl && (
59
+ <p>
60
+ <a href={client.baseUrl} dangerouslySetInnerHTML={{ __html: msgStr("backToApplication") }} />
61
+ </p>
62
+ )}
60
63
  </div>
61
- </>
62
- }
63
- />
64
- );
65
- }
66
- );
64
+ </div>
65
+ </>
66
+ }
67
+ />
68
+ );
69
+ });
67
70
 
68
71
  export default LogoutConfirm;