From 1d6faa93eb4f14f261fa6222d29b57c2e65b0a31 Mon Sep 17 00:00:00 2001
From: n4ze3m
Date: Sun, 14 Jul 2024 00:16:01 +0530
Subject: [PATCH] feat: support for procted bot (beta)
---
app/ui/src/@types/bot.ts | 43 ++---
.../components/Bot/Settings/SettingPwdP.tsx | 110 ++++++++++++
.../components/Bot/Settings/SettingsBody.tsx | 9 +-
app/ui/src/routes/bot/settings.tsx | 11 +-
app/widget/package.json | 1 +
app/widget/src/App.tsx | 70 +++++---
app/widget/src/components/BotForm.tsx | 10 +-
app/widget/src/components/BotHeader.tsx | 74 +++++---
app/widget/src/components/BotLogin.tsx | 163 ++++++++++++++++++
app/widget/src/hooks/useAuth.tsx | 61 +++++++
.../src/hooks/useDynamicTextareaSize.tsx | 38 ++++
app/widget/src/hooks/useMessage.tsx | 21 ++-
app/widget/src/main.tsx | 5 +-
app/widget/src/utils/getUrl.ts | 7 +
app/widget/src/utils/types.ts | 1 +
pnpm-lock.yaml | 58 ++++++-
server/package.json | 2 +
server/prisma/migrations/q_28/migration.sql | 5 +
server/prisma/schema.prisma | 5 +-
server/src/handlers/api/v1/bot/bot/index.ts | 3 +-
.../api/v1/bot/bot/settings.handler.ts | 51 ++++++
server/src/handlers/api/v1/bot/bot/types.ts | 21 ++-
server/src/handlers/bot/bot-login.handler.ts | 54 ++++++
server/src/handlers/bot/get.handler.ts | 2 +
server/src/handlers/bot/index.ts | 3 +-
server/src/handlers/bot/post.handler.ts | 160 +++++++++++++++++
server/src/handlers/bot/types.ts | 13 ++
server/src/routes/api/v1/bot/root.ts | 15 +-
server/src/routes/bot/root.ts | 10 ++
server/src/schema/api/v1/bot/bot/index.ts | 38 +++-
server/src/schema/bot/index.ts | 26 +++
server/src/utils/jwt.ts | 22 +++
server/yarn.lock | 53 ++++++
33 files changed, 1058 insertions(+), 107 deletions(-)
create mode 100644 app/ui/src/components/Bot/Settings/SettingPwdP.tsx
create mode 100644 app/widget/src/components/BotLogin.tsx
create mode 100644 app/widget/src/hooks/useAuth.tsx
create mode 100644 app/widget/src/hooks/useDynamicTextareaSize.tsx
create mode 100644 server/prisma/migrations/q_28/migration.sql
create mode 100644 server/src/handlers/api/v1/bot/bot/settings.handler.ts
create mode 100644 server/src/handlers/bot/bot-login.handler.ts
create mode 100644 server/src/utils/jwt.ts
diff --git a/app/ui/src/@types/bot.ts b/app/ui/src/@types/bot.ts
index ff342c41..62d86a37 100644
--- a/app/ui/src/@types/bot.ts
+++ b/app/ui/src/@types/bot.ts
@@ -1,39 +1,40 @@
export type BotSettings = {
data: {
id: string;
- name: string;
- model: string;
- public_id: string;
- temperature: number;
- embedding: string;
- noOfDocumentsToRetrieve: number;
- qaPrompt: string;
- questionGeneratorPrompt: string;
- streaming: boolean;
- showRef: boolean;
- use_hybrid_search: boolean;
- bot_protect: boolean;
- use_rag: boolean;
- bot_model_api_key: string;
- noOfChatHistoryInContext: number;
- semanticSearchSimilarityScore: string
- },
+ name: string;
+ model: string;
+ public_id: string;
+ temperature: number;
+ embedding: string;
+ noOfDocumentsToRetrieve: number;
+ qaPrompt: string;
+ questionGeneratorPrompt: string;
+ streaming: boolean;
+ showRef: boolean;
+ use_hybrid_search: boolean;
+ publicBotPwdProtected: boolean;
+ publicBotPwd: string;
+ bot_protect: boolean;
+ use_rag: boolean;
+ bot_model_api_key: string;
+ noOfChatHistoryInContext: number;
+ semanticSearchSimilarityScore: string;
+ };
chatModel: {
label: string;
value: string;
stream: boolean;
- }[],
+ }[];
embeddingModel: {
label: string;
value: string;
- }[],
+ }[];
};
-
export type BotIntegrationAPI = {
is_api_enabled: boolean;
data: {
public_url: string | null;
api_key: string | null;
};
-}
\ No newline at end of file
+};
diff --git a/app/ui/src/components/Bot/Settings/SettingPwdP.tsx b/app/ui/src/components/Bot/Settings/SettingPwdP.tsx
new file mode 100644
index 00000000..daa9610f
--- /dev/null
+++ b/app/ui/src/components/Bot/Settings/SettingPwdP.tsx
@@ -0,0 +1,110 @@
+import { Form, Switch, Input, notification } from "antd";
+import { useParams } from "react-router-dom";
+import api from "../../../services/api";
+import { useMutation, useQueryClient } from "@tanstack/react-query";
+import axios from "axios";
+
+type Props = {
+ publicBotPwdProtected: boolean;
+ publicBotPwd: string;
+};
+
+export const SettingsPwdP: React.FC = ({
+ publicBotPwd,
+ publicBotPwdProtected,
+}) => {
+ const params = useParams<{ id: string }>();
+ const [form] = Form.useForm();
+ const isEnabled = Form.useWatch("publicBotPwdProtected", form);
+ const client = useQueryClient();
+ const onFinish = async (values: any) => {
+ const response = await api.put(`/bot/${params.id}/password`, values);
+ return response.data;
+ };
+
+ const { mutate, isLoading } = useMutation(onFinish, {
+ onSuccess: () => {
+ client.invalidateQueries(["getBotSettings", params.id]);
+
+ notification.success({
+ message: "Bot settings updated successfully",
+ });
+ },
+ onError: (error: any) => {
+ if (axios.isAxiosError(error)) {
+ const message = error.response?.data?.message || "Something went wrong";
+ notification.error({
+ message,
+ });
+ return;
+ }
+ notification.error({
+ message: "Something went wrong",
+ });
+ },
+ });
+ return (
+
+ );
+};
diff --git a/app/ui/src/components/Bot/Settings/SettingsBody.tsx b/app/ui/src/components/Bot/Settings/SettingsBody.tsx
index 611bac73..756246bd 100644
--- a/app/ui/src/components/Bot/Settings/SettingsBody.tsx
+++ b/app/ui/src/components/Bot/Settings/SettingsBody.tsx
@@ -17,6 +17,7 @@ import {
HELPFUL_ASSISTANT_WITHOUT_CONTEXT_PROMPT,
} from "../../../utils/prompts";
import { BotSettings } from "../../../@types/bot";
+import { SettingsPwdP } from "./SettingPwdP";
export const SettingsBody: React.FC = ({
data,
@@ -147,7 +148,6 @@ export const SettingsBody: React.FC = ({
- {/* centerize the div */}
+
+
+
+
diff --git a/app/ui/src/routes/bot/settings.tsx b/app/ui/src/routes/bot/settings.tsx
index 9a1c902b..0196040c 100644
--- a/app/ui/src/routes/bot/settings.tsx
+++ b/app/ui/src/routes/bot/settings.tsx
@@ -14,8 +14,7 @@ export default function BotSettingsRoot() {
["getBotSettings", param.id],
async () => {
const response = await api.get(`/bot/${param.id}/settings`);
- return response.data as BotSettings
-
+ return response.data as BotSettings;
},
{
refetchInterval: 1000,
@@ -28,9 +27,11 @@ export default function BotSettingsRoot() {
}
}, [status]);
return (
-
- {status === "loading" &&
}
- {status === "success" &&
}
+
+
+ {status === "loading" && }
+ {status === "success" && }
+
);
}
diff --git a/app/widget/package.json b/app/widget/package.json
index 08bd8681..2ab36865 100644
--- a/app/widget/package.json
+++ b/app/widget/package.json
@@ -17,6 +17,7 @@
"antd": "^5.5.2",
"axios": "^1.4.0",
"react": "^18.2.0",
+ "react-cookie": "^7.1.4",
"react-dom": "^18.2.0",
"react-markdown": "^8.0.7",
"react-syntax-highlighter": "^15.5.0",
diff --git a/app/widget/src/App.tsx b/app/widget/src/App.tsx
index 53281236..f91a44b9 100644
--- a/app/widget/src/App.tsx
+++ b/app/widget/src/App.tsx
@@ -12,10 +12,14 @@ import BotChatBubble from "./components/BotChatBubble";
import { BotStyle } from "./utils/types";
import { Modal } from "antd";
import { useStoreReference } from "./store";
+import { useAuth } from "./hooks/useAuth";
+import LoginPage from "./components/BotLogin";
function App() {
const { openReferences, setOpenReferences, referenceData } =
useStoreReference();
+ const { isAuthenticated } = useAuth();
+
const divRef = React.useRef
(null);
const { messages, setMessages, setStreaming, setHistory } = useMessage();
@@ -61,35 +65,49 @@ function App() {
}
}, [botStyle]);
+ if (status === "loading") {
+ return ;
+ }
+
+ if (status === "error") {
+ return (
+
+ there was an error occured
+
+ );
+ }
+
+ if (botStyle?.data?.is_protected && !isAuthenticated) {
+ return (
+
+
+
+ );
+ }
+
return (
- {status === "loading" && }
-
- {status === "success" && (
- <>
-
-
-
-
-
- {messages.map((message, index) => {
- return (
-
- );
- })}
-
-
-
-
-
-
- >
- )}
+
+
+
+
+
+ {messages.map((message, index) => {
+ return (
+
+ );
+ })}
+
+
+
+
+
+
(false);
+ const textAreaRef = useRef(null);
+
+ useEffect(() => {
+ if (textAreaRef.current) {
+ textAreaRef.current.focus();
+ }
+ }, []);
const form = useForm({
initialValues: {
@@ -36,6 +43,7 @@ export default function BotForm({}: { botStyle: BotStyle }) {
>