@keycloakify/angular 0.0.11 → 0.1.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 (60) 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/main.ts +2 -4
  11. package/src/bin/tools/nodeModulesBinDirPath.ts +38 -0
  12. package/src/bin/tools/runPrettier.ts +89 -0
  13. package/src/bin/tools/transformCodebase_async.ts +89 -0
  14. package/src/bin/update-kc-gen.ts +20 -15
  15. package/stories/account/pages/account.stories.ts +133 -0
  16. package/stories/account/pages/applications.stories.ts +196 -0
  17. package/stories/account/pages/federated-identity.stories.ts +78 -0
  18. package/stories/account/pages/log.stories.ts +147 -0
  19. package/stories/account/pages/password.stories.ts +104 -0
  20. package/stories/account/pages/sessions.stories.ts +143 -0
  21. package/stories/account/pages/totp.stories.ts +100 -0
  22. package/stories/login/pages/code.stories.ts +51 -0
  23. package/stories/login/pages/delete-account-confirm.stories.ts +43 -0
  24. package/stories/login/pages/delete-credential.stories.ts +56 -0
  25. package/stories/login/pages/error.stories.ts +56 -0
  26. package/stories/login/pages/frontchannel-logout.stories.ts +26 -0
  27. package/stories/login/pages/idp-review-user-profile.stories.ts +60 -0
  28. package/stories/login/pages/info.stories.ts +94 -0
  29. package/stories/login/pages/login-config-totp.stories.ts +57 -0
  30. package/stories/login/pages/login-device-verify-user-code.stories.ts +14 -0
  31. package/stories/login/pages/login-idp-link-confirm-override.stories.ts +17 -0
  32. package/stories/login/pages/login-idp-link-confirm.stories.ts +103 -0
  33. package/stories/login/pages/login-idp-link-email.stories.ts +102 -0
  34. package/stories/login/pages/login-oauth-grant.stories.ts +68 -0
  35. package/stories/login/pages/login-oauth2-device-verify-user-code.stories.ts +15 -0
  36. package/stories/login/pages/login-otp.stories.ts +94 -0
  37. package/stories/login/pages/login-page-expired.stories.ts +31 -0
  38. package/stories/login/pages/login-passkeys-conditional-authenticate.stories.ts +16 -0
  39. package/stories/login/pages/login-password.stories.ts +52 -0
  40. package/stories/login/pages/login-recovery-authn-code-config.stories.ts +31 -0
  41. package/stories/login/pages/login-recovery-authn-code-input.stories.ts +16 -0
  42. package/stories/login/pages/login-reset-otp.stories.ts +71 -0
  43. package/stories/login/pages/login-reset-password.stories.ts +50 -0
  44. package/stories/login/pages/login-update-password.stories.ts +46 -0
  45. package/stories/login/pages/login-update-profile.stories.ts +31 -0
  46. package/stories/login/pages/login-username.stories.ts +28 -0
  47. package/stories/login/pages/login-verify-email.stories.ts +98 -0
  48. package/stories/login/pages/login-x509-info.stories.ts +40 -0
  49. package/stories/login/pages/login.stories.ts +260 -0
  50. package/stories/login/pages/logout-confirm.stories.ts +44 -0
  51. package/stories/login/pages/register.stories.ts +230 -0
  52. package/stories/login/pages/saml-post-form.stories.ts +17 -0
  53. package/stories/login/pages/select-authenticator.stories.ts +95 -0
  54. package/stories/login/pages/terms.stories.ts +79 -0
  55. package/stories/login/pages/update-email.stories.ts +31 -0
  56. package/stories/login/pages/webauthn-authenticate.stories.ts +126 -0
  57. package/stories/login/pages/webauthn-error.stories.ts +62 -0
  58. package/stories/login/pages/webauthn-register.stories.ts +46 -0
  59. package/src/bin/tools/runFormat.ts +0 -71
  60. package/src/stories/login/pages/login/login.stories.ts +0 -146
