diff --git a/public/locales/de/translation.json b/public/locales/de/translation.json
index 39feb74..e5bd8fd 100644
--- a/public/locales/de/translation.json
+++ b/public/locales/de/translation.json
@@ -140,6 +140,10 @@
"userProfile.column.expiresAt": "Läuft ab am",
"userProfile.column.action": "Maßnahme",
"userProfile.column.action.signOut": "Abmelden",
+ "userProfile.column.createdAt": "Erstellt am",
+ "userProfile.column.usageCount": "Anzahl der Nutzungen",
+ "userProfile.column.name": "Name",
+ "userProfile.column.token": "Token",
"userProfile.changeAvatarError.notification.message": "Ihr Avatar konnte nicht geändert werden",
"userProfile.changeAvatarError.notification.description": "Avatar muss kleiner sein als {{MAX_AVATAR_SIZE}} MB sein",
"userProfile.form.username": "Benutzername",
@@ -149,6 +153,11 @@
"userProfile.form.repeatNewPassword": "Neues Passwort wiederholen",
"userProfile.form.language": "Sprache",
"userProfile.header.yourSessions": "Ihre Sitzungen",
+ "userProfile.header.yourApiKeys": "Ihre API Schlüssel",
+ "userProfile.button.createApiKey": "Neuen API Schlüssel erstellen",
+ "userProfile.button.createApiKey.popconfirm.title": "Name für den neuen API Schlüssel",
+ "userProfile.button.createApiKey.popconfirm.okText": "Erstellen",
+ "userProfile.button.copyToClipboard.notification": "API Token in die Zwischenablage kopiert",
"scanners.column.name": "Name",
"scanners.column.usedBy": "Verwendet von",
"scanners.column.lastUsed": "Zuletzt verwendet",
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index e130080..f8f4117 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -140,6 +140,10 @@
"userProfile.column.expiresAt": "Expires at",
"userProfile.column.action": "Action",
"userProfile.column.action.signOut": "Sign out",
+ "userProfile.column.createdAt": "Created at",
+ "userProfile.column.usageCount": "Usage count",
+ "userProfile.column.name": "Name",
+ "userProfile.column.token": "Token",
"userProfile.changeAvatarError.notification.message": "Your avatar could not be changed",
"userProfile.changeAvatarError.notification.description": "Avatar must be smaller than {{MAX_AVATAR_SIZE}} MB",
"userProfile.form.username": "Username",
@@ -149,6 +153,11 @@
"userProfile.form.repeatNewPassword": "Repeat new password",
"userProfile.form.language": "Language",
"userProfile.header.yourSessions": "Your sessions",
+ "userProfile.header.yourApiKeys": "Your API keys",
+ "userProfile.button.createApiKey": "Create new API key",
+ "userProfile.button.createApiKey.popconfirm.title": "Name for the new API key",
+ "userProfile.button.createApiKey.popconfirm.okText": "Create",
+ "userProfile.button.copyToClipboard.notification": "API token copied to clipboard",
"scanners.column.name": "Name",
"scanners.column.usedBy": "Used by",
"scanners.column.lastUsed": "Last used",
diff --git a/src/Pages/UserProfile/index.js b/src/Pages/UserProfile/index.js
index fa2ffb6..251c49f 100644
--- a/src/Pages/UserProfile/index.js
+++ b/src/Pages/UserProfile/index.js
@@ -4,6 +4,7 @@ import {
Col,
Form,
Input,
+ Popconfirm,
Row,
Select,
Space,
@@ -26,6 +27,12 @@ import {
} from "../../utils";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
+import {
+ CopyOutlined,
+ EyeInvisibleOutlined,
+ EyeOutlined,
+ KeyOutlined,
+} from "@ant-design/icons";
export default function UserProfile() {
const webSocketContext = useContext(WebSocketContext);
@@ -36,8 +43,10 @@ export default function UserProfile() {
const [oldPassword, setOldPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const [repeatedNewPassword, setRepeatedNewPassword] = useState("");
+ const [newApiKeyName, setNewApikeyName] = useState("");
+ const [showApiKeyPassword, setShowApiKeyPassword] = useState(false);
- const getTableColumns = () => {
+ const getSessionTableColumns = () => {
return [
{
title: t("userProfile.column.userAgent"),
@@ -91,7 +100,81 @@ export default function UserProfile() {
];
};
- const getTableItems = () => {
+ const getApiKeyTableColumns = () => {
+ return [
+ {
+ title: t("userProfile.column.name"),
+ dataIndex: "name",
+ key: "name",
+ },
+ {
+ title: t("userProfile.column.token"),
+ dataIndex: "token",
+ key: "token",
+ render: (text) => (
+