keycloakify 11.3.3 → 11.3.4

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.
package/README.md CHANGED
@@ -141,6 +141,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
141
141
  <td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/oes-rioniz/"><img src="https://avatars.githubusercontent.com/u/5172296?v=4?s=100" width="100px;" alt="Omid"/><br /><sub><b>Omid</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=uchar" title="Tests">⚠️</a> <a href="https://github.com/keycloakify/keycloakify/commits?author=uchar" title="Code">💻</a></td>
142
142
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/kathari00"><img src="https://avatars.githubusercontent.com/u/42547712?v=4?s=100" width="100px;" alt="Katharina Eiserfey"/><br /><sub><b>Katharina Eiserfey</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=kathari00" title="Code">💻</a> <a href="https://github.com/keycloakify/keycloakify/commits?author=kathari00" title="Tests">⚠️</a> <a href="https://github.com/keycloakify/keycloakify/commits?author=kathari00" title="Documentation">📖</a></td>
143
143
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/luca-peruzzo"><img src="https://avatars.githubusercontent.com/u/69015314?v=4?s=100" width="100px;" alt="Luca Peruzzo"/><br /><sub><b>Luca Peruzzo</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=luca-peruzzo" title="Code">💻</a> <a href="https://github.com/keycloakify/keycloakify/commits?author=luca-peruzzo" title="Tests">⚠️</a></td>
144
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/nima70"><img src="https://avatars.githubusercontent.com/u/5094767?v=4?s=100" width="100px;" alt="Nima Shokouhfar"/><br /><sub><b>Nima Shokouhfar</b></sub></a><br /><a href="https://github.com/keycloakify/keycloakify/commits?author=nima70" title="Code">💻</a> <a href="https://github.com/keycloakify/keycloakify/commits?author=nima70" title="Tests">⚠️</a></td>
144
145
  </tr>
145
146
  </tbody>
