Username field (#2135)

This commit is contained in:
Jenny 2022-02-23 09:46:56 -05:00 committed by GitHub
parent 2d55809caf
commit ecd65b3ce7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 87 additions and 18 deletions

View file

@ -178,7 +178,7 @@ describe("User creation", () => {
// Go to user groups
userGroupsPage.goToGroupsTab();
cy.findByTestId(`leave-${groupsList[0]}`).click();
cy.findByTestId("confirm").click();
cy.findByTestId("confirm").click({ force: true });
});
it("Go to user consents test", () => {

View file

@ -34,7 +34,10 @@ export const RealmSettingsLoginTab = ({
return (
<PageSection variant="light">
<FormPanel className="kc-login-screen" title="Login screen customization">
<FormPanel
className="kc-login-screen"
title={t("loginScreenCustomization")}
>
<FormAccess isHorizontal role="manage-realm">
<FormGroup
label={t("userRegistration")}
@ -128,7 +131,7 @@ export const RealmSettingsLoginTab = ({
</FormGroup>
</FormAccess>
</FormPanel>
<FormPanel className="kc-email-settings" title="Email settings">
<FormPanel className="kc-email-settings" title={t("emailSettings")}>
<FormAccess isHorizontal role="manage-realm">
<FormGroup
label={t("emailAsUsername")}
@ -268,6 +271,43 @@ export const RealmSettingsLoginTab = ({
</FormGroup>
</FormAccess>
</FormPanel>
<FormPanel
className="kc-user-info-settings"
title={t("userInfoSettings")}
>
<FormAccess isHorizontal role="manage-realm">
<FormGroup
label={t("editUsername")}
fieldId="kc-edit-username"
labelIcon={
<HelpItem
helpText="realm-settings-help:editUsername"
fieldLabelId="realm-settings:editUsername"
/>
}
hasNoPaddingTop
>
<Controller
name="editUsernameAllowed"
defaultValue={realm.editUsernameAllowed}
control={form.control}
render={({ onChange, value }) => (
<Switch
id="kc-edit-username-switch"
data-testid="edit-username-switch"
name="editUsernameAllowed"
label={t("common:on")}
labelOff={t("common:off")}
isChecked={value}
onChange={(value) => {
updateSwitchValue(onChange, value, "editUsernameAllowed");
}}
/>
)}
/>
</FormGroup>
</FormAccess>
</FormPanel>
</PageSection>
);
};

View file

@ -146,5 +146,7 @@ export default {
"The condition is checked during client registration/update requests and it evaluates to true if the entity (usually user), who is creating/updating client is member of the specified role. For reference the realm role, you can use the realm role name like 'my_realm_role' . For reference client role, you can use the client_id.role_name for example 'my_client.my_client_role' will refer to client role 'my_client_role' of client 'my_client'. ",
defaultGroups:
"Default groups allow you to automatically assign groups membership whenever any new user is created or imported through <1>identity brokering</1>.",
editUsername:
"If enabled, the username field is editable, readonly otherwise.",
},
};

View file

@ -102,6 +102,7 @@ export default {
noKeys: "No keys",
noKeysDescription: "You haven't created any ",
certificate: "Certificate",
loginScreenCustomization: "Login screen customization",
userRegistration: "User registration",
userRegistrationHelpText:
"Enable/disable the registration page. A link for registration will show on login page too.",
@ -111,6 +112,7 @@ export default {
rememberMe: "Remember me",
rememberMeHelpText:
"Show checkbox on login page to allow user to remain logged in between browser restarts until session expires.",
emailSettings: "Email settings",
emailAsUsername: "Email as username",
emailAsUsernameHelpText: "Allow users to set email as username.",
loginWithEmail: "Login with email",
@ -124,6 +126,8 @@ export default {
verifyEmail: "Verify email",
verifyEmailHelpText:
"Require user to verify their email address after initial login or after address changes are submitted.",
userInfoSettings: "User info settings",
editUsername: "Edit username",
testConnection: "Test connection",
testConnectionSuccess:
"Success! SMTP connection successful. E-mail was sent!",

View file

@ -1,5 +1,6 @@
.pf-c-card.pf-m-flat.kc-login-screen,
.pf-c-card.pf-m-flat.kc-email-settings,
.pf-c-card.pf-m-flat.kc-user-info-settings,
.pf-c-card.pf-m-flat.kc-email-template,
.pf-c-card.pf-m-flat.kc-email-connection,
.pf-c-card.pf-m-flat.kc-message-bundles,
@ -24,14 +25,16 @@ article.pf-c-card.pf-m-flat.kc-email-connection
}
.kc-login-screen > div.pf-c-card__header.kc-form-panel__header,
.kc-email-settings > div.pf-c-card__header.kc-form-panel__header {
.kc-email-settings > div.pf-c-card__header.kc-form-panel__header,
.kc-user-info-settings > div.pf-c-card__header.kc-form-panel__header {
padding-bottom: 0px;
padding-left: 0px;
padding-top: 0px;
}
.kc-email-settings > div.pf-c-card__body.kc-form-panel__body,
.kc-login-screen > div.pf-c-card__body.kc-form-panel__body {
.kc-login-screen > div.pf-c-card__body.kc-form-panel__body,
.kc-user-info-settings > div.pf-c-card__body.kc-form-panel__body {
padding-left: 0px;
padding-bottom: var(--pf-global--spacer--2xl);
}
@ -219,7 +222,8 @@ article.pf-c-card.pf-m-flat.kc-login-settings-template
padding: 0 var(--pf-global--spacer--md) 0 var(--pf-global--spacer--md);
}
.kc-backToPolicies, .kc-backToPolicies {
.kc-backToPolicies,
.kc-backToPolicies {
width: 5rem;
}
@ -228,7 +232,7 @@ article.pf-c-card.pf-m-flat.kc-login-settings-template
}
.kc-executor-trash-icon {
margin-left: .5rem;
margin-left: 0.5rem;
color: var(--pf-global--Color--200);
}
@ -241,7 +245,7 @@ article.pf-c-card.pf-m-flat.kc-login-settings-template
}
.kc-conditionType-trash-icon {
margin-left: .5rem;
margin-left: 0.5rem;
color: var(--pf-global--Color--400);
}

View file

@ -20,12 +20,13 @@ import { FormAccess } from "../components/form-access/FormAccess";
import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation";
import { HelpItem } from "../components/help-enabler/HelpItem";
import { useRealm } from "../context/realm-context/RealmContext";
import { useAdminClient } from "../context/auth/AdminClient";
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
import { useAlerts } from "../components/alert/Alerts";
import { emailRegexPattern } from "../util";
import { GroupPickerDialog } from "../components/group/GroupPickerDialog";
import moment from "moment";
import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
export type BruteForced = {
isBruteForceProtected?: boolean;
@ -49,7 +50,7 @@ export const UserForm = ({
onGroupsUpdate,
}: UserFormProps) => {
const { t } = useTranslation("users");
const { realm } = useRealm();
const { realm: realmName } = useRealm();
const [
isRequiredUserActionsDropdownOpen,
@ -67,6 +68,21 @@ export const UserForm = ({
);
const [open, setOpen] = useState(false);
const [locked, setLocked] = useState(isLocked);
const [realm, setRealm] = useState<RealmRepresentation>();
useFetch(
async () => {
const realm = await adminClient.realms.findOne({ realm: realmName });
if (!realm) {
throw new Error(t("common:notFound"));
}
return realm;
},
(realm) => {
setRealm(realm);
},
[]
);
const unLockUser = async () => {
try {
@ -148,7 +164,7 @@ export const UserForm = ({
filterGroups={selectedGroups.map((group) => group.name!)}
/>
)}
{user?.id ? (
{user?.id && (
<>
<FormGroup label={t("common:id")} fieldId="kc-id" isRequired>
<TextInput id={user.id} value={user.id} type="text" isReadOnly />
@ -165,7 +181,8 @@ export const UserForm = ({
/>
</FormGroup>
</>
) : (
)}
{!realm?.registrationEmailAsUsername && (
<FormGroup
label={t("username")}
fieldId="kc-username"
@ -178,7 +195,7 @@ export const UserForm = ({
type="text"
id="kc-username"
name="username"
isReadOnly={!!user?.id}
isReadOnly={!!user?.id && !realm?.editUsernameAllowed}
/>
</FormGroup>
)}
@ -401,7 +418,7 @@ export const UserForm = ({
<Button
data-testid="cancel-create-user"
onClick={() =>
user?.id ? reset(user) : history.push(`/${realm}/users`)
user?.id ? reset(user) : history.push(`/${realmName}/users`)
}
variant="link"
>

View file

@ -70,7 +70,7 @@ const UsersTabs = () => {
setBruteForced(bruteForced);
user && setupForm(user);
},
[]
[user?.username]
);
const setupForm = (user: UserRepresentation) => {
@ -152,7 +152,9 @@ const UsersTabs = () => {
<ImpersonateConfirm />
<DeleteConfirm />
<ViewHeader
titleKey={user?.username || t("createUser")}
titleKey={
userForm.getValues().username || user?.username || t("createUser")
}
divider={!id}
dropdownItems={[
<DropdownItem