expiration check
parent
f56a4235e7
commit
71c6a72308
|
@ -29,7 +29,8 @@
|
|||
"copiedToClipboard": "In die Zwischenablage kopiert",
|
||||
"copyToClipboard": "In die Zwischenablage kopieren",
|
||||
"show": "Anzeigen",
|
||||
"hide": "Verbergen"
|
||||
"hide": "Verbergen",
|
||||
"reload": "Neu laden"
|
||||
}
|
||||
},
|
||||
"sideMenu": {
|
||||
|
@ -386,7 +387,6 @@
|
|||
"repeatNewPassword": "Neues Passwort wiederholen",
|
||||
"language": "Sprache"
|
||||
},
|
||||
|
||||
"button": {
|
||||
"createApiKey": {
|
||||
"title": "Neuen API-Schlüssel erstellen",
|
||||
|
@ -396,7 +396,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"icon": { "viewApiDoc": "Api-Dokumentation anschauen" }
|
||||
"icon": { "viewApiDoc": "Api-Dokumentation anschauen" },
|
||||
"telegram": {
|
||||
"title": "Telegram Benachrichtigungen",
|
||||
"disconnectPopconfirm": {
|
||||
"title": "Sind Sie sicher, dass Sie die Verbindung zu Telegram trennen wollen?",
|
||||
"description": "Sie werden keine Benachrichtigungen mehr erhalten"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanners": {
|
||||
"column": {
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
"copiedToClipboard": "Copied to clipboard",
|
||||
"copyToClipboard": "Copy to clipboard",
|
||||
"show": "Show",
|
||||
"hide": "Hide"
|
||||
"hide": "Hide",
|
||||
"reload": "Reload"
|
||||
}
|
||||
},
|
||||
"sideMenu": {
|
||||
|
@ -415,7 +416,21 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"icon": { "viewApiDoc": "View API Documentation" }
|
||||
"icon": { "viewApiDoc": "View API Documentation" },
|
||||
"telegram": {
|
||||
"title": "Telegram notifications",
|
||||
"subscribeButton": "Subscribe",
|
||||
"checkStatusButton": "Check Status",
|
||||
"subscribed": "Subscribed",
|
||||
"disconnectPopconfirm": {
|
||||
"title": "Are you sure you want to disconnect your Telegram account?",
|
||||
"description": "You will no longer receive notifications via Telegram"
|
||||
},
|
||||
"verificationPopover": {
|
||||
"title": "Verification",
|
||||
"description": "Add the bot on your telegram account and send the command {{command}} to the bot"
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanners": {
|
||||
"column": {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import {
|
||||
CopyOutlined,
|
||||
DisconnectOutlined,
|
||||
EyeInvisibleOutlined,
|
||||
EyeOutlined,
|
||||
ReloadOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { Tooltip } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
@ -37,3 +39,13 @@ export function MyShowHiddenIcon({ setIsHidden, isHidden }) {
|
|||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
export function MyReloadIcon({ onClick }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Tooltip title={t("common.text.reload")}>
|
||||
<ReloadOutlined onClick={onClick} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import {
|
|||
Form,
|
||||
Input,
|
||||
Popconfirm,
|
||||
Popover,
|
||||
Row,
|
||||
Select,
|
||||
Space,
|
||||
|
@ -14,7 +15,7 @@ import {
|
|||
Upload,
|
||||
notification,
|
||||
} from "antd";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
Constants,
|
||||
EncodeStringToBase64,
|
||||
|
@ -24,18 +25,29 @@ import {
|
|||
hasPermission,
|
||||
isEmailValid,
|
||||
myFetch,
|
||||
myFetchContentType,
|
||||
wsConnectionCustomEventName,
|
||||
} from "../../utils";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FileTextOutlined, KeyOutlined } from "@ant-design/icons";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
import {
|
||||
DisconnectOutlined,
|
||||
FileTextOutlined,
|
||||
InfoCircleOutlined,
|
||||
KeyOutlined,
|
||||
NotificationOutlined,
|
||||
} from "@ant-design/icons";
|
||||
import { MyUserAvatar } from "../../Components/MyAvatar";
|
||||
import { useUserProfileContext } from "../../Contexts/UserProfileContext";
|
||||
import { useWebSocketContext } from "../../Contexts/WebSocketContext";
|
||||
import { useAppContext } from "../../Contexts/AppContext";
|
||||
import { useSideBarContext } from "../../Contexts/SideBarContext";
|
||||
import { SentMessagesCommands } from "../../Handlers/WebSocketMessageHandler";
|
||||
import { MyCopyIcon, MyShowHiddenIcon } from "../../Components/MyIcon";
|
||||
import {
|
||||
MyCopyIcon,
|
||||
MyReloadIcon,
|
||||
MyShowHiddenIcon,
|
||||
} from "../../Components/MyIcon";
|
||||
|
||||
export default function UserProfile() {
|
||||
const webSocketContext = useWebSocketContext();
|
||||
|
@ -53,6 +65,13 @@ export default function UserProfile() {
|
|||
const [repeatedNewPassword, setRepeatedNewPassword] = useState("");
|
||||
const [newApiKeyName, setNewApikeyName] = useState("");
|
||||
const [showApiKeyPassword, setShowApiKeyPassword] = useState(false);
|
||||
const [
|
||||
telegramNotificationSubscribedStatus,
|
||||
setTelegramNotificationSubscribedStatus,
|
||||
] = useState(null);
|
||||
|
||||
const statusInterval = useRef(null);
|
||||
const telegramVerifyCodeRequestTime = useRef(null);
|
||||
|
||||
const getSessionTableColumns = () => {
|
||||
return [
|
||||
|
@ -271,6 +290,165 @@ export default function UserProfile() {
|
|||
setNewApikeyName("");
|
||||
};
|
||||
|
||||
const telegramVerifyStatusRequest = (updateOnlyOnVerified) =>
|
||||
myFetch(
|
||||
`/status/${appContext.userId.current}`,
|
||||
"GET",
|
||||
null,
|
||||
{},
|
||||
myFetchContentType.JSON,
|
||||
Constants.TELEGRAM_BOT_MANAGER_ADDRESS
|
||||
).then((data) => {
|
||||
// manual check verify status by clicking reload icon
|
||||
if (!updateOnlyOnVerified) {
|
||||
setTelegramNotificationSubscribedStatus(data.Status);
|
||||
}
|
||||
|
||||
// used for auto check verify status
|
||||
if (data.Status === true) {
|
||||
setTelegramNotificationSubscribedStatus(data.Status);
|
||||
clearInterval(statusInterval.current);
|
||||
telegramVerifyCodeRequestTime.current = null;
|
||||
}
|
||||
});
|
||||
|
||||
const TelegramNotificationSubscribedStatusItem = () => {
|
||||
// check verified status
|
||||
if (telegramNotificationSubscribedStatus === null) {
|
||||
return (
|
||||
<Button
|
||||
style={{ width: "100%" }}
|
||||
onClick={() => telegramVerifyStatusRequest()}
|
||||
>
|
||||
{t("userProfile.telegram.checkStatusButton")}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
// unsubscribe
|
||||
if (telegramNotificationSubscribedStatus === true) {
|
||||
return (
|
||||
<Space>
|
||||
<span>{t("userProfile.telegram.subscribed")}</span>
|
||||
|
||||
<Popconfirm
|
||||
title={t("userProfile.telegram.disconnectPopconfirm.title")}
|
||||
description={t(
|
||||
"userProfile.telegram.disconnectPopconfirm.description"
|
||||
)}
|
||||
okText={t("common.button.confirm")}
|
||||
cancelText={t("common.button.cancel")}
|
||||
onConfirm={() => {
|
||||
myFetch(
|
||||
`/verifycode/${appContext.userId.current}`,
|
||||
"DELETE",
|
||||
null,
|
||||
{},
|
||||
myFetchContentType.JSON,
|
||||
Constants.TELEGRAM_BOT_MANAGER_ADDRESS
|
||||
).then(() => {
|
||||
setTelegramNotificationSubscribedStatus(null);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<DisconnectOutlined />
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
// subscribe
|
||||
if (telegramNotificationSubscribedStatus === false) {
|
||||
return (
|
||||
<Button
|
||||
icon={<NotificationOutlined />}
|
||||
style={{ width: "100%" }}
|
||||
onClick={() =>
|
||||
myFetch(
|
||||
`/verifycode/${appContext.userId.current}`,
|
||||
"GET",
|
||||
null,
|
||||
{},
|
||||
myFetchContentType.JSON,
|
||||
Constants.TELEGRAM_BOT_MANAGER_ADDRESS
|
||||
).then((data) => {
|
||||
setTelegramNotificationSubscribedStatus(data.Code);
|
||||
})
|
||||
}
|
||||
>
|
||||
{t("userProfile.telegram.subscribeButton")}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
// verification code
|
||||
return (
|
||||
<Space>
|
||||
<Popover
|
||||
placement="left"
|
||||
title={t("userProfile.telegram.verificationPopover.title")}
|
||||
overlayStyle={{ maxWidth: 300 }}
|
||||
content={
|
||||
<Space direction="vertical">
|
||||
<Trans
|
||||
i18nKey="userProfile.telegram.verificationPopover.description"
|
||||
values={{
|
||||
command: `<strong>/verify ${telegramNotificationSubscribedStatus}</strong>`,
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<img
|
||||
src={`${Constants.TELEGRAM_BOT_MANAGER_CONTENT_ADDRESS}qrcode.png`}
|
||||
width={200}
|
||||
/>
|
||||
</div>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
<InfoCircleOutlined style={{ color: Constants.COLORS.ICON_INFO }} />
|
||||
</Popover>
|
||||
|
||||
<span>{telegramNotificationSubscribedStatus}</span>
|
||||
|
||||
<MyCopyIcon
|
||||
text={`/verify ${telegramNotificationSubscribedStatus}`}
|
||||
notificationApi={notificationApi}
|
||||
/>
|
||||
|
||||
<MyReloadIcon onClick={() => telegramVerifyStatusRequest()} />
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
telegramNotificationSubscribedStatus !== true &&
|
||||
telegramNotificationSubscribedStatus !== false &&
|
||||
telegramNotificationSubscribedStatus !== null
|
||||
) {
|
||||
telegramVerifyCodeRequestTime.current = new Date();
|
||||
|
||||
statusInterval.current = setInterval(() => {
|
||||
// check expiration time
|
||||
if (
|
||||
telegramVerifyCodeRequestTime.current !== null &&
|
||||
new Date() - telegramVerifyCodeRequestTime.current >
|
||||
Constants.GLOBALS.TELEGRAM_VERIFY_CODE_EXPIRATION_TIME
|
||||
) {
|
||||
clearInterval(statusInterval.current);
|
||||
telegramVerifyCodeRequestTime.current = null;
|
||||
setTelegramNotificationSubscribedStatus(false);
|
||||
return;
|
||||
}
|
||||
|
||||
telegramVerifyStatusRequest(true);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
return () => clearInterval(statusInterval.current);
|
||||
}, [telegramNotificationSubscribedStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
const userProfileRequest = () =>
|
||||
myFetch("/user/profile", "GET").then((data) => {
|
||||
|
@ -342,6 +520,10 @@ export default function UserProfile() {
|
|||
onChange={(e) => i18n.changeLanguage(e)}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label={t("userProfile.telegram.title")}>
|
||||
<TelegramNotificationSubscribedStatusItem />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
|
|
11
src/utils.js
11
src/utils.js
|
@ -14,6 +14,8 @@ let wsAddress = "";
|
|||
let logApiAddress = "";
|
||||
let roboticsApiAddress = "";
|
||||
var roboticsSwaggerAddress = "";
|
||||
var telegramBotManagerAddress = "";
|
||||
var telegramBotManagerStaticContentAddress = "";
|
||||
|
||||
if (window.location.hostname === "localhost" && window.location.port === "") {
|
||||
// for docker container testing on localhost
|
||||
|
@ -23,6 +25,8 @@ if (window.location.hostname === "localhost" && window.location.port === "") {
|
|||
logApiAddress = "http://localhost/lm/v1/log";
|
||||
roboticsApiAddress = "http://localhost/rcm/v1";
|
||||
roboticsSwaggerAddress = "http://localhost/rcm/swagger/index.html";
|
||||
telegramBotManagerAddress = "http://localhost/tnm/v1";
|
||||
telegramBotManagerStaticContentAddress = "http://localhost/tnm/";
|
||||
} else if (window.location.hostname === "localhost") {
|
||||
// programming on localhost
|
||||
apiAddress = "http://localhost:50050/v1";
|
||||
|
@ -31,6 +35,8 @@ if (window.location.hostname === "localhost" && window.location.port === "") {
|
|||
logApiAddress = "http://127.0.0.1:50110/v1/log";
|
||||
roboticsApiAddress = "http://localhost:50055/v1";
|
||||
roboticsSwaggerAddress = "http://localhost:50055/swagger/index.html";
|
||||
telegramBotManagerAddress = "http://localhost:50056/v1";
|
||||
telegramBotManagerStaticContentAddress = "http://localhost:50056/";
|
||||
/*} else if (window.location.hostname === "192.168.178.93") {
|
||||
apiAddress = "http://192.168.178.93:50050/v1";
|
||||
staticContentAddress = "http://192.168.178.93:50050/";
|
||||
|
@ -43,6 +49,8 @@ if (window.location.hostname === "localhost" && window.location.port === "") {
|
|||
logApiAddress = `${window.location.protocol}${window.location.hostname}/lm/v1/log`;
|
||||
roboticsApiAddress = `${window.location.protocol}${window.location.hostname}/rcm/v1`;
|
||||
roboticsSwaggerAddress = `${window.location.protocol}${window.location.hostname}/rcm/swagger/index.html`;
|
||||
telegramBotManagerAddress = `${window.location.protocol}${window.location.hostname}/tnm/v1`;
|
||||
telegramBotManagerStaticContentAddress = `${window.location.protocol}${window.location.hostname}/tnm/`;
|
||||
}
|
||||
|
||||
export const Constants = {
|
||||
|
@ -66,6 +74,8 @@ export const Constants = {
|
|||
LOG_API_ADDRESS: logApiAddress,
|
||||
ROBOTICS_API_ADDRESS: roboticsApiAddress, // robot-control-manager
|
||||
ROBOTICS_SWAGGER_ADDRESS: roboticsSwaggerAddress,
|
||||
TELEGRAM_BOT_MANAGER_ADDRESS: telegramBotManagerAddress,
|
||||
TELEGRAM_BOT_MANAGER_CONTENT_ADDRESS: telegramBotManagerStaticContentAddress,
|
||||
ROUTE_PATHS: {
|
||||
EQUIPMENT_DOCUMENTATION: "/equipment-documentation",
|
||||
EQUIPMENT_DOCUMENTATION_VIEW: "/equipment-documentation/",
|
||||
|
@ -113,6 +123,7 @@ export const Constants = {
|
|||
MAX_USER_API_KEY_NAME_LENGTH: 30,
|
||||
ROBOTICS_ROBOTS_PAGINATION_LIMIT: 5,
|
||||
ROBOTICS_UNAUTHORIZED_PAGINATION_LIMIT: 5,
|
||||
TELEGRAM_VERIFY_CODE_EXPIRATION_TIME: 10 * 60 * 1000, // 10 minutes
|
||||
},
|
||||
MAX_AVATAR_SIZE: 5 * 1024 * 1024,
|
||||
ACCEPTED_AVATAR_FILE_TYPES: [
|
||||
|
|
Loading…
Reference in New Issue