146
147
  </table>
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { getKcClsx } from "../../login/lib/kcClsx";
3
+ import { kcSanitize } from "../../lib/kcSanitize";
3
4
  export default function Code(props) {
4
5
  const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
5
6
  const { kcClsx } = getKcClsx({
@@ -8,6 +9,8 @@ export default function Code(props) {
8
9
  });
9
10
  const { code } = kcContext;
10
11
  const { msg } = i18n;
11
- return (_jsx(Template, Object.assign({ kcContext: kcContext, i18n: i18n, doUseDefaultCss: doUseDefaultCss, classes: classes, headerNode: code.success ? msg("codeSuccessTitle") : msg("codeErrorTitle", code.error) }, { children: _jsx("div", Object.assign({ id: "kc-code" }, { children: code.success ? (_jsxs(_Fragment, { children: [_jsx("p", { children: msg("copyCodeInstruction") }), _jsx("input", { id: "code", className: kcClsx("kcTextareaClass"), defaultValue: code.code })] })) : (_jsx("p", Object.assign({ id: "error" }, { children: code.error }))) })) })));
12
+ return (_jsx(Template, Object.assign({ kcContext: kcContext, i18n: i18n, doUseDefaultCss: doUseDefaultCss, classes: classes, headerNode: code.success ? msg("codeSuccessTitle") : msg("codeErrorTitle", code.error) }, { children: _jsx("div", Object.assign({ id: "kc-code" }, { children: code.success ? (_jsxs(_Fragment, { children: [_jsx("p", { children: msg("copyCodeInstruction") }), _jsx("input", { id: "code", className: kcClsx("kcTextareaClass"), defaultValue: code.code })] })) : (code.error && (_jsx("p", { id: "error", dangerouslySetInnerHTML: {
13
+ __html: kcSanitize(code.error)
14
+ } }))) })) })));
12
15
  }
13
16
  //# sourceMappingURL=Code.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Code.js","sourceRoot":"","sources":["../../src/login/pages/Code.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAKzD,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAkE;IAC3F,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAEtE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACzB,eAAe;QACf,OAAO;KACV,CAAC,CAAC;IAEH,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAE3B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErB,OAAO,CACH,KAAC,QAAQ,kBACL,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAEtF,4BAAK,EAAE,EAAC,SAAS,gBACZ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CACZ,8BACI,sBAAI,GAAG,CAAC,qBAAqB,CAAC,GAAK,EACnC,gBAAO,EAAE,EAAC,MAAM,EAAC,SAAS,EAAE,MAAM,CAAC,iBAAiB,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,GAAI,IACnF,CACN,CAAC,CAAC,CAAC,CACA,0BAAG,EAAE,EAAC,OAAO,gBAAE,IAAI,CAAC,KAAK,IAAK,CACjC,IACC,IACC,CACd,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"Code.js","sourceRoot":"","sources":["../../src/login/pages/Code.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAIzD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,KAAkE;IAC3F,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAEtE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QACzB,eAAe;QACf,OAAO;KACV,CAAC,CAAC;IAEH,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAE3B,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAErB,OAAO,CACH,KAAC,QAAQ,kBACL,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAEtF,4BAAK,EAAE,EAAC,SAAS,gBACZ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CACZ,8BACI,sBAAI,GAAG,CAAC,qBAAqB,CAAC,GAAK,EACnC,gBAAO,EAAE,EAAC,MAAM,EAAC,SAAS,EAAE,MAAM,CAAC,iBAAiB,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,GAAI,IACnF,CACN,CAAC,CAAC,CAAC,CACA,IAAI,CAAC,KAAK,IAAI,CACV,YACI,EAAE,EAAC,OAAO,EACV,uBAAuB,EAAE;oBACrB,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;iBACjC,GACH,CACL,CACJ,IACC,IACC,CACd,CAAC;AACN,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keycloakify",
3
- "version": "11.3.3",
3
+ "version": "11.3.4",
4
4
  "description": "Framework to create custom Keycloak UIs",
5
5
  "repository": {
6
6
  "type": "git",
@@ -2,6 +2,7 @@ import { getKcClsx } from "keycloakify/login/lib/kcClsx";
2
2
  import type { PageProps } from "keycloakify/login/pages/PageProps";
3
3
  import type { KcContext } from "../KcContext";
4
4
  import type { I18n } from "../i18n";
5
+ import { kcSanitize } from "keycloakify/lib/kcSanitize";
5
6
 
6
7
  export default function Code(props: PageProps<Extract<KcContext, { pageId: "code.ftl" }>, I18n>) {
7
8
  const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
@@ -30,7 +31,14 @@ export default function Code(props: PageProps<Extract<KcContext, { pageId: "code
30
31
  <input id="code" className={kcClsx("kcTextareaClass")} defaultValue={code.code} />
31
32
  </>
32
33
  ) : (
33
- <p id="error">{code.error}</p>
34
+ code.error && (
35
+ <p
36
+ id="error"
37
+ dangerouslySetInnerHTML={{
38
+ __html: kcSanitize(code.error)
39
+ }}
40
+ />
41
+ )
34
42
  )}
35
43
  </div>
36
44
  </Template>
@@ -16,3 +16,42 @@ type Story = StoryObj<typeof meta>;
16
16
  export const Default: Story = {
17
17
  render: () => <KcPageStory />
18
18
  };
19
+ export const WithErrorCode: Story = {
20
+ render: () => (
21
+ <KcPageStory
22
+ kcContext={{
23
+ code: {
24
+ success: false,
25
+ error: "Failed to generate code"
26
+ }
27
+ }}
28
+ />
29
+ )
30
+ };
31
+ export const WithFrenchLanguage: Story = {
32
+ render: () => (
33
+ <KcPageStory
34
+ kcContext={{
35
+ locale: {
36
+ currentLanguageTag: "fr"
37
+ },
38
+ code: {
39
+ success: true,
40
+ code: "XYZ789"
41
+ }
42
+ }}
43
+ />
44
+ )
45
+ };
46
+ export const WithHtmlErrorMessage: Story = {
47
+ render: () => (
48
+ <KcPageStory
49
+ kcContext={{
50
+ code: {
51
+ success: false,
52
+ error: "Something went wrong. <a href='https://example.com'>Try again</a>"
53
+ }
54
+ }}
55
+ />
56
+ )
57
+ };
@@ -16,3 +16,33 @@ type Story = StoryObj<typeof meta>;
16
16
  export const Default: Story = {
17
17
  render: () => <KcPageStory />
18
18
  };
19
+ export const WithAIAFlow: Story = {
20
+ render: () => (
21
+ <KcPageStory
22
+ kcContext={{
23
+ triggered_from_aia: true,
24
+ url: { loginAction: "/login-action" }
25
+ }}
26
+ />
27
+ )
28
+ };
29
+ export const WithoutAIAFlow: Story = {
30
+ render: () => (
31
+ <KcPageStory
32
+ kcContext={{
33
+ triggered_from_aia: false,
34
+ url: { loginAction: "/login-action" }
35
+ }}
36
+ />
37
+ )
38
+ };
39
+ export const WithCustomButtonStyle: Story = {
40
+ render: () => (
41
+ <KcPageStory
42
+ kcContext={{
43
+ triggered_from_aia: true,
44
+ url: { loginAction: "/login-action" }
45
+ }}
46
+ />
47
+ )
48
+ };
@@ -16,3 +16,13 @@ type Story = StoryObj<typeof meta>;
16
16
  export const Default: Story = {
17
17
  render: () => <KcPageStory />
18
18
  };
19
+ export const WithCustomCredentialLabel: Story = {
20
+ render: () => (
21
+ <KcPageStory
22
+ kcContext={{
23
+ credentialLabel: "Test Credential",
24
+ url: { loginAction: "/login-action" }
25
+ }}
26
+ />
27
+ )
28
+ };
@@ -26,3 +26,38 @@ export const WithAnotherMessage: Story = {
26
26
  />
27
27
  )
28
28
  };
29
+
30
+ export const WithHtmlErrorMessage: Story = {
31
+ render: () => (
32
+ <KcPageStory
33
+ kcContext={{
34
+ message: {
35
+ summary: "<strong>Error:</strong> Something went wrong. <a href='https://example.com'>Go back</a>"
36
+ }
37
+ }}
38
+ />
39
+ )
40
+ };
41
+ export const FrenchError: Story = {
42
+ render: () => (
43
+ <KcPageStory
44
+ kcContext={{
45
+ locale: { currentLanguageTag: "fr" },
46
+ message: { summary: "Une erreur s'est produite" }
47
+ }}
48
+ />
49
+ )
50
+ };
51
+ export const WithSkipLink: Story = {
52
+ render: () => (
53
+ <KcPageStory
54
+ kcContext={{
55
+ message: { summary: "An error occurred" },
56
+ skipLink: true,
57
+ client: {
58
+ baseUrl: "https://example.com"
59
+ }
60
+ }}
61
+ />
62
+ )
63
+ };
@@ -16,3 +16,14 @@ type Story = StoryObj<typeof meta>;
16
16
  export const Default: Story = {
17
17
  render: () => <KcPageStory />
18
18
  };
19
+ export const WithoutRedirectUrl: Story = {
20
+ render: () => (
21
+ <KcPageStory
22
+ kcContext={{
23
+ logout: {
24
+ clients: []
25
+ }
26
+ }}
27
+ />
28
+ )
29
+ };
@@ -16,3 +16,47 @@ type Story = StoryObj<typeof meta>;
16
16
  export const Default: Story = {
17
17
  render: () => <KcPageStory />
18
18
  };
19
+ export const WithFormValidationErrors: Story = {
20
+ render: () => (
21
+ <KcPageStory
22
+ kcContext={{
23
+ messagesPerField: {
24
+ existsError: (fieldName: string) => ["email", "firstName"].includes(fieldName),
25
+ get: (fieldName: string) => {
26
+ if (fieldName === "email") return "Invalid email format.";
27
+ if (fieldName === "firstName") return "First name is required.";
28
+ }
29
+ }
30
+ }}
31
+ />
32
+ )
33
+ };
34
+ export const WithReadOnlyFields: Story = {
35
+ render: () => (
36
+ <KcPageStory
37
+ kcContext={{
38
+ profile: {
39
+ attributesByName: {
40
+ email: { value: "jane.doe@example.com", readOnly: true },
41
+ firstName: { value: "Jane", readOnly: false }
42
+ }
43
+ }
44
+ }}
45
+ />
46
+ )
47
+ };
48
+ export const WithPrefilledFormFields: Story = {
49
+ render: () => (
50
+ <KcPageStory
51
+ kcContext={{
52
+ profile: {
53
+ attributesByName: {
54
+ firstName: { value: "Jane" },
55
+ lastName: { value: "Doe" },
56
+ email: { value: "jane.doe@example.com" }
57
+ }
58
+ }
59
+ }}
60
+ />
61
+ )
62
+ };
@@ -55,3 +55,42 @@ export const WithRequiredActions: Story = {
55
55
  />
56
56
  )
57
57
  };
58
+ export const WithPageRedirect: Story = {
59
+ render: () => (
60
+ <KcPageStory
61
+ kcContext={{
62
+ message: { summary: "You will be redirected shortly." },
63
+ pageRedirectUri: "https://example.com"
64
+ }}
65
+ />
66
+ )
67
+ };
68
+ export const WithoutClientBaseUrl: Story = {
69
+ render: () => (
70
+ <KcPageStory
71
+ kcContext={{
72
+ message: { summary: "No client base URL defined." },
73
+ client: { baseUrl: undefined }
74
+ }}
75
+ />
76
+ )
77
+ };
78
+ export const WithMessageHeader: Story = {
79
+ render: () => (
80
+ <KcPageStory
81
+ kcContext={{
82
+ messageHeader: "Important Notice",
83
+ message: { summary: "This is an important message." }
84
+ }}
85
+ />
86
+ )
87
+ };
88
+ export const WithAdvancedMessage: Story = {
89
+ render: () => (
90
+ <KcPageStory
91
+ kcContext={{
92
+ message: { summary: "Please take note of this <strong>important</strong> information." }
93
+ }}
94
+ />
95
+ )
96
+ };
@@ -231,3 +231,131 @@ export const WithErrorMessage: Story = {
231
231
  />
232
232
  )
233
233
  };
