diff --git a/package-lock.json b/package-lock.json index 2aafe39170..f171d82ba9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "version": "0.0.1", "license": "Apache", "dependencies": { - "@keycloak/keycloak-admin-client": "^16.0.0-dev.0", + "@keycloak/keycloak-admin-client": "^16.0.0-dev.2", "@patternfly/patternfly": "^4.132.2", "@patternfly/react-core": "4.152.4", "@patternfly/react-icons": "4.11.14", @@ -2541,9 +2541,9 @@ } }, "node_modules/@keycloak/keycloak-admin-client": { - "version": "16.0.0-dev.0", - "resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.0.tgz", - "integrity": "sha512-o1gUKPn6Zeqe//1v2TF5VVvwDeeXktUFf/L70rQ8KJC/PudGPnV6luDu6Pyj/G32Yoc5iigSMWFly5Qlsd0bgw==", + "version": "16.0.0-dev.2", + "resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.2.tgz", + "integrity": "sha512-eLeN4/O5OWjU0fIIvndv0oLSRQN3q0bdMep19E+09/qL4jeNeBR4ltxLKd0mnW1FY53cZJ+QWLaq/lfgRXFfzA==", "dependencies": { "axios": "^0.21.0", "camelize": "^1.0.0", @@ -19352,9 +19352,9 @@ } }, "@keycloak/keycloak-admin-client": { - "version": "16.0.0-dev.0", - "resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.0.tgz", - "integrity": "sha512-o1gUKPn6Zeqe//1v2TF5VVvwDeeXktUFf/L70rQ8KJC/PudGPnV6luDu6Pyj/G32Yoc5iigSMWFly5Qlsd0bgw==", + "version": "16.0.0-dev.2", + "resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.2.tgz", + "integrity": "sha512-eLeN4/O5OWjU0fIIvndv0oLSRQN3q0bdMep19E+09/qL4jeNeBR4ltxLKd0mnW1FY53cZJ+QWLaq/lfgRXFfzA==", "requires": { "axios": "^0.21.0", "camelize": "^1.0.0", diff --git a/package.json b/package.json index 7af5edd4dc..2c534e5a56 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "prepare": "husky install" }, "dependencies": { - "@keycloak/keycloak-admin-client": "^16.0.0-dev.0", + "@keycloak/keycloak-admin-client": "^16.0.0-dev.2", "@patternfly/patternfly": "^4.132.2", "@patternfly/react-core": "4.152.4", "@patternfly/react-icons": "4.11.14", diff --git a/src/clients/messages.ts b/src/clients/messages.ts index 08f941bc4b..7815759662 100644 --- a/src/clients/messages.ts +++ b/src/clients/messages.ts @@ -59,7 +59,6 @@ export default { searchForRole: "Search role", origin: "Origin", user: "User", - details: "Details", noGeneratedAccessToken: "No generated access token", generatedAccessTokenIsDisabled: "Generated access token is disabled when no user is selected", diff --git a/src/common-messages.ts b/src/common-messages.ts index 630d516f21..48db5aa1c9 100644 --- a/src/common-messages.ts +++ b/src/common-messages.ts @@ -84,6 +84,7 @@ export default { userFederation: "User federation", settings: "Settings", + details: "Details", required: "Required field", maxLength: "Max length {{length}}", diff --git a/src/components/download-dialog/DownloadDialog.tsx b/src/components/download-dialog/DownloadDialog.tsx index f5577e11f3..2d6e4b5c97 100644 --- a/src/components/download-dialog/DownloadDialog.tsx +++ b/src/components/download-dialog/DownloadDialog.tsx @@ -144,11 +144,11 @@ export const DownloadDialog = ({ } diff --git a/src/realm-roles/RealmRoleTabs.tsx b/src/realm-roles/RealmRoleTabs.tsx index 576763d598..c590026c10 100644 --- a/src/realm-roles/RealmRoleTabs.tsx +++ b/src/realm-roles/RealmRoleTabs.tsx @@ -331,7 +331,7 @@ export const RealmRoleTabs = () => { {t("details")}} + title={{t("common:details")}} > { - const { t } = useTranslation("roles"); + const { t } = useTranslation("users"); const { addAlert, addError } = useAlerts(); const history = useHistory(); const { realm } = useRealm(); @@ -70,7 +74,7 @@ export const UsersTabs = () => { try { if (id) { await adminClient.users.update({ id }, user); - addAlert(t("users:userSaved"), AlertVariant.success); + addAlert(t("userSaved"), AlertVariant.success); } else { const createdUser = await adminClient.users.create(user); @@ -81,7 +85,7 @@ export const UsersTabs = () => { }); }); - addAlert(t("users:userCreated"), AlertVariant.success); + addAlert(t("userCreated"), AlertVariant.success); history.push(toUser({ id: createdUser.id, realm, tab: "settings" })); } } catch (error) { @@ -89,11 +93,61 @@ export const UsersTabs = () => { } }; + const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ + titleKey: "users:deleteConfirm", + messageKey: "users:deleteConfirmCurrentUser", + continueButtonLabel: "common:delete", + continueButtonVariant: ButtonVariant.danger, + onConfirm: async () => { + try { + await adminClient.users.del({ id }); + addAlert(t("userDeletedSuccess"), AlertVariant.success); + history.push(toUsers({ realm })); + } catch (error) { + addError("users:userDeletedError", error); + } + }, + }); + + const [toggleImpersonateDialog, ImpersonateConfirm] = useConfirmDialog({ + titleKey: "users:impersonateConfirm", + messageKey: "users:impersonateConfirmDialog", + continueButtonLabel: "users:impersonate", + onConfirm: async () => { + try { + const data = await adminClient.users.impersonation( + { id }, + { user: id, realm } + ); + if (data.sameRealm) { + window.location = data.redirect; + } else { + window.open(data.redirect, "_blank"); + } + } catch (error) { + addError("users:impersonateError", error); + } + }, + }); + return ( <> + + toggleImpersonateDialog()} + > + {t("impersonate")} + , + toggleDeleteDialog()}> + {t("common:delete")} + , + ]} /> @@ -102,7 +156,7 @@ export const UsersTabs = () => { {t("details")}} + title={{t("common:details")}} > {bruteForced && ( @@ -118,14 +172,14 @@ export const UsersTabs = () => { {t("groups")}} + title={{t("common:groups")}} > {t("users:consents")}} + title={{t("consents")}} > @@ -133,9 +187,7 @@ export const UsersTabs = () => { eventKey="identity-provider-links" data-testid="identity-provider-links-tab" title={ - - {t("users:identityProviderLinks")} - + {t("identityProviderLinks")} } > diff --git a/src/user/messages.ts b/src/user/messages.ts index 4248991309..b4ed10e3c3 100644 --- a/src/user/messages.ts +++ b/src/user/messages.ts @@ -46,8 +46,16 @@ export default { notVerified: "Not verified", requiredUserActions: "Required user actions", addUser: "Add user", + impersonate: "Impersonate", + impersonateConfirm: "Impersonate user?", + impersonateConfirmDialog: + "Are you sure you want to log in as this user? If this user is in the same realm with you, your current login session will be logged out before you log in as this user.", + impersonateError: "Could not impersonate the user: {{error}}", + deleteUser: "Delete user", deleteConfirm: "Delete user?", + deleteConfirmCurrentUser: + "Are you sure you want to permanently delete this user", deleteConfirmDialog: "Are you sure you want to permanently delete {{count}} selected user", deleteConfirmDialog_plural: