@keycloakify/angular 0.0.11 → 0.1.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 (61) hide show
  1. package/bin/108.index.js +242 -0
  2. package/bin/338.index.js +104 -54
  3. package/bin/402.index.js +1250 -0
  4. package/bin/758.index.js +777 -53
  5. package/bin/{925.index.js → 84.index.js} +124 -624
  6. package/bin/main.js +59 -4
  7. package/package.json +1 -1
  8. package/src/bin/add-story.ts +126 -0
  9. package/src/bin/eject-page.ts +49 -11
  10. package/src/bin/initialize-account-theme/boilerplate/KcContextMock.ts +47 -1
  11. package/src/bin/main.ts +2 -4
  12. package/src/bin/tools/nodeModulesBinDirPath.ts +38 -0
  13. package/src/bin/tools/runPrettier.ts +89 -0
  14. package/src/bin/tools/transformCodebase_async.ts +89 -0
  15. package/src/bin/update-kc-gen.ts +20 -15
  16. package/stories/account/pages/account.stories.ts +133 -0
  17. package/stories/account/pages/applications.stories.ts +196 -0
  18. package/stories/account/pages/federated-identity.stories.ts +78 -0
  19. package/stories/account/pages/log.stories.ts +147 -0
  20. package/stories/account/pages/password.stories.ts +104 -0
  21. package/stories/account/pages/sessions.stories.ts +143 -0
  22. package/stories/account/pages/totp.stories.ts +100 -0
  23. package/stories/login/pages/code.stories.ts +51 -0
  24. package/stories/login/pages/delete-account-confirm.stories.ts +43 -0
  25. package/stories/login/pages/delete-credential.stories.ts +56 -0
  26. package/stories/login/pages/error.stories.ts +56 -0
  27. package/stories/login/pages/frontchannel-logout.stories.ts +26 -0
  28. package/stories/login/pages/idp-review-user-profile.stories.ts +60 -0
  29. package/stories/login/pages/info.stories.ts +94 -0
  30. package/stories/login/pages/login-config-totp.stories.ts +57 -0
  31. package/stories/login/pages/login-device-verify-user-code.stories.ts +14 -0
  32. package/stories/login/pages/login-idp-link-confirm-override.stories.ts +17 -0
  33. package/stories/login/pages/login-idp-link-confirm.stories.ts +103 -0
  34. package/stories/login/pages/login-idp-link-email.stories.ts +102 -0
  35. package/stories/login/pages/login-oauth-grant.stories.ts +68 -0
  36. package/stories/login/pages/login-oauth2-device-verify-user-code.stories.ts +15 -0
  37. package/stories/login/pages/login-otp.stories.ts +94 -0
  38. package/stories/login/pages/login-page-expired.stories.ts +31 -0
  39. package/stories/login/pages/login-passkeys-conditional-authenticate.stories.ts +16 -0
  40. package/stories/login/pages/login-password.stories.ts +52 -0
  41. package/stories/login/pages/login-recovery-authn-code-config.stories.ts +31 -0
  42. package/stories/login/pages/login-recovery-authn-code-input.stories.ts +16 -0
  43. package/stories/login/pages/login-reset-otp.stories.ts +71 -0
  44. package/stories/login/pages/login-reset-password.stories.ts +50 -0
  45. package/stories/login/pages/login-update-password.stories.ts +46 -0
  46. package/stories/login/pages/login-update-profile.stories.ts +31 -0
  47. package/stories/login/pages/login-username.stories.ts +28 -0
  48. package/stories/login/pages/login-verify-email.stories.ts +98 -0
  49. package/stories/login/pages/login-x509-info.stories.ts +40 -0
  50. package/stories/login/pages/login.stories.ts +260 -0
  51. package/stories/login/pages/logout-confirm.stories.ts +44 -0
  52. package/stories/login/pages/register.stories.ts +230 -0
  53. package/stories/login/pages/saml-post-form.stories.ts +17 -0
  54. package/stories/login/pages/select-authenticator.stories.ts +95 -0
  55. package/stories/login/pages/terms.stories.ts +79 -0
  56. package/stories/login/pages/update-email.stories.ts +31 -0
  57. package/stories/login/pages/webauthn-authenticate.stories.ts +126 -0
  58. package/stories/login/pages/webauthn-error.stories.ts +62 -0
  59. package/stories/login/pages/webauthn-register.stories.ts +46 -0
  60. package/src/bin/tools/runFormat.ts +0 -71
  61. package/src/stories/login/pages/login/login.stories.ts +0 -146
