@oussemasahbeni/keycloakify-login-shadcn 250004.0.7 → 250004.0.9
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/keycloak-theme/components/langauges.tsx +1 -1
- package/keycloak-theme/components/theme-toggle.tsx +0 -1
- package/keycloak-theme/components/ui/alert.tsx +69 -62
- package/keycloak-theme/components/ui/button.tsx +44 -39
- package/keycloak-theme/components/ui/card.tsx +59 -45
- package/keycloak-theme/components/ui/checkbox.tsx +24 -23
- package/keycloak-theme/components/ui/dropdown-menu.tsx +233 -168
- package/keycloak-theme/components/ui/field.tsx +50 -48
- package/keycloak-theme/components/ui/input-otp.tsx +55 -49
- package/keycloak-theme/components/ui/input.tsx +18 -22
- package/keycloak-theme/components/ui/label.tsx +19 -21
- package/keycloak-theme/components/ui/radio-group.tsx +27 -26
- package/keycloak-theme/components/ui/select.tsx +169 -122
- package/keycloak-theme/components/ui/separator.tsx +23 -24
- package/keycloak-theme/components/ui/tooltip.tsx +53 -24
- package/keycloak-theme/login/KcPage.tsx +2 -5
- package/keycloak-theme/login/components/LogoutOtherSessions.tsx +3 -5
- package/keycloak-theme/login/components/PasswordWrapper.tsx +4 -4
- package/keycloak-theme/login/components/Template/Template.tsx +110 -58
- package/keycloak-theme/login/components/UserProfileFormFields/AddRemoveButtonsMultiValuedAttribute.tsx +7 -3
- package/keycloak-theme/login/components/UserProfileFormFields/FieldErrors.tsx +8 -4
- package/keycloak-theme/login/components/UserProfileFormFields/GroupLabel.tsx +33 -14
- package/keycloak-theme/login/components/UserProfileFormFields/InputFieldByType.tsx +9 -2
- package/keycloak-theme/login/components/UserProfileFormFields/InputLabel.tsx +0 -1
- package/keycloak-theme/login/components/UserProfileFormFields/InputTag.tsx +25 -8
- package/keycloak-theme/login/components/UserProfileFormFields/InputTagSelects.tsx +30 -16
- package/keycloak-theme/login/components/UserProfileFormFields/SelectTag.tsx +32 -11
- package/keycloak-theme/login/components/UserProfileFormFields/TextareaTag.tsx +19 -7
- package/keycloak-theme/login/components/UserProfileFormFields/UserProfileFormFields.tsx +11 -5
- package/keycloak-theme/login/index.css +3 -20
- package/keycloak-theme/login/mocks/KcPageStory.tsx +6 -2
- package/keycloak-theme/login/pages/PageIndex.tsx +0 -4
- package/keycloak-theme/login/pages/code/Page.stories.tsx +4 -5
- package/keycloak-theme/login/pages/code/Page.tsx +6 -6
- package/keycloak-theme/login/pages/delete-account-confirm/Page.stories.tsx +0 -2
- package/keycloak-theme/login/pages/delete-account-confirm/Page.tsx +3 -6
- package/keycloak-theme/login/pages/delete-credential/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/delete-credential/Page.tsx +11 -6
- package/keycloak-theme/login/pages/error/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/error/Page.tsx +13 -12
- package/keycloak-theme/login/pages/frontchannel-logout/Page.tsx +2 -4
- package/keycloak-theme/login/pages/idp-review-user-profile/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/idp-review-user-profile/Page.tsx +2 -5
- package/keycloak-theme/login/pages/info/Page.tsx +8 -6
- package/keycloak-theme/login/pages/link-idp-action/Page.tsx +5 -3
- package/keycloak-theme/login/pages/login/Form.tsx +36 -38
- package/keycloak-theme/login/pages/login/Page.stories.tsx +4 -3
- package/keycloak-theme/login/pages/login/Page.tsx +0 -1
- package/keycloak-theme/login/pages/login/SocialProviders.tsx +14 -23
- package/keycloak-theme/login/pages/login/providers/github.svg +4 -3
- package/keycloak-theme/login/pages/login/providers/x.svg +4 -3
- package/keycloak-theme/login/pages/login/useProviderLogos.tsx +2 -3
- package/keycloak-theme/login/pages/login-config-totp/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-config-totp/Page.tsx +25 -12
- package/keycloak-theme/login/pages/login-idp-link-confirm/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-idp-link-confirm/Page.tsx +4 -7
- package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.tsx +4 -7
- package/keycloak-theme/login/pages/login-idp-link-email/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-idp-link-email/Page.tsx +4 -7
- package/keycloak-theme/login/pages/login-oauth-grant/Page.tsx +21 -11
- package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/Page.tsx +5 -7
- package/keycloak-theme/login/pages/login-otp/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-otp/Page.tsx +35 -26
- package/keycloak-theme/login/pages/login-page-expired/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-page-expired/Page.tsx +4 -6
- package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/Page.tsx +153 -96
- package/keycloak-theme/login/pages/login-password/Page.tsx +14 -15
- package/keycloak-theme/login/pages/login-password/useScript.tsx +0 -1
- package/keycloak-theme/login/pages/login-recovery-authn-code-config/Page.tsx +5 -8
- package/keycloak-theme/login/pages/login-recovery-authn-code-input/Page.tsx +2 -3
- package/keycloak-theme/login/pages/login-reset-otp/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-reset-otp/Page.tsx +3 -4
- package/keycloak-theme/login/pages/login-reset-password/Form.tsx +5 -6
- package/keycloak-theme/login/pages/login-reset-password/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-reset-password/Page.tsx +3 -3
- package/keycloak-theme/login/pages/login-update-password/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-update-password/Page.tsx +5 -7
- package/keycloak-theme/login/pages/login-update-profile/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-update-profile/Page.tsx +6 -7
- package/keycloak-theme/login/pages/login-username/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-username/Page.tsx +6 -6
- package/keycloak-theme/login/pages/login-verify-email/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-verify-email/Page.tsx +3 -4
- package/keycloak-theme/login/pages/login-x509-info/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/login-x509-info/Page.tsx +3 -6
- package/keycloak-theme/login/pages/logout-confirm/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/logout-confirm/Page.tsx +3 -6
- package/keycloak-theme/login/pages/register/Form.tsx +8 -7
- package/keycloak-theme/login/pages/register/Page.stories.tsx +17 -8
- package/keycloak-theme/login/pages/register/TermsAcceptance.tsx +6 -7
- package/keycloak-theme/login/pages/saml-post-form/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/saml-post-form/Page.tsx +4 -6
- package/keycloak-theme/login/pages/select-authenticator/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/select-authenticator/Page.tsx +3 -6
- package/keycloak-theme/login/pages/select-organization/Page.tsx +5 -8
- package/keycloak-theme/login/pages/terms/Page.tsx +1 -3
- package/keycloak-theme/login/pages/update-email/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/update-email/Page.tsx +6 -7
- package/keycloak-theme/login/pages/webauthn-authenticate/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/webauthn-authenticate/Page.tsx +50 -46
- package/keycloak-theme/login/pages/webauthn-error/Page.stories.tsx +2 -5
- package/keycloak-theme/login/pages/webauthn-error/Page.tsx +3 -6
- package/keycloak-theme/login/pages/webauthn-register/Page.stories.tsx +0 -1
- package/keycloak-theme/login/pages/webauthn-register/Page.tsx +4 -4
- package/keycloak-theme/login/styleLevelCustomization.tsx +5 -6
- package/keycloak-theme/public/site.webmanifest +11 -1
- package/package.json +2 -2
|
@@ -6,10 +6,7 @@ import { Template } from "../../components/Template";
|
|
|
6
6
|
import { UserProfileFormFields } from "../../components/UserProfileFormFields";
|
|
7
7
|
import { useI18n } from "../../i18n";
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
export function Page() {
|
|
11
|
-
|
|
12
|
-
|
|
13
10
|
const { kcContext } = useKcContext();
|
|
14
11
|
assert(kcContext.pageId === "idp-review-user-profile.ftl");
|
|
15
12
|
|
|
@@ -32,8 +29,8 @@ export function Page() {
|
|
|
32
29
|
<UserProfileFormFields
|
|
33
30
|
onIsFormSubmittableValueChange={setIsFomSubmittable}
|
|
34
31
|
/>
|
|
35
|
-
<div
|
|
36
|
-
<div id="kc-form-options"
|
|
32
|
+
<div>
|
|
33
|
+
<div id="kc-form-options">
|
|
37
34
|
<div />
|
|
38
35
|
</div>
|
|
39
36
|
<div id="kc-form-buttons">
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { Button } from '@/components/ui/button';
|
|
1
|
+
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
2
|
+
import { Button } from "@/components/ui/button";
|
|
4
3
|
import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
|
|
5
4
|
import { assert } from "tsafe/assert";
|
|
6
5
|
import { Template } from "../../components/Template";
|
|
@@ -8,7 +7,6 @@ import { useI18n } from "../../i18n";
|
|
|
8
7
|
import { useKcContext } from "../../KcContext";
|
|
9
8
|
|
|
10
9
|
export function Page() {
|
|
11
|
-
|
|
12
10
|
const { kcContext } = useKcContext();
|
|
13
11
|
assert(kcContext.pageId === "info.ftl");
|
|
14
12
|
|
|
@@ -67,7 +65,9 @@ export function Page() {
|
|
|
67
65
|
if (kcContext.pageRedirectUri) {
|
|
68
66
|
return (
|
|
69
67
|
<Button type="button" className="mt-2 flex ms-auto">
|
|
70
|
-
<a href={kcContext.pageRedirectUri}>
|
|
68
|
+
<a href={kcContext.pageRedirectUri}>
|
|
69
|
+
{msg("backToApplication")}
|
|
70
|
+
</a>
|
|
71
71
|
</Button>
|
|
72
72
|
);
|
|
73
73
|
}
|
|
@@ -82,7 +82,9 @@ export function Page() {
|
|
|
82
82
|
if (kcContext.client.baseUrl) {
|
|
83
83
|
return (
|
|
84
84
|
<Button type="button" className="mt-2 flex ms-auto-end">
|
|
85
|
-
<a href={kcContext.client.baseUrl}>
|
|
85
|
+
<a href={kcContext.client.baseUrl}>
|
|
86
|
+
{msg("backToApplication")}
|
|
87
|
+
</a>
|
|
86
88
|
</Button>
|
|
87
89
|
);
|
|
88
90
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Button } from "@/components/ui/button";
|
|
2
|
-
import { useI18n } from
|
|
3
|
-
import { useKcContext } from
|
|
2
|
+
import { useI18n } from "@/login/i18n";
|
|
3
|
+
import { useKcContext } from "@/login/KcContext";
|
|
4
4
|
import { assert } from "tsafe/assert";
|
|
5
5
|
import { Template } from "../../components/Template";
|
|
6
6
|
|
|
@@ -15,7 +15,9 @@ export function Page() {
|
|
|
15
15
|
headerNode={msg("linkIdpActionTitle", kcContext.idpDisplayName)}
|
|
16
16
|
displayMessage={false}
|
|
17
17
|
>
|
|
18
|
-
<div id="kc-link-text">
|
|
18
|
+
<div id="kc-link-text">
|
|
19
|
+
{msg("linkIdpActionMessage", kcContext.idpDisplayName)}
|
|
20
|
+
</div>
|
|
19
21
|
<form action={kcContext.url.loginAction} method="post">
|
|
20
22
|
<div className="flex flex-col sm:flex-row gap-3 sm:justify-between mt-6">
|
|
21
23
|
<Button
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Button } from
|
|
2
|
-
import { Checkbox } from
|
|
3
|
-
import { Field, FieldError, FieldLabel } from
|
|
4
|
-
import { Input } from
|
|
5
|
-
import { Label } from
|
|
6
|
-
import { useKcContext } from
|
|
1
|
+
import { Button } from "@/components/ui/button";
|
|
2
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
3
|
+
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
|
|
4
|
+
import { Input } from "@/components/ui/input";
|
|
5
|
+
import { Label } from "@/components/ui/label";
|
|
6
|
+
import { useKcContext } from "@/login/KcContext";
|
|
7
7
|
import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
|
|
8
8
|
import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
|
|
9
|
-
import { Fingerprint } from
|
|
9
|
+
import { Fingerprint } from "lucide-react";
|
|
10
10
|
import { useState } from "react";
|
|
11
11
|
import { assert } from "tsafe/assert";
|
|
12
12
|
import { PasswordWrapper } from "../../components/PasswordWrapper";
|
|
@@ -91,7 +91,7 @@ export function Form() {
|
|
|
91
91
|
<FieldLabel htmlFor="password">
|
|
92
92
|
{msg("password")}
|
|
93
93
|
</FieldLabel>
|
|
94
|
-
<PasswordWrapper passwordInputId="password"
|
|
94
|
+
<PasswordWrapper passwordInputId="password">
|
|
95
95
|
<Input
|
|
96
96
|
tabIndex={3}
|
|
97
97
|
type="password"
|
|
@@ -104,33 +104,38 @@ export function Form() {
|
|
|
104
104
|
)}
|
|
105
105
|
/>
|
|
106
106
|
</PasswordWrapper>
|
|
107
|
-
{kcContext.messagesPerField.existsError(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
107
|
+
{kcContext.messagesPerField.existsError(
|
|
108
|
+
"username",
|
|
109
|
+
"password"
|
|
110
|
+
) && (
|
|
111
|
+
<FieldError>
|
|
112
|
+
<span
|
|
113
|
+
id="input-error"
|
|
114
|
+
aria-live="polite"
|
|
115
|
+
dangerouslySetInnerHTML={{
|
|
116
|
+
__html: kcSanitize(
|
|
117
|
+
kcContext.messagesPerField.getFirstError(
|
|
118
|
+
"username",
|
|
119
|
+
"password"
|
|
120
|
+
)
|
|
117
121
|
)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)}
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
</FieldError>
|
|
125
|
+
)}
|
|
123
126
|
</Field>
|
|
124
127
|
|
|
125
128
|
<div className=" space-y-1 my-3 flex justify-between text-xs ">
|
|
126
|
-
|
|
127
|
-
|
|
129
|
+
{kcContext.realm.rememberMe &&
|
|
130
|
+
!kcContext.usernameHidden && (
|
|
128
131
|
<div className="flex items-center space-x-2 ">
|
|
129
132
|
<Checkbox
|
|
130
133
|
tabIndex={5}
|
|
131
134
|
id="rememberMe"
|
|
132
135
|
name="rememberMe"
|
|
133
|
-
defaultChecked={
|
|
136
|
+
defaultChecked={
|
|
137
|
+
!!kcContext.login.rememberMe
|
|
138
|
+
}
|
|
134
139
|
/>
|
|
135
140
|
|
|
136
141
|
<Label
|
|
@@ -141,13 +146,14 @@ export function Form() {
|
|
|
141
146
|
</Label>
|
|
142
147
|
</div>
|
|
143
148
|
)}
|
|
144
|
-
</div>
|
|
145
149
|
<div className="link-style ">
|
|
146
150
|
{kcContext.realm.resetPasswordAllowed && (
|
|
147
151
|
<span className=" underline-offset-4 hover:underline">
|
|
148
152
|
<a
|
|
149
153
|
tabIndex={6}
|
|
150
|
-
href={
|
|
154
|
+
href={
|
|
155
|
+
kcContext.url.loginResetCredentialsUrl
|
|
156
|
+
}
|
|
151
157
|
>
|
|
152
158
|
<Label className="text-sm font-medium cursor-pointer">
|
|
153
159
|
{msg("doForgotPassword")}
|
|
@@ -181,17 +187,12 @@ export function Form() {
|
|
|
181
187
|
</form>
|
|
182
188
|
)}
|
|
183
189
|
</div>
|
|
184
|
-
|
|
185
190
|
</div>
|
|
186
191
|
|
|
187
192
|
{kcContext.enableWebAuthnConditionalUI && (
|
|
188
193
|
<>
|
|
189
194
|
<form id="webauth" action={kcContext.url.loginAction} method="post">
|
|
190
|
-
<input
|
|
191
|
-
type="hidden"
|
|
192
|
-
id="clientDataJSON"
|
|
193
|
-
name="clientDataJSON"
|
|
194
|
-
/>
|
|
195
|
+
<input type="hidden" id="clientDataJSON" name="clientDataJSON" />
|
|
195
196
|
<input
|
|
196
197
|
type="hidden"
|
|
197
198
|
id="authenticatorData"
|
|
@@ -206,10 +207,7 @@ export function Form() {
|
|
|
206
207
|
{kcContext.authenticators !== undefined &&
|
|
207
208
|
kcContext.authenticators.authenticators.length !== 0 && (
|
|
208
209
|
<>
|
|
209
|
-
<form
|
|
210
|
-
id="authn_select"
|
|
211
|
-
className={kcClsx("kcFormClass")}
|
|
212
|
-
>
|
|
210
|
+
<form id="authn_select" className={kcClsx("kcFormClass")}>
|
|
213
211
|
{kcContext.authenticators.authenticators.map(
|
|
214
212
|
(authenticator, i) => (
|
|
215
213
|
<input
|
|
@@ -13,7 +13,6 @@ type Story = StoryObj<typeof meta>;
|
|
|
13
13
|
|
|
14
14
|
export const Default: Story = {};
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
export const Arabic: Story = {
|
|
18
17
|
args: {
|
|
19
18
|
kcContext: {
|
|
@@ -46,7 +45,9 @@ export const WithInvalidCredential: Story = {
|
|
|
46
45
|
// existsError() so they are the only ones that need to mock.
|
|
47
46
|
existsError: (fieldName: string, ...otherFieldNames: string[]) => {
|
|
48
47
|
const fieldNames = [fieldName, ...otherFieldNames];
|
|
49
|
-
return
|
|
48
|
+
return (
|
|
49
|
+
fieldNames.includes("username") || fieldNames.includes("password")
|
|
50
|
+
);
|
|
50
51
|
},
|
|
51
52
|
get: (fieldName: string) => {
|
|
52
53
|
if (fieldName === "username" || fieldName === "password") {
|
|
@@ -342,4 +343,4 @@ export const WithSocialProvidersAndWithoutRememberMe: Story = {
|
|
|
342
343
|
realm: { rememberMe: false }
|
|
343
344
|
}
|
|
344
345
|
}
|
|
345
|
-
};
|
|
346
|
+
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { cn } from '@/components/lib/utils';
|
|
2
|
+
import { Button } from "@/components/ui/button";
|
|
2
3
|
import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
|
|
3
4
|
import { clsx } from "@keycloakify/login-ui/tools/clsx";
|
|
4
5
|
import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
|
|
5
6
|
import { assert } from "tsafe/assert";
|
|
6
7
|
import { useI18n } from "../../i18n";
|
|
7
8
|
import { useKcContext } from "../../KcContext";
|
|
8
|
-
import useProviderLogos from
|
|
9
|
+
import useProviderLogos from "./useProviderLogos";
|
|
9
10
|
|
|
10
11
|
/** To use this component make sure that kcContext.social exists */
|
|
11
12
|
export function SocialProviders() {
|
|
@@ -15,7 +16,6 @@ export function SocialProviders() {
|
|
|
15
16
|
|
|
16
17
|
const providerLogos = useProviderLogos();
|
|
17
18
|
|
|
18
|
-
|
|
19
19
|
const { msg } = useI18n();
|
|
20
20
|
|
|
21
21
|
const { kcClsx } = useKcClsx();
|
|
@@ -40,15 +40,11 @@ export function SocialProviders() {
|
|
|
40
40
|
<div className="mt-px flex-auto border-t"></div>
|
|
41
41
|
</div>
|
|
42
42
|
<ul
|
|
43
|
-
className={`mt-4! grid gap-
|
|
44
|
-
|
|
43
|
+
className={`mt-4! grid gap-3 sm:grid-cols-1 ${(kcContext.social?.providers?.length ?? 0) > 3 ? "sm:grid-cols-2" : ""}`}
|
|
45
44
|
>
|
|
46
45
|
{kcContext.social.providers.map((...[p, , providers]) => (
|
|
47
46
|
<li key={p.alias}>
|
|
48
|
-
<Button
|
|
49
|
-
variant="outline"
|
|
50
|
-
className="w-full hover:text-current"
|
|
51
|
-
>
|
|
47
|
+
<Button variant="outline" className="w-full hover:text-current">
|
|
52
48
|
<a
|
|
53
49
|
id={`social-${p.alias}`}
|
|
54
50
|
className={clsx(
|
|
@@ -56,7 +52,7 @@ export function SocialProviders() {
|
|
|
56
52
|
providers.length > 3 &&
|
|
57
53
|
"kcFormSocialAccountGridItem"
|
|
58
54
|
),
|
|
59
|
-
"flex items-center justify-center gap-
|
|
55
|
+
"flex items-center justify-center gap-3 "
|
|
60
56
|
)}
|
|
61
57
|
type="button"
|
|
62
58
|
href={p.loginUrl}
|
|
@@ -64,22 +60,20 @@ export function SocialProviders() {
|
|
|
64
60
|
<div className={"h-5 w-5"}>
|
|
65
61
|
{providerLogos[p.alias] ? (
|
|
66
62
|
<img
|
|
67
|
-
src={
|
|
68
|
-
providerLogos[p.alias]
|
|
69
|
-
}
|
|
63
|
+
src={providerLogos[p.alias]}
|
|
70
64
|
alt={`${p.displayName} logo`}
|
|
71
|
-
className={
|
|
72
|
-
"h-full w-auto"
|
|
73
|
-
|
|
65
|
+
className={cn(
|
|
66
|
+
"h-full w-auto",
|
|
67
|
+
// Invert specific icons in dark mode
|
|
68
|
+
(p.alias === "github" || p.alias === "x" || p.alias === "twitter") && "dark:invert"
|
|
69
|
+
)}
|
|
74
70
|
/>
|
|
75
71
|
) : (
|
|
76
72
|
// Fallback to the original iconClasses if the logo is not defined
|
|
77
73
|
p.iconClasses && (
|
|
78
74
|
<i
|
|
79
75
|
className={clsx(
|
|
80
|
-
kcClsx(
|
|
81
|
-
"kcCommonLogoIdP"
|
|
82
|
-
),
|
|
76
|
+
kcClsx("kcCommonLogoIdP"),
|
|
83
77
|
p.iconClasses,
|
|
84
78
|
`text-provider-${p.alias}`
|
|
85
79
|
)}
|
|
@@ -91,15 +85,12 @@ export function SocialProviders() {
|
|
|
91
85
|
|
|
92
86
|
<span
|
|
93
87
|
dangerouslySetInnerHTML={{
|
|
94
|
-
__html: kcSanitize(
|
|
95
|
-
p.displayName
|
|
96
|
-
)
|
|
88
|
+
__html: kcSanitize(p.displayName)
|
|
97
89
|
}}
|
|
98
90
|
></span>
|
|
99
91
|
</a>
|
|
100
92
|
</Button>
|
|
101
93
|
</li>
|
|
102
|
-
|
|
103
94
|
))}
|
|
104
95
|
</ul>
|
|
105
96
|
</div>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<svg
|
|
2
|
-
<
|
|
3
|
-
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
2
|
+
<path
|
|
3
|
+
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
|
|
4
|
+
fill="currentColor" />
|
|
4
5
|
</svg>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
<path
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" role="img"
|
|
2
|
+
aria-hidden="true">
|
|
3
|
+
<path
|
|
4
|
+
d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z" />
|
|
4
5
|
</svg>
|
|
@@ -24,11 +24,10 @@ const useProviderLogos: () => Record<string, string> = () => ({
|
|
|
24
24
|
gitlab: gitlabLogo,
|
|
25
25
|
google: googleLogo,
|
|
26
26
|
instagram: instagramLogo,
|
|
27
|
-
|
|
27
|
+
linkedin: linkedinLogo,
|
|
28
28
|
microsoft: microsoftLogo,
|
|
29
29
|
oidc: oidcLogo,
|
|
30
|
-
|
|
31
|
-
"openshift-v4": openshiftLogo,
|
|
30
|
+
openshift: openshiftLogo,
|
|
32
31
|
paypal: paypalLogo,
|
|
33
32
|
slack: slackLogo,
|
|
34
33
|
stackoverflow: stackoverflowLogo,
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { Button } from "@/components/ui/button";
|
|
2
2
|
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
|
|
3
3
|
import { Input } from "@/components/ui/input";
|
|
4
|
-
import { LogoutOtherSessions } from
|
|
5
|
-
import { useI18n } from
|
|
6
|
-
import { useKcContext } from
|
|
7
|
-
import { useKcClsx } from
|
|
4
|
+
import { LogoutOtherSessions } from "@/login/components/LogoutOtherSessions";
|
|
5
|
+
import { useI18n } from "@/login/i18n";
|
|
6
|
+
import { useKcContext } from "@/login/KcContext";
|
|
7
|
+
import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
|
|
8
8
|
import { kcSanitize } from "keycloakify/lib/kcSanitize";
|
|
9
9
|
import { assert } from "tsafe/assert";
|
|
10
10
|
import { Template } from "../../components/Template";
|
|
11
11
|
|
|
12
12
|
export function Page() {
|
|
13
|
-
|
|
14
13
|
const { kcContext } = useKcContext();
|
|
15
14
|
assert(kcContext.pageId === "login-config-totp.ftl");
|
|
16
15
|
|
|
@@ -60,7 +59,10 @@ export function Page() {
|
|
|
60
59
|
</div>
|
|
61
60
|
<div className="mt-4">
|
|
62
61
|
<Button variant="outline" asChild>
|
|
63
|
-
<a
|
|
62
|
+
<a
|
|
63
|
+
href={kcContext.totp.qrUrl}
|
|
64
|
+
className="text-sm"
|
|
65
|
+
>
|
|
64
66
|
{msg("loginTotpScanBarcode")}
|
|
65
67
|
</a>
|
|
66
68
|
</Button>
|
|
@@ -76,7 +78,9 @@ export function Page() {
|
|
|
76
78
|
{msg("loginTotpType")}:
|
|
77
79
|
</span>
|
|
78
80
|
<span className="font-mono bg-secondary px-2 py-1 rounded text-xs">
|
|
79
|
-
{msg(
|
|
81
|
+
{msg(
|
|
82
|
+
`loginTotp.${kcContext.totp.policy.type}`
|
|
83
|
+
)}
|
|
80
84
|
</span>
|
|
81
85
|
</div>
|
|
82
86
|
<div className="flex justify-between">
|
|
@@ -105,7 +109,8 @@ export function Page() {
|
|
|
105
109
|
<span className="font-mono bg-secondary px-2 py-1 rounded text-xs">
|
|
106
110
|
{kcContext.totp.policy.type === "totp"
|
|
107
111
|
? kcContext.totp.policy.period
|
|
108
|
-
: kcContext.totp.policy
|
|
112
|
+
: kcContext.totp.policy
|
|
113
|
+
.initialCounter}
|
|
109
114
|
</span>
|
|
110
115
|
</div>
|
|
111
116
|
</div>
|
|
@@ -152,7 +157,9 @@ export function Page() {
|
|
|
152
157
|
id="totp"
|
|
153
158
|
name="totp"
|
|
154
159
|
autoComplete="off"
|
|
155
|
-
aria-invalid={kcContext.messagesPerField.existsError(
|
|
160
|
+
aria-invalid={kcContext.messagesPerField.existsError(
|
|
161
|
+
"totp"
|
|
162
|
+
)}
|
|
156
163
|
/>
|
|
157
164
|
{kcContext.messagesPerField.existsError("totp") && (
|
|
158
165
|
<FieldError>
|
|
@@ -173,7 +180,9 @@ export function Page() {
|
|
|
173
180
|
name="totpSecret"
|
|
174
181
|
value={kcContext.totp.totpSecret}
|
|
175
182
|
/>
|
|
176
|
-
{kcContext.mode &&
|
|
183
|
+
{kcContext.mode && (
|
|
184
|
+
<input type="hidden" id="mode" value={kcContext.mode} />
|
|
185
|
+
)}
|
|
177
186
|
</div>
|
|
178
187
|
|
|
179
188
|
<div className={kcClsx("kcFormGroupClass")}>
|
|
@@ -189,7 +198,9 @@ export function Page() {
|
|
|
189
198
|
id="userLabel"
|
|
190
199
|
name="userLabel"
|
|
191
200
|
autoComplete="off"
|
|
192
|
-
aria-invalid={kcContext.messagesPerField.existsError(
|
|
201
|
+
aria-invalid={kcContext.messagesPerField.existsError(
|
|
202
|
+
"userLabel"
|
|
203
|
+
)}
|
|
193
204
|
/>
|
|
194
205
|
{kcContext.messagesPerField.existsError("userLabel") && (
|
|
195
206
|
<FieldError>
|
|
@@ -197,7 +208,9 @@ export function Page() {
|
|
|
197
208
|
<span
|
|
198
209
|
dangerouslySetInnerHTML={{
|
|
199
210
|
__html: kcSanitize(
|
|
200
|
-
kcContext.messagesPerField.get(
|
|
211
|
+
kcContext.messagesPerField.get(
|
|
212
|
+
"userLabel"
|
|
213
|
+
)
|
|
201
214
|
)
|
|
202
215
|
}}
|
|
203
216
|
/>
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Button } from "@/components/ui/button";
|
|
2
|
-
import { useI18n } from
|
|
3
|
-
import { useKcContext } from
|
|
4
|
-
import { assert } from
|
|
2
|
+
import { useI18n } from "@/login/i18n";
|
|
3
|
+
import { useKcContext } from "@/login/KcContext";
|
|
4
|
+
import { assert } from "tsafe/assert";
|
|
5
5
|
import { Template } from "../../components/Template";
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
export function Page() {
|
|
9
8
|
const { kcContext } = useKcContext();
|
|
10
9
|
assert(kcContext.pageId === "login-idp-link-confirm.ftl");
|
|
@@ -12,9 +11,7 @@ export function Page() {
|
|
|
12
11
|
const { msg } = useI18n();
|
|
13
12
|
|
|
14
13
|
return (
|
|
15
|
-
<Template
|
|
16
|
-
headerNode={msg("confirmLinkIdpTitle")}
|
|
17
|
-
>
|
|
14
|
+
<Template headerNode={msg("confirmLinkIdpTitle")}>
|
|
18
15
|
<form id="kc-register-form" action={kcContext.url.loginAction} method="post">
|
|
19
16
|
<div className="flex flex-col gap-4">
|
|
20
17
|
<Button
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { Button } from "@/components/ui/button";
|
|
2
|
-
import { useI18n } from
|
|
3
|
-
import { useKcContext } from
|
|
4
|
-
import { assert } from
|
|
2
|
+
import { useI18n } from "@/login/i18n";
|
|
3
|
+
import { useKcContext } from "@/login/KcContext";
|
|
4
|
+
import { assert } from "tsafe/assert";
|
|
5
5
|
import { Template } from "../../components/Template";
|
|
6
6
|
|
|
7
7
|
export function Page() {
|
|
8
8
|
const { kcContext } = useKcContext();
|
|
9
9
|
assert(kcContext.pageId === "login-idp-link-confirm-override.ftl");
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
const { msg } = useI18n();
|
|
13
12
|
|
|
14
13
|
return (
|
|
15
|
-
<Template
|
|
16
|
-
headerNode={msg("confirmOverrideIdpTitle")}
|
|
17
|
-
>
|
|
14
|
+
<Template headerNode={msg("confirmOverrideIdpTitle")}>
|
|
18
15
|
<form
|
|
19
16
|
id="kc-register-form"
|
|
20
17
|
action={kcContext.url.loginAction}
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import { Alert, AlertDescription } from "@/components/ui/alert";
|
|
2
|
-
import { useI18n } from
|
|
3
|
-
import { useKcContext } from
|
|
4
|
-
import { assert } from
|
|
2
|
+
import { useI18n } from "@/login/i18n";
|
|
3
|
+
import { useKcContext } from "@/login/KcContext";
|
|
4
|
+
import { assert } from "tsafe/assert";
|
|
5
5
|
import { Template } from "../../components/Template";
|
|
6
6
|
|
|
7
7
|
export function Page() {
|
|
8
|
-
|
|
9
8
|
const { kcContext } = useKcContext();
|
|
10
9
|
assert(kcContext.pageId === "login-idp-link-email.ftl");
|
|
11
10
|
|
|
12
11
|
const { msg } = useI18n();
|
|
13
12
|
|
|
14
13
|
return (
|
|
15
|
-
<Template
|
|
16
|
-
headerNode={msg("emailLinkIdpTitle", kcContext.idpAlias)}
|
|
17
|
-
>
|
|
14
|
+
<Template headerNode={msg("emailLinkIdpTitle", kcContext.idpAlias)}>
|
|
18
15
|
<Alert id="instruction1" variant="info" className="my-3">
|
|
19
16
|
<AlertDescription>
|
|
20
17
|
{msg(
|