234
+
235
+ export const WithOneSocialProvider: Story = {
236
+ render: args => (
237
+ <KcPageStory
238
+ {...args}
239
+ kcContext={{
240
+ social: {
241
+ displayInfo: true,
242
+ providers: [
243
+ {
244
+ loginUrl: "google",
245
+ alias: "google",
246
+ providerId: "google",
247
+ displayName: "Google",
248
+ iconClasses: "fa fa-google"
249
+ }
250
+ ]
251
+ }
252
+ }}
253
+ />
254
+ )
255
+ };
256
+
257
+ export const WithTwoSocialProviders: Story = {
258
+ render: args => (
259
+ <KcPageStory
260
+ {...args}
261
+ kcContext={{
262
+ social: {
263
+ displayInfo: true,
264
+ providers: [
265
+ {
266
+ loginUrl: "google",
267
+ alias: "google",
268
+ providerId: "google",
269
+ displayName: "Google",
270
+ iconClasses: "fa fa-google"
271
+ },
272
+ {
273
+ loginUrl: "microsoft",
274
+ alias: "microsoft",
275
+ providerId: "microsoft",
276
+ displayName: "Microsoft",
277
+ iconClasses: "fa fa-windows"
278
+ }
279
+ ]
280
+ }
281
+ }}
282
+ />
283
+ )
284
+ };
285
+ export const WithNoSocialProviders: Story = {
286
+ render: args => (
287
+ <KcPageStory
288
+ {...args}
289
+ kcContext={{
290
+ social: {
291
+ displayInfo: true,
292
+ providers: []
293
+ }
294
+ }}
295
+ />
296
+ )
297
+ };
298
+ export const WithMoreThanTwoSocialProviders: Story = {
299
+ render: args => (
300
+ <KcPageStory
301
+ {...args}
302
+ kcContext={{
303
+ social: {
304
+ displayInfo: true,
305
+ providers: [
306
+ {
307
+ loginUrl: "google",
308
+ alias: "google",
309
+ providerId: "google",
310
+ displayName: "Google",
311
+ iconClasses: "fa fa-google"
312
+ },
313
+ {
314
+ loginUrl: "microsoft",
315
+ alias: "microsoft",
316
+ providerId: "microsoft",
317
+ displayName: "Microsoft",
318
+ iconClasses: "fa fa-windows"
319
+ },
320
+ {
321
+ loginUrl: "facebook",
322
+ alias: "facebook",
323
+ providerId: "facebook",
324
+ displayName: "Facebook",
325
+ iconClasses: "fa fa-facebook"
326
+ },
327
+ {
328
+ loginUrl: "twitter",
329
+ alias: "twitter",
330
+ providerId: "twitter",
331
+ displayName: "Twitter",
332
+ iconClasses: "fa fa-twitter"
333
+ }
334
+ ]
335
+ }
336
+ }}
337
+ />
338
+ )
339
+ };
340
+ export const WithSocialProvidersAndWithoutRememberMe: Story = {
341
+ render: args => (
342
+ <KcPageStory
343
+ {...args}
344
+ kcContext={{
345
+ social: {
346
+ displayInfo: true,
347
+ providers: [
348
+ {
349
+ loginUrl: "google",
350
+ alias: "google",
351
+ providerId: "google",
352
+ displayName: "Google",
353
+ iconClasses: "fa fa-google"
354
+ }
355
+ ]
356
+ },
357
+ realm: { rememberMe: false }
358
+ }}
359
+ />
360
+ )
361
+ };
@@ -41,3 +41,24 @@ export const WithError: Story = {
41
41
  />
42
42
  )