@@ -0,0 +1,14 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-device-verify-user-code.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators
8
+ };
9
+
10
+ export default meta;
11
+
12
+ type Story = StoryObj<KcPageStory>;
13
+
14
+ export const Default: Story = {};
@@ -0,0 +1,17 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-idp-link-confirm-override.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-idp-link-confirm-override.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+
15
+ type Story = StoryObj<KcPageStory>;
16
+
17
+ export const Default: Story = {};
@@ -0,0 +1,103 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ // Mock kcContext to avoid errors
5
+ const mockKcContext = {
6
+ url: {
7
+ loginAction: '/login-action'
8
+ },
9
+ idpAlias: 'mockIdpAlias',
10
+ brokerContext: {
11
+ username: 'mockUser'
12
+ },
13
+ realm: {
14
+ displayName: 'MockRealm'
15
+ }
16
+ };
17
+
18
+ const meta: Meta<KcPageStory> = {
19
+ title: 'login/login-idp-link-confirm.ftl',
20
+ component: KcPageStory,
21
+ decorators: decorators,
22
+ globals: {
23
+ pageId: 'login-idp-link-confirm.ftl',
24
+ overrides: {
25
+ kcContext: mockKcContext
26
+ }
27
+ }
28
+ };
29
+
30
+ export default meta;
31
+
32
+ type Story = StoryObj<KcPageStory>;
33
+
34
+ /**
35
+ * Default:
36
+ * - Purpose: Tests the default behavior with mock data.
37
+ * - Scenario: The component renders with a mocked identity provider alias (`mockIdpAlias`), a default broker username (`mockUser`), and a default realm name (`MockRealm`).
38
+ * - Key Aspect: Ensures the default behavior of the component with typical kcContext values.
39
+ */
40
+ export const Default: Story = {};
41
+
42
+ /**
43
+ * WithIdpAlias:
44
+ * - Purpose: Tests behavior when the idpAlias is set to "Google".
45
+ * - Scenario: Simulates the component being used with a Google identity provider, showing the username "john.doe" and realm "MyRealm".
46
+ * - Key Aspect: Ensures the correct identity provider alias ("Google") and broker context (user info) are displayed in the email linking instructions.
47
+ */
48
+ export const WithIdpAlias: Story = {
49
+ globals: {
50
+ overrides: {
51
+ ...mockKcContext,
52
+ idpAlias: 'Google',
53
+ brokerContext: {
54
+ username: 'john.doe'
55
+ },
56
+ realm: {
57
+ displayName: 'MyRealm'
58
+ }
59
+ }
60
+ }
61
+ };
62
+
63
+ /**
64
+ * WithCustomRealmDisplayName:
65
+ * - Purpose: Tests behavior when the realm display name is customized.
66
+ * - Scenario: Simulates the component with a Facebook identity provider, a broker username "jane.doe", and a custom realm name "CustomRealm".
67
+ * - Key Aspect: Ensures that custom realm display names are rendered correctly alongside the idpAlias and broker context.
68
+ */
69
+ export const WithCustomRealmDisplayName: Story = {
70
+ globals: {
71
+ overrides: {
72
+ ...mockKcContext,
73
+ idpAlias: 'Facebook',
74
+ brokerContext: {
75
+ username: 'jane.doe'
76
+ },
77
+ realm: {
78
+ displayName: 'CUSTOM REALM DISPLAY NAME'
79
+ }
80
+ }
81
+ }
82
+ };
83
+
84
+ /**
85
+ * WithFormSubmissionError:
86
+ * - Purpose: Tests how the component handles form submission errors.
87
+ * - Scenario: Simulates a form submission error by setting the login action URL to `/error` and displays an error message.
88
+ * - Key Aspect: Verifies that the component can display error messages during form submission failure, ensuring proper error handling.
89
+ */
90
+ export const WithFormSubmissionError: Story = {
91
+ globals: {
92
+ overrides: {
93
+ ...mockKcContext,
94
+ url: {
95
+ loginAction: '/error'
96
+ },
97
+ message: {
98
+ type: 'error',
99
+ summary: 'An error occurred during form submission.'
100
+ }
101
+ }
102
+ }
103
+ };
@@ -0,0 +1,102 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const mockKcContext = {
5
+ url: {
6
+ loginAction: '/login-action'
7
+ },
8
+ idpAlias: 'mockIdpAlias',
9
+ brokerContext: {
10
+ username: 'mockUser'
11
+ },
12
+ realm: {
13
+ displayName: 'MockRealm'
14
+ }
15
+ };
16
+
17
+ const meta: Meta<KcPageStory> = {
18
+ title: 'login/login-idp-link-email.ftl',
19
+ component: KcPageStory,
20
+ decorators: decorators,
21
+ globals: {
22
+ pageId: 'login-idp-link-email.ftl',
23
+ overrides: {
24
+ mockKcContext
25
+ }
26
+ }
27
+ };
28
+
29
+ export default meta;
30
+
31
+ type Story = StoryObj<KcPageStory>;
32
+
33
+ /**
34
+ * Default:
35
+ * - Purpose: Tests the default behavior with mock data.
36
+ * - Scenario: The component renders with a mocked identity provider alias (`mockIdpAlias`), a default broker username (`mockUser`), and a default realm name (`MockRealm`).
37
+ * - Key Aspect: Ensures the default behavior of the component with typical kcContext values.
38
+ */
39
+ export const Default: Story = {};
40
+
41
+ /**
42
+ * WithIdpAlias:
43
+ * - Purpose: Tests behavior when the idpAlias is set to "Google".
44
+ * - Scenario: Simulates the component being used with a Google identity provider, showing the username "john.doe" and realm "MyRealm".
45
+ * - Key Aspect: Ensures the correct identity provider alias ("Google") and broker context (user info) are displayed in the email linking instructions.
46
+ */
47
+ export const WithIdpAlias: Story = {
48
+ globals: {
49
+ overrides: {
50
+ ...mockKcContext,
51
+ idpAlias: 'Google',
52
+ brokerContext: {
53
+ username: 'john.doe'
54
+ },
55
+ realm: {
56
+ displayName: 'MyRealm'
57
+ }
58
+ }
59
+ }
60
+ };
61
+
62
+ /**
63
+ * WithCustomRealmDisplayName:
64
+ * - Purpose: Tests behavior when the realm display name is customized.
65
+ * - Scenario: Simulates the component with a Facebook identity provider, a broker username "jane.doe", and a custom realm name "CustomRealm".
66
+ * - Key Aspect: Ensures that custom realm display names are rendered correctly alongside the idpAlias and broker context.
67
+ */
68
+ export const WithCustomRealmDisplayName: Story = {
69
+ globals: {
70
+ overrides: {
71
+ ...mockKcContext,
72
+ idpAlias: 'Facebook',
73
+ brokerContext: {
74
+ username: 'jane.doe'
75
+ },
76
+ realm: {
77
+ displayName: 'CUSTOM REALM DISPLAY NAME'
78
+ }
79
+ }
80
+ }
81
+ };
82
+
83
+ /**
84
+ * WithFormSubmissionError:
85
+ * - Purpose: Tests how the component handles form submission errors.
86
+ * - Scenario: Simulates a form submission error by setting the login action URL to `/error` and displays an error message.
87
+ * - Key Aspect: Verifies that the component can display error messages during form submission failure, ensuring proper error handling.
88
+ */
89
+ export const WithFormSubmissionError: Story = {
90
+ globals: {
91
+ overrides: {
92
+ ...mockKcContext,
93
+ url: {
94
+ loginAction: '/error'
95
+ },
96
+ message: {
97
+ type: 'error',
98
+ summary: 'An error occurred during form submission.'
99
+ }
100
+ }
101
+ }
102
+ };
@@ -0,0 +1,68 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const mockKcContext = {
5
+ url: {
6
+ oauthAction: '/oauth-action'
7
+ },
8
+ oauth: {
9
+ clientScopesRequested: [
10
+ { consentScreenText: 'Scope1', dynamicScopeParameter: 'dynamicScope1' },
11
+ { consentScreenText: 'Scope2' }
12
+ ],
13
+ code: 'mockCode'
14
+ },
15
+ client: {
16
+ attributes: {
17
+ policyUri: 'https://twitter.com/en/tos',
18
+ tosUri: 'https://twitter.com/en/privacy'
19
+ },
20
+ name: 'Twitter',
21
+ clientId: 'twitter-client-id'
22
+ }
23
+ };
24
+
25
+ const meta: Meta<KcPageStory> = {
26
+ title: 'login/login-oauth-grant.ftl',
27
+ component: KcPageStory,
28
+ decorators: decorators,
29
+ globals: {
30
+ pageId: 'login-oauth-grant.ftl'
31
+ }
32
+ };
33
+
34
+ export default meta;
35
+ type Story = StoryObj<KcPageStory>;
36
+
37
+ export const Default: Story = {
38
+ globals: {
39
+ overrides: mockKcContext
40
+ }
41
+ };
42
+
43
+ export const WithoutScopes: Story = {
44
+ globals: {
45
+ overrides: {
46
+ ...mockKcContext,
47
+ oauth: {
48
+ ...mockKcContext.oauth,
49
+ clientScopesRequested: []
50
+ }
51
+ }
52
+ }
53
+ };
54
+
55
+ export const WithFormSubmissionError: Story = {
56
+ globals: {
57
+ overrides: {
58
+ ...mockKcContext,
59
+ url: {
60
+ oauthAction: '/error'
61
+ },
62
+ message: {
63
+ type: 'error',
64
+ summary: 'An error occurred during form submission.'
65
+ }
66
+ }
67
+ }
68
+ };
@@ -0,0 +1,15 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-oauth2-device-verify-user-code.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: { pageId: 'login-oauth2-device-verify-user-code.ftl' }
9
+ };
10
+
11
+ export default meta;
12
+
13
+ type Story = StoryObj<KcPageStory>;
14
+
15
+ export const Default: Story = {};
@@ -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/login-otp.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-otp.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const MultipleOtpCredentials: Story = {
19
+ globals: {
20
+ overrides: {
21
+ otpLogin: {
22
+ userOtpCredentials: [
23
+ { id: 'credential1', userLabel: 'Device 1' },
24
+ { id: 'credential2', userLabel: 'Device 2' },
25
+ { id: 'credential2', userLabel: 'Device 3' },
26
+ { id: 'credential2', userLabel: 'Device 4' },
27
+ { id: 'credential2', userLabel: 'Device 5' },
28
+ { id: 'credential2', userLabel: 'Device 6' }
29
+ ],
30
+ selectedCredentialId: 'credential1'
31
+ },
32
+ url: {
33
+ loginAction: '/login-action'
34
+ },
35
+ messagesPerField: {
36
+ existsError: () => false
37
+ }
38
+ }
39
+ }
40
+ };
41
+
42
+ export const WithOtpError: Story = {
43
+ globals: {
44
+ overrides: {
45
+ otpLogin: {
46
+ userOtpCredentials: []
47
+ },
48
+ url: {
49
+ loginAction: '/login-action'
50
+ },
51
+ messagesPerField: {
52
+ existsError: (field: string) => field === 'totp',
53
+ get: () => 'Invalid OTP code'
54
+ }
55
+ }
56
+ }
57
+ };
58
+
59
+ export const NoOtpCredentials: Story = {
60
+ globals: {
61
+ overrides: {
62
+ otpLogin: {
63
+ userOtpCredentials: []
64
+ },
65
+ url: {
66
+ loginAction: '/login-action'
67
+ },
68
+ messagesPerField: {
69
+ existsError: () => false
70
+ }
71
+ }
72
+ }
73
+ };
74
+
75
+ export const WithErrorAndMultipleOtpCredentials: Story = {
76
+ globals: {
77
+ overrides: {
78
+ otpLogin: {
79
+ userOtpCredentials: [
80
+ { id: 'credential1', userLabel: 'Device 1' },
81
+ { id: 'credential2', userLabel: 'Device 2' }
82
+ ],
83
+ selectedCredentialId: 'credential1'
84
+ },
85
+ url: {
86
+ loginAction: '/login-action'
87
+ },
88
+ messagesPerField: {
89
+ existsError: (field: string) => field === 'totp',
90
+ get: () => 'Invalid OTP code'
91
+ }
92
+ }
93
+ }
94
+ };
@@ -0,0 +1,31 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-page-expired.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-page-expired.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithErrorMessage: Story = {
19
+ globals: {
20
+ overrides: {
21
+ url: {
22
+ loginRestartFlowUrl: '/mock-restart-flow',
23
+ loginAction: '/mock-continue-login'
24
+ },
25
+ message: {
26
+ type: 'error',
27
+ summary: 'An error occurred while processing your session.'
28
+ }
29
+ }
30
+ }
31
+ };
@@ -0,0 +1,16 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-passkeys-conditional-authenticate.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-passkeys-conditional-authenticate.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
@@ -0,0 +1,52 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-password.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-password.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+
15
+ type Story = StoryObj<KcPageStory>;
16
+
17
+ export const Default: Story = {};
18
+
19
+ export const WithPasswordError: Story = {
20
+ globals: {
21
+ overrides: {
22
+ realm: {
23
+ resetPasswordAllowed: true
24
+ },
25
+ url: {
26
+ loginAction: '/mock-login',
27
+ loginResetCredentialsUrl: '/mock-reset-password'
28
+ },
29
+ messagesPerField: {
30
+ existsError: (field: string) => field === 'password',
31
+ get: () => 'Invalid password'
32
+ }
33
+ }
34
+ }
35
+ };
36
+
37
+ export const WithoutResetPasswordOption: Story = {
38
+ globals: {
39
+ overrides: {
40
+ realm: {
41
+ resetPasswordAllowed: false
42
+ },
43
+ url: {
44
+ loginAction: '/mock-login',
45
+ loginResetCredentialsUrl: '/mock-reset-password'
46
+ },
47
+ messagesPerField: {
48
+ existsError: () => false
49
+ }
50
+ }
51
+ }
52
+ };
@@ -0,0 +1,31 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-recovery-authn-code-config.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-recovery-authn-code-config.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithErrorDuringCodeGeneration: Story = {
19
+ globals: {
20
+ overrides: {
21
+ url: {
22
+ loginAction: '/mock-login-action'
23
+ },
24
+ message: {
25
+ summary:
26
+ 'An error occurred during recovery code generation. Please try again.',
27
+ type: 'error'
28
+ }
29
+ }
30
+ }
31
+ };
@@ -0,0 +1,16 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-recovery-authn-code-input.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-recovery-authn-code-input.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
@@ -0,0 +1,71 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-reset-otp.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-reset-otp.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithoutOtpCredentials: Story = {
19
+ globals: {
20
+ overrides: {
21
+ url: {
22
+ loginAction: '/mock-login'
23
+ },
24
+ configuredOtpCredentials: {
25
+ userOtpCredentials: [],
26
+ selectedCredentialId: undefined
27
+ },
28
+ messagesPerField: {
29
+ existsError: () => false
30
+ }
31
+ }
32
+ }
33
+ };
34
+
35
+ export const WithOtpError: Story = {
36
+ globals: {
37
+ overrides: {
38
+ url: {
39
+ loginAction: '/mock-login'
40
+ },
41
+ configuredOtpCredentials: {
42
+ userOtpCredentials: [
43
+ { id: 'otp1', userLabel: 'Device 1' },
44
+ { id: 'otp2', userLabel: 'Device 2' }
45
+ ],
46
+ selectedCredentialId: 'otp1'
47
+ },
48
+ messagesPerField: {
49
+ existsError: (field: string) => field === 'totp',
50
+ get: () => 'Invalid OTP selection'
51
+ }
52
+ }
53
+ }
54
+ };
55
+
56
+ export const WithOnlyOneOtpCredential: Story = {
57
+ globals: {
58
+ overrides: {
59
+ url: {
60
+ loginAction: '/mock-login'
61
+ },
62
+ configuredOtpCredentials: {
63
+ userOtpCredentials: [{ id: 'otp1', userLabel: 'Device 1' }],
64
+ selectedCredentialId: 'otp1'
65
+ },
66
+ messagesPerField: {
67
+ existsError: () => false
68
+ }
69
+ }
70
+ }
71
+ };
@@ -0,0 +1,50 @@
1
+ import { Meta, StoryObj } from '@storybook/angular';
2
+ import { decorators, KcPageStory } from '../KcPageStory';
3
+
4
+ const meta: Meta<KcPageStory> = {
5
+ title: 'login/login-reset-password.ftl',
6
+ component: KcPageStory,
7
+ decorators: decorators,
8
+ globals: {
9
+ pageId: 'login-reset-password.ftl'
10
+ }
11
+ };
12
+
13
+ export default meta;
14
+ type Story = StoryObj<KcPageStory>;
15
+
16
+ export const Default: Story = {};
17
+
18
+ export const WithEmailAsUsername: Story = {
19
+ globals: {
20
+ overrides: {
21
+ realm: {
22
+ loginWithEmailAllowed: true,
23
+ registrationEmailAsUsername: true
24
+ }
25
+ }
26
+ }
27
+ };
28
+
29
+ export const WithUsernameError: Story = {
30
+ globals: {
31
+ overrides: {
32
+ realm: {
33
+ loginWithEmailAllowed: false,
34
+ registrationEmailAsUsername: false,
35
+ duplicateEmailsAllowed: false
36
+ },
37
+ url: {
38
+ loginAction: '/mock-login-action',
39
+ loginUrl: '/mock-login-url'
40
+ },
41
+ messagesPerField: {
42
+ existsError: (field: string) => field === 'username',
43
+ get: () => 'Invalid username'
44
+ },
45
+ auth: {
46
+ attemptedUsername: 'invalid_user'
47
+ }
48
+ }
49
+ }
50
+ };