keycloakify 6.7.2 → 6.8.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 (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 +1 -1
  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,192 +1,195 @@
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 { useCssAndCx } from "../tools/useCssAndCx";
6
7
  import type { I18n } from "../i18n";
7
8
 
8
- const LoginConfigTotp = memo(
9
- ({
10
- kcContext,
11
- i18n,
12
- doFetchDefaultThemeResources = true,
13
- ...props
14
- }: { kcContext: KcContextBase.LoginConfigTotp; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
15
- const { url, isAppInitiatedAction, totp, mode, messagesPerField } = kcContext;
9
+ export type LoginConfigTotpProps = KcProps & {
10
+ kcContext: KcContextBase.LoginConfigTotp;
11
+ i18n: I18n;
12
+ doFetchDefaultThemeResources?: boolean;
13
+ Template?: (props: TemplateProps) => JSX.Element | null;
14
+ };
16
15
 
17
- const { cx } = useCssAndCx();
16
+ const LoginConfigTotp = memo((props: LoginConfigTotpProps) => {
17
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
18
18
 
19
- const { msg, msgStr } = i18n;
19
+ const { url, isAppInitiatedAction, totp, mode, messagesPerField } = kcContext;
20
20
 
21
- const algToKeyUriAlg: Record<KcContextBase.LoginConfigTotp["totp"]["policy"]["algorithm"], string> = {
22
- HmacSHA1: "SHA1",
23
- HmacSHA256: "SHA256",
24
- HmacSHA512: "SHA512"
25
- };
21
+ const { cx } = useCssAndCx();
26
22
 
27
- return (
28
- <Template
29
- {...{ kcContext, i18n, doFetchDefaultThemeResources, ...props }}
30
- headerNode={msg("loginTotpTitle")}
31
- formNode={
32
- <>
33
- <ol id="kc-totp-settings">
34
- <li>
35
- <p>{msg("loginTotpStep1")}</p>
23
+ const { msg, msgStr } = i18n;
36
24
 
37
- <ul id="kc-totp-supported-apps">
38
- {totp.policy.supportedApplications.map(app => (
39
- <li>{app}</li>
40
- ))}
41
- </ul>
42
- </li>
25
+ const algToKeyUriAlg: Record<KcContextBase.LoginConfigTotp["totp"]["policy"]["algorithm"], string> = {
26
+ "HmacSHA1": "SHA1",
27
+ "HmacSHA256": "SHA256",
28
+ "HmacSHA512": "SHA512"
29
+ };
43
30
 
44
- {mode && mode == "manual" ? (
45
- <>
46
- <li>
47
- <p>{msg("loginTotpManualStep2")}</p>
48
- <p>
49
- <span id="kc-totp-secret-key">{totp.totpSecretEncoded}</span>
50
- </p>
51
- <p>
52
- <a href={totp.qrUrl} id="mode-barcode">
53
- {msg("loginTotpScanBarcode")}
54
- </a>
55
- </p>
56
- </li>
57
- <li>
58
- <p>{msg("loginTotpManualStep3")}</p>
59
- <p>
60
- <ul>
61
- <li id="kc-totp-type">
62
- {msg("loginTotpType")}: {msg(`loginTotp.${totp.policy.type}`)}
63
- </li>
64
- <li id="kc-totp-algorithm">
65
- {msg("loginTotpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
66
- </li>
67
- <li id="kc-totp-digits">
68
- {msg("loginTotpDigits")}: {totp.policy.digits}
69
- </li>
70
- {totp.policy.type === "totp" ? (
71
- <li id="kc-totp-period">
72
- {msg("loginTotpInterval")}: {totp.policy.period}
73
- </li>
74
- ) : (
75
- <li id="kc-totp-counter">
76
- {msg("loginTotpCounter")}: {totp.policy.initialCounter}
77
- </li>
78
- )}
79
- </ul>
80
- </p>
81
- </li>
82
- </>
83
- ) : (
31
+ return (
32
+ <Template
33
+ {...{ kcContext, i18n, doFetchDefaultThemeResources, ...kcProps }}
34
+ headerNode={msg("loginTotpTitle")}
35
+ formNode={
36
+ <>
37
+ <ol id="kc-totp-settings">
38
+ <li>
39
+ <p>{msg("loginTotpStep1")}</p>
40
+
41
+ <ul id="kc-totp-supported-apps">
42
+ {totp.policy.supportedApplications.map(app => (
43
+ <li>{app}</li>
44
+ ))}
45
+ </ul>
46
+ </li>
47
+
48
+ {mode && mode == "manual" ? (
49
+ <>
84
50
  <li>
85
- <p>{msg("loginTotpStep2")}</p>
86
- <img id="kc-totp-secret-qr-code" src={`data:image/png;base64, ${totp.totpSecretQrCode}`} alt="Figure: Barcode" />
87
- <br />
51
+ <p>{msg("loginTotpManualStep2")}</p>
88
52
  <p>
89
- <a href={totp.manualUrl} id="mode-manual">
90
- {msg("loginTotpUnableToScan")}
53
+ <span id="kc-totp-secret-key">{totp.totpSecretEncoded}</span>
54
+ </p>
55
+ <p>
56
+ <a href={totp.qrUrl} id="mode-barcode">
57
+ {msg("loginTotpScanBarcode")}
91
58
  </a>
92
59
  </p>
93
60
  </li>
94
- )}
61
+ <li>
62
+ <p>{msg("loginTotpManualStep3")}</p>
63
+ <p>
64
+ <ul>
65
+ <li id="kc-totp-type">
66
+ {msg("loginTotpType")}: {msg(`loginTotp.${totp.policy.type}`)}
67
+ </li>
68
+ <li id="kc-totp-algorithm">
69
+ {msg("loginTotpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
70
+ </li>
71
+ <li id="kc-totp-digits">
72
+ {msg("loginTotpDigits")}: {totp.policy.digits}
73
+ </li>
74
+ {totp.policy.type === "totp" ? (
75
+ <li id="kc-totp-period">
76
+ {msg("loginTotpInterval")}: {totp.policy.period}
77
+ </li>
78
+ ) : (
79
+ <li id="kc-totp-counter">
80
+ {msg("loginTotpCounter")}: {totp.policy.initialCounter}
81
+ </li>
82
+ )}
83
+ </ul>
84
+ </p>
85
+ </li>
86
+ </>
87
+ ) : (
95
88
  <li>
96
- <p>{msg("loginTotpStep3")}</p>
97
- <p>{msg("loginTotpStep3DeviceName")}</p>
89
+ <p>{msg("loginTotpStep2")}</p>
90
+ <img id="kc-totp-secret-qr-code" src={`data:image/png;base64, ${totp.totpSecretQrCode}`} alt="Figure: Barcode" />
91
+ <br />
92
+ <p>
93
+ <a href={totp.manualUrl} id="mode-manual">
94
+ {msg("loginTotpUnableToScan")}
95
+ </a>
96
+ </p>
98
97
  </li>
99
- </ol>
98
+ )}
99
+ <li>
100
+ <p>{msg("loginTotpStep3")}</p>
101
+ <p>{msg("loginTotpStep3DeviceName")}</p>
102
+ </li>
103
+ </ol>
100
104
 
101
- <form action={url.loginAction} className={cx(props.kcFormClass)} id="kc-totp-settings-form" method="post">
102
- <div className={cx(props.kcFormGroupClass)}>
103
- <div className={cx(props.kcInputWrapperClass)}>
104
- <label htmlFor="totp" className={cx(props.kcLabelClass)}>
105
- {msg("authenticatorCode")}
106
- </label>{" "}
107
- <span className="required">*</span>
108
- </div>
109
- <div className={cx(props.kcInputWrapperClass)}>
110
- <input
111
- type="text"
112
- id="totp"
113
- name="totp"
114
- autoComplete="off"
115
- className={cx(props.kcInputClass)}
116
- aria-invalid={messagesPerField.existsError("totp")}
117
- />
105
+ <form action={url.loginAction} className={cx(kcProps.kcFormClass)} id="kc-totp-settings-form" method="post">
106
+ <div className={cx(kcProps.kcFormGroupClass)}>
107
+ <div className={cx(kcProps.kcInputWrapperClass)}>
108
+ <label htmlFor="totp" className={cx(kcProps.kcLabelClass)}>
109
+ {msg("authenticatorCode")}
110
+ </label>{" "}
111
+ <span className="required">*</span>
112
+ </div>
113
+ <div className={cx(kcProps.kcInputWrapperClass)}>
114
+ <input
115
+ type="text"
116
+ id="totp"
117
+ name="totp"
118
+ autoComplete="off"
119
+ className={cx(kcProps.kcInputClass)}
120
+ aria-invalid={messagesPerField.existsError("totp")}
121
+ />
118
122
 
119
- {messagesPerField.existsError("totp") && (
120
- <span id="input-error-otp-code" className={cx(props.kcInputErrorMessageClass)} aria-live="polite">
121
- {messagesPerField.get("totp")}
122
- </span>
123
- )}
124
- </div>
125
- <input type="hidden" id="totpSecret" name="totpSecret" value={totp.totpSecret} />
126
- {mode && <input type="hidden" id="mode" value={mode} />}
123
+ {messagesPerField.existsError("totp") && (
124
+ <span id="input-error-otp-code" className={cx(kcProps.kcInputErrorMessageClass)} aria-live="polite">
125
+ {messagesPerField.get("totp")}
126
+ </span>
127
+ )}
127
128
  </div>
129
+ <input type="hidden" id="totpSecret" name="totpSecret" value={totp.totpSecret} />
130
+ {mode && <input type="hidden" id="mode" value={mode} />}
131
+ </div>
128
132
 
129
- <div className={cx(props.kcFormGroupClass)}>
130
- <div className={cx(props.kcInputWrapperClass)}>
131
- <label htmlFor="userLabel" className={cx(props.kcLabelClass)}>
132
- {msg("loginTotpDeviceName")}
133
- </label>{" "}
134
- {totp.otpCredentials.length >= 1 && <span className="required">*</span>}
135
- </div>
136
- <div className={cx(props.kcInputWrapperClass)}>
137
- <input
138
- type="text"
139
- id="userLabel"
140
- name="userLabel"
141
- autoComplete="off"
142
- className={cx(props.kcInputClass)}
143
- aria-invalid={messagesPerField.existsError("userLabel")}
144
- />
145
- {messagesPerField.existsError("userLabel") && (
146
- <span id="input-error-otp-label" className={cx(props.kcInputErrorMessageClass)} aria-live="polite">
147
- {messagesPerField.get("userLabel")}
148
- </span>
149
- )}
150
- </div>
133
+ <div className={cx(kcProps.kcFormGroupClass)}>
134
+ <div className={cx(kcProps.kcInputWrapperClass)}>
135
+ <label htmlFor="userLabel" className={cx(kcProps.kcLabelClass)}>
136
+ {msg("loginTotpDeviceName")}
137
+ </label>{" "}
138
+ {totp.otpCredentials.length >= 1 && <span className="required">*</span>}
139
+ </div>
140
+ <div className={cx(kcProps.kcInputWrapperClass)}>
141
+ <input
142
+ type="text"
143
+ id="userLabel"
144
+ name="userLabel"
145
+ autoComplete="off"
146
+ className={cx(kcProps.kcInputClass)}
147
+ aria-invalid={messagesPerField.existsError("userLabel")}
148
+ />
149
+ {messagesPerField.existsError("userLabel") && (
150
+ <span id="input-error-otp-label" className={cx(kcProps.kcInputErrorMessageClass)} aria-live="polite">
151
+ {messagesPerField.get("userLabel")}
152
+ </span>
153
+ )}
151
154
  </div>
155
+ </div>
152
156
 
153
- {isAppInitiatedAction ? (
154
- <>
155
- <input
156
- type="submit"
157
- className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonLargeClass)}
158
- id="saveTOTPBtn"
159
- value={msgStr("doSubmit")}
160
- />
161
- <button
162
- type="submit"
163
- className={cx(
164
- props.kcButtonClass,
165
- props.kcButtonDefaultClass,
166
- props.kcButtonLargeClass,
167
- props.kcButtonLargeClass
168
- )}
169
- id="cancelTOTPBtn"
170
- name="cancel-aia"
171
- value="true"
172
- >
173
- ${msg("doCancel")}
174
- </button>
175
- </>
176
- ) : (
157
+ {isAppInitiatedAction ? (
158
+ <>
177
159
  <input
178
160
  type="submit"
179
- className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonLargeClass)}
161
+ className={cx(kcProps.kcButtonClass, kcProps.kcButtonPrimaryClass, kcProps.kcButtonLargeClass)}
180
162
  id="saveTOTPBtn"
181
163
  value={msgStr("doSubmit")}
182
164
  />
183
- )}
184
- </form>
185
- </>
186
- }
187
- />
188
- );
189
- }
190
- );
165
+ <button
166
+ type="submit"
167
+ className={cx(
168
+ kcProps.kcButtonClass,
169
+ kcProps.kcButtonDefaultClass,
170
+ kcProps.kcButtonLargeClass,
171
+ kcProps.kcButtonLargeClass
172
+ )}
173
+ id="cancelTOTPBtn"
174
+ name="cancel-aia"
175
+ value="true"
176
+ >
177
+ ${msg("doCancel")}
178
+ </button>
179
+ </>
180
+ ) : (
181
+ <input
182
+ type="submit"
183
+ className={cx(kcProps.kcButtonClass, kcProps.kcButtonPrimaryClass, kcProps.kcButtonLargeClass)}
184
+ id="saveTOTPBtn"
185
+ value={msgStr("doSubmit")}
186
+ />
187
+ )}
188
+ </form>
189
+ </>
190
+ }
191
+ />
192
+ );
193
+ });
191
194
 
192
195
  export default LoginConfigTotp;
@@ -1,54 +1,67 @@
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 { useCssAndCx } from "../tools/useCssAndCx";
6
7
  import type { I18n } from "../i18n";
7
8
 
8
- const LoginIdpLinkConfirm = memo(
9
- ({
10
- kcContext,
11
- i18n,
12
- doFetchDefaultThemeResources = true,
13
- ...props
14
- }: { kcContext: KcContextBase.LoginIdpLinkConfirm; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
15
- const { url, idpAlias } = kcContext;
9
+ export type LoginIdpLinkConfirmProps = KcProps & {
10
+ kcContext: KcContextBase.LoginIdpLinkConfirm;
11
+ i18n: I18n;
12
+ doFetchDefaultThemeResources?: boolean;
13
+ Template?: (props: TemplateProps) => JSX.Element | null;
14
+ };
16
15
 
17
- const { msg } = i18n;
16
+ const LoginIdpLinkConfirm = memo((props: LoginIdpLinkConfirmProps) => {
17
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
18
18
 
19
- const { cx } = useCssAndCx();
19
+ const { url, idpAlias } = kcContext;
20
20
 
21
- return (
22
- <Template
23
- {...{ kcContext, i18n, doFetchDefaultThemeResources, ...props }}
24
- headerNode={msg("confirmLinkIdpTitle")}
25
- formNode={
26
- <form id="kc-register-form" action={url.loginAction} method="post">
27
- <div className={cx(props.kcFormGroupClass)}>
28
- <button
29
- type="submit"
30
- className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
31
- name="submitAction"
32
- id="updateProfile"
33
- value="updateProfile"
34
- >
35
- {msg("confirmLinkIdpReviewProfile")}
36
- </button>
37
- <button
38
- type="submit"
39
- className={cx(props.kcButtonClass, props.kcButtonDefaultClass, props.kcButtonBlockClass, props.kcButtonLargeClass)}
40
- name="submitAction"
41
- id="linkAccount"
42
- value="linkAccount"
43
- >
44
- {msg("confirmLinkIdpContinue", idpAlias)}
45
- </button>
46
- </div>
47
- </form>
48
- }
49
- />
50
- );
51
- }
52
- );
21
+ const { msg } = i18n;
22
+
23
+ const { cx } = useCssAndCx();
24
+
25
+ return (
26
+ <Template
27
+ {...{ kcContext, i18n, doFetchDefaultThemeResources, ...kcProps }}
28
+ headerNode={msg("confirmLinkIdpTitle")}
29
+ formNode={
30
+ <form id="kc-register-form" action={url.loginAction} method="post">
31
+ <div className={cx(kcProps.kcFormGroupClass)}>
32
+ <button
33
+ type="submit"
34
+ className={cx(
35
+ kcProps.kcButtonClass,
36
+ kcProps.kcButtonDefaultClass,
37
+ kcProps.kcButtonBlockClass,
38
+ kcProps.kcButtonLargeClass
39
+ )}
40
+ name="submitAction"
41
+ id="updateProfile"
42
+ value="updateProfile"
43
+ >
44
+ {msg("confirmLinkIdpReviewProfile")}
45
+ </button>
46
+ <button
47
+ type="submit"
48
+ className={cx(
49
+ kcProps.kcButtonClass,
50
+ kcProps.kcButtonDefaultClass,
51
+ kcProps.kcButtonBlockClass,
52
+ kcProps.kcButtonLargeClass
53
+ )}
54
+ name="submitAction"
55
+ id="linkAccount"
56
+ value="linkAccount"
57
+ >
58
+ {msg("confirmLinkIdpContinue", idpAlias)}
59
+ </button>
60
+ </div>
61
+ </form>
62
+ }
63
+ />
64
+ );
65
+ });
53
66
 
54
67
  export default LoginIdpLinkConfirm;
@@ -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 LoginIdpLinkEmail = memo(
8
- ({
9
- kcContext,
10
- i18n,
11
- doFetchDefaultThemeResources = true,
12
- ...props
13
- }: { kcContext: KcContextBase.LoginIdpLinkEmail; i18n: I18n; doFetchDefaultThemeResources?: boolean } & KcProps) => {
14
- const { url, realm, brokerContext, idpAlias } = kcContext;
8
+ export type LoginIdpLinkEmailProps = KcProps & {
9
+ kcContext: KcContextBase.LoginIdpLinkEmail;
10
+ i18n: I18n;
11
+ doFetchDefaultThemeResources?: boolean;
12
+ Template?: (props: TemplateProps) => JSX.Element | null;
13
+ };
15
14
 
16
- const { msg } = i18n;
15
+ const LoginIdpLinkEmail = memo((props: LoginIdpLinkEmailProps) => {
16
+ const { kcContext, i18n, doFetchDefaultThemeResources = true, Template = DefaultTemplate, ...kcProps } = props;
17
17
 
18
- return (
19
- <Template
20
- {...{ kcContext, i18n, doFetchDefaultThemeResources, ...props }}
21
- headerNode={msg("emailLinkIdpTitle", idpAlias)}
22
- formNode={
23
- <>
24
- <p id="instruction1" className="instruction">
25
- {msg("emailLinkIdp1", idpAlias, brokerContext.username, realm.displayName)}
26
- </p>
27
- <p id="instruction2" className="instruction">
28
- {msg("emailLinkIdp2")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp3")}
29
- </p>
30
- <p id="instruction3" className="instruction">
31
- {msg("emailLinkIdp4")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp5")}
32
- </p>
33
- </>
34
- }
35
- />
36
- );
37
- }
38
- );
18
+ const { url, realm, brokerContext, idpAlias } = kcContext;
19
+
20
+ const { msg } = i18n;
21
+
22
+ return (
23
+ <Template
24
+ {...{ kcContext, i18n, doFetchDefaultThemeResources, ...kcProps }}
25
+ headerNode={msg("emailLinkIdpTitle", idpAlias)}
26
+ formNode={
27
+ <>
28
+ <p id="instruction1" className="instruction">
29
+ {msg("emailLinkIdp1", idpAlias, brokerContext.username, realm.displayName)}
30
+ </p>
31
+ <p id="instruction2" className="instruction">
32
+ {msg("emailLinkIdp2")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp3")}
33
+ </p>
34
+ <p id="instruction3" className="instruction">
35
+ {msg("emailLinkIdp4")} <a href={url.loginAction}>{msg("doClickHere")}</a> {msg("emailLinkIdp5")}
36
+ </p>
37
+ </>
38
+ }
39
+ />
40
+ );
41
+ });
39
42
 
40
43
  export default LoginIdpLinkEmail;