43
43
  };
44
+ export const WithAppInitiatedAction: Story = {
45
+ render: () => (
46
+ <KcPageStory
47
+ kcContext={{
48
+ isAppInitiatedAction: true
49
+ }}
50
+ />
51
+ )
52
+ };
53
+
54
+ export const WithPreFilledUserLabel: Story = {
55
+ render: () => (
56
+ <KcPageStory
57
+ kcContext={{
58
+ totp: {
59
+ otpCredentials: [{ userLabel: "MyDevice" }]
60
+ }
61
+ }}
62
+ />
63
+ )
64
+ };
@@ -16,3 +16,49 @@ type Story = StoryObj<typeof meta>;
16
16
  export const Default: Story = {
17
17
  render: () => <KcPageStory />
18
18
  };
19
+ export const WithIdpAlias: Story = {
20
+ render: () => (
21
+ <KcPageStory
22
+ kcContext={{
23
+ idpAlias: "Google",
24
+ brokerContext: {
25
+ username: "john.doe"
26
+ },
27
+ realm: {
28
+ displayName: "MyRealm"
29
+ }
30
+ }}
31
+ />
32
+ )
33
+ };
34
+ export const WithoutIdpAlias: Story = {
35
+ render: () => (
36
+ <KcPageStory
37
+ kcContext={{
38
+ idpAlias: undefined,
39
+ brokerContext: {
40
+ username: "john.doe"
41
+ },
42
+ realm: {
43
+ displayName: "MyRealm"
44
+ }
45
+ }}
46
+ />
47
+ )
48
+ };
49
+
50
+ export const WithCustomRealmDisplayName: Story = {
51
+ render: () => (
52
+ <KcPageStory
53
+ kcContext={{
54
+ idpAlias: "Facebook",
55
+ brokerContext: {
56
+ username: "jane.doe"
57
+ },
58
+ realm: {
59
+ displayName: "CustomRealm"
60
+ }
61
+ }}
62
+ />
63
+ )
64
+ };
@@ -215,3 +215,65 @@ export const WithTermsAcceptance: Story = {
215
215
  />
216
216
  )