@@ -0,0 +1,143 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'account/sessions.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'sessions.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+
15
+ type Story = StoryObj<KcPageStory>;
16
+
17
+ export const Default: Story = {
18
+ globals: {
19
+ overrides: {
20
+ sessions: {
21
+ sessions: [
22
+ {
23
+ expires: '2024-04-26T18:14:19Z',
24
+ clients: ['account'],
25
+ ipAddress: '172.20.0.1',
26
+ started: '2024-04-26T08:14:19Z',
27
+ lastAccess: '2024-04-26T08:30:54Z',
28
+ id: 'af835e30-4821-43b1-b4f7-e732d3cc15d2'
29
+ },
30
+ {
31
+ expires: '2024-04-26T18:14:09Z',
32
+ clients: ['security-admin-console', 'account'],
33
+ ipAddress: '172.20.0.1',
34
+ started: '2024-04-26T08:14:09Z',
35
+ lastAccess: '2024-04-26T08:15:14Z',
36
+ id: '60a9d8b8-617d-441e-8643-08c3fe30e231'
37
+ }
38
+ ]
39
+ },
40
+ stateChecker: 'xQ7EOgFrLi4EvnJ8dbXKhwFGWk_bkOp0X89mhilt1os'
41
+ }
42
+ }
43
+ };
44
+
45
+ export const WithError: Story = {
46
+ globals: {
47
+ overrides: {
48
+ url: { passwordUrl: '/auth/realms/keycloakify/account/password' },
49
+ stateChecker: 'xQ7EOgFrLi4EvnJ8dbXKhwFGWk_bkOp0X89mhilt1os',
50
+ message: {
51
+ summary: 'Invalid existing password.',
52
+ type: 'error'
53
+ }
54
+ }
55
+ }
56
+ };
57
+
58
+ /**
59
+ * No active sessions scenario:
60
+ * - Simulates the scenario where no sessions are active for the user.
61
+ */
62
+ export const NoActiveSessions: Story = {
63
+ globals: {
64
+ overrides: {
65
+ sessions: {
66
+ sessions: []
67
+ },
68
+ stateChecker: 'randomStateCheckerValue'
69
+ }
70
+ }
71
+ };
72
+
73
+ /**
74
+ * Single session scenario:
75
+ * - Displays only one active session with session details.
76
+ */
77
+ export const SingleSession: Story = {
78
+ globals: {
79
+ overrides: {
80
+ sessions: {
81
+ sessions: [
82
+ {
83
+ expires: '2024-04-26T18:14:19Z',
84
+ clients: ['account'],
85
+ ipAddress: '172.20.0.1',
86
+ started: '2024-04-26T08:14:19Z',
87
+ lastAccess: '2024-04-26T08:30:54Z',
88
+ id: 'single-session-id'
89
+ }
90
+ ]
91
+ },
92
+ stateChecker: 'anotherStateChecker'
93
+ }
94
+ }
95
+ };
96
+
97
+ /**
98
+ * Multiple clients per session scenario:
99
+ * - Displays sessions where each session has multiple associated clients.
100
+ */
101
+ export const MultipleClientsSession: Story = {
102
+ globals: {
103
+ overrides: {
104
+ sessions: {
105
+ sessions: [
106
+ {
107
+ expires: '2024-04-26T18:14:19Z',
108
+ clients: ['account', 'admin-console', 'another-client'],
109
+ ipAddress: '172.20.0.1',
110
+ started: '2024-04-26T08:14:19Z',
111
+ lastAccess: '2024-04-26T08:30:54Z',
112
+ id: 'multiple-clients-session'
113
+ }
114
+ ]
115
+ },
116
+ stateChecker: 'multiClientsStateChecker'
117
+ }
118
+ }
119
+ };
120
+
121
+ /**
122
+ * Session without client details scenario:
123
+ * - Simulates a session where no client information is provided.
124
+ */
125
+ export const SessionWithoutClients: Story = {
126
+ globals: {
127
+ overrides: {
128
+ sessions: {
129
+ sessions: [
130
+ {
131
+ expires: '2024-04-26T18:14:19Z',
132
+ clients: [], // No clients information
133
+ ipAddress: '172.20.0.1',
134
+ started: '2024-04-26T08:14:19Z',
135
+ lastAccess: '2024-04-26T08:30:54Z',
136
+ id: 'no-clients-session'
137
+ }
138
+ ]
139
+ },
140
+ stateChecker: 'noClientsStateChecker'
141
+ }
142
+ }
143
+ };
@@ -0,0 +1,100 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'account/totp.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'totp.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+
15
+ type Story = StoryObj<KcPageStory>;
16
+
17
+ export const Default: Story = {
18
+ globals: {
19
+ overrides: {
20
+ totp: {
21
+ enabled: false,
22
+ totpSecretEncoded: 'HE4W MSTC OBKU CY2M ONXF OV3Q NYYU I3SH',
23
+ totpSecret: '99fJbpUAcLsnWWpn1DnG',
24
+ manualUrl:
25
+ 'http://localhost:8080/realms/myrealm/account/totp?mode=manual',
26
+ totpSecretQrCode:
27
+ 'iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACk0lEQVR4Xu2YQY6DMAxFjViw5AjcBC6GBBIXozfJEbpkger53wEKqOpmFvaikQYNeVRyHPvbiejXscp95jp+/D5zHT9+n7kO8qeIFDqKzjJo9dC1wUSPP7yG4IPq41lq9ZK+keLZSwXDGwMhOCZgdX4sBVD1qld+GYg/h6ScreBuIDo5FKfVM7Z8aWs9PB2E2/73DdOlwUrK9Ck+HDnzB7ziR8fjlD/OPI8pVQwCi899TkNw2M+tp9XSLFKPIq2UySIhBB906fCQTicFwiv1EUG6+d+bl4zPIYnUk5oIcS69/evPYStUp6P0dJhD/mhauijcth76mOsfw+GFrbfXKJx7LW2N15kijuWIMCYicLQOCEimDp1c0L8PzCLTs3/d+ZQLyl6VqeSIT9nz25szf2ZybHgC31yrXEQIbqaPjX0k9GqWy0N/nLkagsHWNXR0LZwsR357c0pjC6fm+meu5f6f6oszz/qj7GpYCdHf0LVH/gTgtJ/5bVavPJ9svwnBS9qaqwoHOh3G7Ln++HIIDgpKYpFW00dlkX7ruz836THBWQpzd23/xeDsFVroz15fRjsfMyaC8JX2Y8PZf+VIoKff+uTO6WSIUIfSkrl9/rbfnbPr30R8hnMtXA/98ea5lx4ZlSMgQlMsEnb73XnP+yNl/SuR3/lzTSZHMTirMpMcXjWr0U5Mp/rnzmk/TsXkC2/iKEJ5TRG4DZ5KrP/C0RiVmkp+5I8zN1uh2vv9Vs+bzJ4947Y+bz6wl6ZIcv87ZaU2+6PwnoKdb7VYmrf9Z02MxCmNdmparbVJtrA4nA+e9LgIS6dzfvly7j+4XWIuPJp8iE9PbvkzJHYNabt/o5MP+535t/Hj95nr+PH7zHX8m/8B+RAnloz5pi4AAAAASUVORK5CYII=',
28
+ policy: {
29
+ type: 'totp'
30
+ },
31
+ qrUrl: 'http://localhost:8080/realms/myrealm/account/totp?mode=qr',
32
+ otpCredentials: []
33
+ },
34
+ messagesPerField: {},
35
+ stateChecker: 'ihTeSAMfNsobnPjYiktV8DY-5T4sVzVdrEZRdwfMm8Y',
36
+ realm: {
37
+ userManagedAccessAllowed: true,
38
+ internationalizationEnabled: false
39
+ },
40
+ url: {
41
+ totpUrl: 'http://localhost:8080/realms/myrealm/account/totp'
42
+ },
43
+ keycloakifyVersion: '9.6.1',
44
+ themeVersion: '1.0.10',
45
+ themeType: 'account',
46
+ themeName: 'keycloakify',
47
+ pageId: 'totp.ftl'
48
+ }
49
+ }
50
+ };
51
+
52
+ export const WithTotpEnabled: Story = {
53
+ globals: {
54
+ overrides: {
55
+ totp: {
56
+ enabled: true,
57
+ totpSecretEncoded: 'G55E MZKC JFUD MQLT MFIF EVSB JFLG M6SO',
58
+ totpSecret: '7zFeBIh6AsaPRVAIVfzN',
59
+ manualUrl:
60
+ 'http://localhost:8080/realms/myrealm/account/totp?mode=manual',
61
+ supportedApplications: [
62
+ 'totpAppFreeOTPName',
63
+ 'totpAppMicrosoftAuthenticatorName',
64
+ 'totpAppGoogleName'
65
+ ],
66
+ totpSecretQrCode:
67
+ 'iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACo0lEQVR4Xu2YPY6DMBCFJ6JwyRF8k+RiSCBxsXATjkDpAmX2vTGBwErbbDFTZIps4s8rmfl9RvRPW+W6crYvv66c7cuvK2cjX0Tkho9yW/q5PHSc5QYA62PwXnWqmzrRSUdNL+mygRC8kzQZWhqVO1CRds3YHopnfUkzp2c7ZAY+GIdXywOb0qsdJMXiFn9serYrncxNv/PDkdfUzObk/eNaX368mnl1kML8RH1vFoGzargA1DM/VeWhOpf9+by5iL5Q0NaEUETslHiSIz+dOc4q0tqBrcg7IsnpnZ8BeLmjqjFa4Fps4vlR3484nFHH6OP8o1cTc4I/Q3D4Uqw1TjpkeHqc2R/Rjvb89OUUDAL/CpycOf/o6fUjP505/phrOf8wn+tolsxyD8GZnzyrJSScrNyEcXhHJwrBh2yj2fShPlFB2PQxn935aK1HIB1G1nczm8+P+nbmC7si+zell53a4i97fnhz5Gddxc9iSgLPpPifGn9vDqN0YBL0lpozdx7nd+dDHSiFXkV+NlZO85Efzvzda8yrwkylvlEbhxE4bTJpiCEIkWNHbxD/w/++fJMOVX8p5Q70F0V2EI4LsUWd+ov6Wtgu5aM/OXNIf6jWbKq6zmekA77t88WZr5lXO6vvWaj6kbNo4nv/ceaon0TpYPqrmNJhue/x9+ZKLchbO+cLPrb+aI09BLeob1en2nqkKsUYfOvatSGa/ircmD7i78rNmJoYzXwIKh228z3+ztzef+Cb6S/lSxoWOXM2CO/ZuvlqARtLvX8u1Ie6+d+bd/X9pdS3lrrF/8jPCPytv9AVIbfvddxE4iNFLKL+hH/xCNudKgTvGX/r33ars/y062gQjljfWN8cyKm+f2NPOvqTL//Lvvy6crYvv66c7d/8B/9RFjk6Tp30AAAAAElFTkSuQmCC',
68
+ policy: {
69
+ type: 'totp',
70
+ algorithm: 'HmacSHA1'
71
+ },
72
+ qrUrl: 'http://localhost:8080/realms/myrealm/account/totp?mode=qr',
73
+ otpCredentials: [
74
+ {
75
+ id: '7afaaf7d-f2d5-44f5-a966-e5297f0b2b7a',
76
+ userLabel: 'mobile'
77
+ }
78
+ ]
79
+ },
80
+ message: {
81
+ summary: 'Mobile authenticator configured.',
82
+ type: 'success'
83
+ },
84
+ url: {
85
+ totpUrl: 'http://localhost:8080/realms/myrealm/account/totp'
86
+ },
87
+ messagesPerField: {},
88
+ stateChecker: '0UvyCNJHRJXmdahtRmn0tTPCU2nwLtWBUfPwpJ8Ohkw',
89
+ realm: {
90
+ userManagedAccessAllowed: true,
91
+ internationalizationEnabled: false
92
+ },
93
+ keycloakifyVersion: '9.6.1',
94
+ themeVersion: '1.0.10',
95
+ themeType: 'account',
96
+ themeName: 'keycloakify',
97
+ pageId: 'totp.ftl'
98
+ }
99
+ }
100
+ };
@@ -0,0 +1,51 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/code.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'code.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithErrorCode: Story = {
19
+ globals: {
20
+ overrides: {
21
+ code: {
22
+ success: false,
23
+ error: 'Failed to generate code'
24
+ }
25
+ }
26
+ }
27
+ };
28
+ export const WithFrenchLanguage: Story = {
29
+ globals: {
30
+ overrides: {
31
+ locale: {
32
+ currentLanguageTag: 'fr'
33
+ },
34
+ code: {
35
+ success: true,
36
+ code: 'XYZ789'
37
+ }
38
+ }
39
+ }
40
+ };
41
+
42
+ export const WithHtmlErrorMessage: Story = {
43
+ globals: {
44
+ overrides: {
45
+ code: {
46
+ success: false,
47
+ error: "Something went wrong. <a href='https://example.com'>Try again</a>"
48
+ }
49
+ }
50
+ }
51
+ };
@@ -0,0 +1,43 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/delete-account-confirm.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'delete-account-confirm.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithAIAFlow: Story = {
19
+ globals: {
20
+ overrides: {
21
+ triggered_from_aia: true,
22
+ url: { loginAction: '/login-action' }
23
+ }
24
+ }
25
+ };
26
+
27
+ export const WithoutAIAFlow: Story = {
28
+ globals: {
29
+ overrides: {
30
+ triggered_from_aia: false,
31
+ url: { loginAction: '/login-action' }
32
+ }
33
+ }
34
+ };
35
+
36
+ export const WithCustomButtonStyle: Story = {
37
+ globals: {
38
+ overrides: {
39
+ triggered_from_aia: true,
40
+ url: { loginAction: '/login-action' }
41
+ }
42
+ }
43
+ };
@@ -0,0 +1,56 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/delete-credential.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'delete-credential.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithCustomCredentialLabel: Story = {
19
+ globals: {
20
+ overrides: {
21
+ credentialLabel: 'Test Credential',
22
+ url: { loginAction: '/login-action' }
23
+ }
24
+ }
25
+ };
26
+
27
+ export const WithSuccessMessage: Story = {
28
+ globals: {
29
+ overrides: {
30
+ message: {
31
+ type: 'success',
32
+ summary: 'Credential has been successfully deleted.'
33
+ }
34
+ }
35
+ }
36
+ };
37
+
38
+ export const WithErrorMessage: Story = {
39
+ globals: {
40
+ overrides: {
41
+ message: {
42
+ type: 'error',
43
+ summary: 'Failed to delete the credential. Please try again.'
44
+ }
45
+ }
46
+ }
47
+ };
48
+
49
+ export const WithDisabledDeleteButton: Story = {
50
+ globals: {
51
+ overrides: {
52
+ isDeleteButtonDisabled: true,
53
+ credentialLabel: 'Non-deletable Credential'
54
+ }
55
+ }
56
+ };
@@ -0,0 +1,56 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/error.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'error.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithAnotherMessage: Story = {
19
+ globals: {
20
+ overrides: {
21
+ message: { summary: 'With another error message' }
22
+ }
23
+ }
24
+ };
25
+
26
+ export const WithHtmlErrorMessage: Story = {
27
+ globals: {
28
+ overrides: {
29
+ message: {
30
+ summary:
31
+ "<strong>Error:</strong> Something went wrong. <a href='https://example.com'>Go back</a>"
32
+ }
33
+ }
34
+ }
35
+ };
36
+
37
+ export const FrenchError: Story = {
38
+ globals: {
39
+ overrides: {
40
+ locale: { currentLanguageTag: 'fr' },
41
+ message: { summary: "Une erreur s'est produite" }
42
+ }
43
+ }
44
+ };
45
+
46
+ export const WithSkipLink: Story = {
47
+ globals: {
48
+ overrides: {
49
+ message: { summary: 'An error occurred' },
50
+ skipLink: true,
51
+ client: {
52
+ baseUrl: 'https://example.com'
53
+ }
54
+ }
55
+ }
56
+ };
@@ -0,0 +1,26 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/frontchannel-logout.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'frontchannel-logout.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithoutRedirectUrl: Story = {
19
+ globals: {
20
+ overrides: {
21
+ logout: {
22
+ clients: []
23
+ }
24
+ }
25
+ }
26
+ };
@@ -0,0 +1,60 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/idp-review-user-profile.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'idp-review-user-profile.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+
15
+ type Story = StoryObj<KcPageStory>;
16
+
17
+ export const Default: Story = {};
18
+
19
+ export const WithFormValidationErrors: Story = {
20
+ globals: {
21
+ overrides: {
22
+ messagesPerField: {
23
+ existsError: (fieldName: string) =>
24
+ ['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
+ return '';
29
+ }
30
+ }
31
+ }
32
+ }
33
+ };
34
+
35
+ export const WithReadOnlyFields: Story = {
36
+ globals: {
37
+ overrides: {
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
+ globals: {
50
+ overrides: {
51
+ profile: {
52
+ attributesByName: {
53
+ firstName: { value: 'Jane' },
54
+ lastName: { value: 'Doe' },
55
+ email: { value: 'jane.doe@example.com' }
56
+ }
57
+ }
58
+ }
59
+ }
60
+ };
@@ -0,0 +1,94 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/info.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'info.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {
17
+ globals: {
18
+ overrides: {
19
+ message: {
20
+ summary: 'Server info message'
21
+ }
22
+ }
23
+ }
24
+ };
25
+
26
+ export const WithLinkBack: Story = {
27
+ globals: {
28
+ overrides: {
29
+ message: {
30
+ summary: 'Server message'
31
+ },
32
+ actionUri: undefined
33
+ }
34
+ }
35
+ };
36
+
37
+ export const WithRequiredActions: Story = {
38
+ globals: {
39
+ overrides: {
40
+ message: {
41
+ summary: 'Required actions: '
42
+ },
43
+ requiredActions: [
44
+ 'CONFIGURE_TOTP',
45
+ 'UPDATE_PROFILE',
46
+ 'VERIFY_EMAIL',
47
+ 'CUSTOM_ACTION'
48
+ ],
49
+ 'x-keycloakify': {
50
+ messages: {
51
+ 'requiredAction.CUSTOM_ACTION': 'Custom action'
52
+ }
53
+ }
54
+ }
55
+ }
56
+ };
57
+
58
+ export const WithPageRedirect: Story = {
59
+ globals: {
60
+ overrides: {
61
+ message: { summary: 'You will be redirected shortly.' },
62
+ pageRedirectUri: 'https://example.com'
63
+ }
64
+ }
65
+ };
66
+
67
+ export const WithoutClientBaseUrl: Story = {
68
+ globals: {
69
+ overrides: {
70
+ message: { summary: 'No client base URL defined.' },
71
+ client: { baseUrl: undefined }
72
+ }
73
+ }
74
+ };
75
+
76
+ export const WithMessageHeader: Story = {
77
+ globals: {
78
+ overrides: {
79
+ messageHeader: 'Important Notice',
80
+ message: { summary: 'This is an important message.' }
81
+ }
82
+ }
83
+ };
84
+
85
+ export const WithAdvancedMessage: Story = {
86
+ globals: {
87
+ overrides: {
88
+ message: {
89
+ summary:
90
+ 'Please take note of this <strong>important</strong> information.'
91
+ }
92
+ }
93
+ }
94
+ };
@@ -0,0 +1,57 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-config-totp.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-config-totp.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithManualSetUp: Story = {
19
+ globals: {
20
+ overrides: {
21
+ mode: 'manual'
22
+ }
23
+ }
24
+ };
25
+
26
+ export const WithError: Story = {
27
+ globals: {
28
+ overrides: {
29
+ messagesPerField: {
30
+ get: (fieldName: string) =>
31
+ fieldName === 'totp' ? 'Invalid TOTP' : undefined,
32
+ exists: (fieldName: string) => fieldName === 'totp',
33
+ existsError: (fieldName: string) => fieldName === 'totp',
34
+ printIfExists: <T>(fieldName: string, x: T) =>
35
+ fieldName === 'totp' ? x : undefined
36
+ }
37
+ }
38
+ }
39
+ };
40
+
41
+ export const WithAppInitiatedAction: Story = {
42
+ globals: {
43
+ overrides: {
44
+ isAppInitiatedAction: true
45
+ }
46
+ }
47
+ };
48
+
49
+ export const WithPreFilledUserLabel: Story = {
50
+ globals: {
51
+ overrides: {
52
+ totp: {
53
+ otpCredentials: [{ userLabel: 'MyDevice' }]
54
+ }
55
+ }
56
+ }
57
+ };