217
217
  };
218
+ export const WithTermsNotAccepted: Story = {
219
+ render: args => (
220
+ <KcPageStory
221
+ {...args}
222
+ kcContext={{
223
+ termsAcceptanceRequired: true,
224
+ messagesPerField: {
225
+ existsError: (fieldName: string) => fieldName === "termsAccepted",
226
+ get: (fieldName: string) => (fieldName === "termsAccepted" ? "You must accept the terms." : undefined)
227
+ }
228
+ }}
229
+ />
230
+ )
231
+ };
232
+ export const WithFieldErrors: Story = {
233
+ render: () => (
234
+ <KcPageStory
235
+ kcContext={{
236
+ profile: {
237
+ attributesByName: {
238
+ username: { value: "" },
239
+ email: { value: "invalid-email" }
240
+ }
241
+ },
242
+ messagesPerField: {
243
+ existsError: fieldName => ["username", "email"].includes(fieldName),
244
+ get: fieldName => {
245
+ if (fieldName === "username") return "Username is required.";
246
+ if (fieldName === "email") return "Invalid email format.";
247
+ }
248
+ }
249
+ }}
250
+ />
251
+ )
252
+ };
253
+ export const WithReadOnlyFields: Story = {
254
+ render: () => (
255
+ <KcPageStory
256
+ kcContext={{
257
+ profile: {
258
+ attributesByName: {
259
+ username: { value: "johndoe", readOnly: true },
260
+ email: { value: "jhon.doe@gmail.com", readOnly: false }
261
+ }
262
+ }
263
+ }}
264
+ />
265
+ )
266
+ };
267
+ export const WithAutoGeneratedUsername: Story = {
268
+ render: () => (
269
+ <KcPageStory
270
+ kcContext={{
271
+ profile: {
272
+ attributesByName: {
273
+ username: { value: "autogenerated_username" }
274
+ }
275
+ }
276
+ }}
277
+ />
278
+ )
279
+ };
@@ -45,3 +45,32 @@ export const French: Story = {
45
45
  />
46
46
  )
47
47
  };
48
+ export const WithErrorMessage: Story = {
49
+ render: () => (
50
+ <KcPageStory
51
+ kcContext={{
52
+ messagesPerField: {
53
+ existsError: () => true,
54
+ get: () => "An error occurred while processing your request."
55
+ }
56
+ }}
57
+ />
58
+ )
59
+ };
60
+
61
+ export const Spanish: Story = {
62
+ render: () => (
63
+ <KcPageStory
64
+ kcContext={{
65
+ locale: {
66
+ currentLanguageTag: "es"
67
+ },
68
+ "x-keycloakify": {
69
+ messages: {
70
+ termsText: "<p>Mis términos en <strong>Español</strong></p>"
71
+ }
72
+ }
73
+ }}
74
+ />
75
+ )
76
+ };