From 31c89aa8e6be9b57935a04d0935bca1831a8f822 Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 20 Feb 2024 16:44:37 +0530 Subject: [PATCH 01/11] Add allowed domains settings and disallow prediction based on this list --- packages/server/src/index.ts | 18 +- packages/ui/src/menu-items/settings.js | 20 +- .../dialog/AllowedDomainsDialog.js | 238 ++++++++++++++++++ packages/ui/src/views/canvas/CanvasHeader.js | 15 ++ 4 files changed, 288 insertions(+), 3 deletions(-) create mode 100644 packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 20102a42a57..5c1f41313fe 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1219,7 +1219,23 @@ export class App { upload.array('files'), (req: Request, res: Response, next: NextFunction) => getRateLimiter(req, res, next), async (req: Request, res: Response) => { - await this.buildChatflow(req, res, socketIO) + const chatflow = await this.AppDataSource.getRepository(ChatFlow).findOneBy({ + id: req.params.id + }) + if (!chatflow) return res.status(404).send(`Chatflow ${req.params.id} not found`) + let isDomainAllowed = true + if (chatflow.chatbotConfig) { + const parsedConfig = JSON.parse(chatflow.chatbotConfig) + if (parsedConfig.allowedDomains && parsedConfig.allowedDomains.length > 0) { + isDomainAllowed = parsedConfig.allowedDomains.includes(req.headers.host) + } + } + + if (isDomainAllowed) { + await this.buildChatflow(req, res, socketIO) + } else { + return res.status(401).send(`This domain is not allowed to access chatflow ${req.params.id}`) + } } ) diff --git a/packages/ui/src/menu-items/settings.js b/packages/ui/src/menu-items/settings.js index 1e0f58ddbc8..691d194e3d7 100644 --- a/packages/ui/src/menu-items/settings.js +++ b/packages/ui/src/menu-items/settings.js @@ -1,8 +1,17 @@ // assets -import { IconTrash, IconFileUpload, IconFileExport, IconCopy, IconSearch, IconMessage, IconPictureInPictureOff } from '@tabler/icons' +import { + IconTrash, + IconFileUpload, + IconFileExport, + IconCopy, + IconSearch, + IconMessage, + IconPictureInPictureOff, + IconLink +} from '@tabler/icons' // constant -const icons = { IconTrash, IconFileUpload, IconFileExport, IconCopy, IconSearch, IconMessage, IconPictureInPictureOff } +const icons = { IconTrash, IconFileUpload, IconFileExport, IconCopy, IconSearch, IconMessage, IconPictureInPictureOff, IconLink } // ==============================|| SETTINGS MENU ITEMS ||============================== // @@ -25,6 +34,13 @@ const settings = { url: '', icon: icons.IconMessage }, + { + id: 'allowedDomains', + title: 'Allowed Domains', + type: 'item', + url: '', + icon: icons.IconLink + }, { id: 'duplicateChatflow', title: 'Duplicate Chatflow', diff --git a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js new file mode 100644 index 00000000000..7048c29e2b2 --- /dev/null +++ b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js @@ -0,0 +1,238 @@ +import { createPortal } from 'react-dom' +import { useDispatch } from 'react-redux' +import { useState, useEffect } from 'react' +import PropTypes from 'prop-types' +import { enqueueSnackbar as enqueueSnackbarAction, closeSnackbar as closeSnackbarAction, SET_CHATFLOW } from 'store/actions' + +// material-ui +import { + Button, + IconButton, + Dialog, + DialogContent, + OutlinedInput, + DialogTitle, + DialogActions, + Box, + List, + InputAdornment +} from '@mui/material' +import { IconX, IconTrash, IconPlus } from '@tabler/icons' + +// Project import +import { StyledButton } from 'ui-component/button/StyledButton' + +// store +import { HIDE_CANVAS_DIALOG, SHOW_CANVAS_DIALOG } from 'store/actions' +import useNotifier from 'utils/useNotifier' + +// API +import chatflowsApi from 'api/chatflows' + +const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { + const portalElement = document.getElementById('portal') + const dispatch = useDispatch() + + useNotifier() + + const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args)) + const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args)) + + const [inputFields, setInputFields] = useState([ + { + origin: '' + } + ]) + + const [chatbotConfig, setChatbotConfig] = useState({}) + + const addInputField = () => { + setInputFields([ + ...inputFields, + { + origin: '' + } + ]) + } + const removeInputFields = (index) => { + const rows = [...inputFields] + rows.splice(index, 1) + setInputFields(rows) + } + + const handleChange = (index, evnt) => { + const { name, value } = evnt.target + const list = [...inputFields] + list[index][name] = value + setInputFields(list) + } + + const onSave = async () => { + try { + let value = { + allowedOrigins: { + ...inputFields + } + } + chatbotConfig.allowedOrigins = value.allowedOrigins + const saveResp = await chatflowsApi.updateChatflow(dialogProps.chatflow.id, { + chatbotConfig: JSON.stringify(chatbotConfig) + }) + if (saveResp.data) { + enqueueSnackbar({ + message: 'Allowed Origins Saved', + options: { + key: new Date().getTime() + Math.random(), + variant: 'success', + action: (key) => ( + + ) + } + }) + dispatch({ type: SET_CHATFLOW, chatflow: saveResp.data }) + } + onConfirm() + } catch (error) { + const errorData = error.response.data || `${error.response.status}: ${error.response.statusText}` + enqueueSnackbar({ + message: `Failed to save Allowed Origins: ${errorData}`, + options: { + key: new Date().getTime() + Math.random(), + variant: 'error', + persist: true, + action: (key) => ( + + ) + } + }) + } + } + + useEffect(() => { + if (dialogProps.chatflow && dialogProps.chatflow.chatbotConfig) { + try { + let chatbotConfig = JSON.parse(dialogProps.chatflow.chatbotConfig) + setChatbotConfig(chatbotConfig || {}) + if (chatbotConfig.allowedOrigins) { + let inputFields = [] + Object.getOwnPropertyNames(chatbotConfig.allowedOrigins).forEach((key) => { + if (chatbotConfig.allowedOrigins[key]) { + inputFields.push(chatbotConfig.allowedOrigins[key]) + } + }) + setInputFields(inputFields) + } else { + setInputFields([ + { + origin: '' + } + ]) + } + } catch (e) { + setInputFields([ + { + origin: '' + } + ]) + } + } + + return () => {} + }, [dialogProps]) + + useEffect(() => { + if (show) dispatch({ type: SHOW_CANVAS_DIALOG }) + else dispatch({ type: HIDE_CANVAS_DIALOG }) + return () => dispatch({ type: HIDE_CANVAS_DIALOG }) + }, [show, dispatch]) + + const component = show ? ( + + + {dialogProps.title || 'Allowed Origins'} + + +
+ Your chatbot will only work when used from the following domains +
+ :not(style)': { m: 1 }, pt: 2 }}> + + {inputFields.map((data, index) => { + return ( +
+ + handleChange(index, e)} + size='small' + value={data.prompt} + name='prompt' + endAdornment={ + + {inputFields.length > 1 && ( + removeInputFields(index)} + edge='end' + > + + + )} + + } + /> + + + {index === inputFields.length - 1 && ( + + + + )} + +
+ ) + })} +
+
+
+ + + + Save + + +
+ ) : null + + return createPortal(component, portalElement) +} + +AllowedDomainsDialog.propTypes = { + show: PropTypes.bool, + dialogProps: PropTypes.object, + onCancel: PropTypes.func, + onConfirm: PropTypes.func +} + +export default AllowedDomainsDialog diff --git a/packages/ui/src/views/canvas/CanvasHeader.js b/packages/ui/src/views/canvas/CanvasHeader.js index 85408cd8a67..094b382f15c 100644 --- a/packages/ui/src/views/canvas/CanvasHeader.js +++ b/packages/ui/src/views/canvas/CanvasHeader.js @@ -17,6 +17,7 @@ import APICodeDialog from 'views/chatflows/APICodeDialog' import AnalyseFlowDialog from 'ui-component/dialog/AnalyseFlowDialog' import ViewMessagesDialog from 'ui-component/dialog/ViewMessagesDialog' import StarterPromptsDialog from 'ui-component/dialog/StarterPromptsDialog' +import AllowedDomainsDialog from 'ui-component/dialog/AllowedDomainsDialog' // API import chatflowsApi from 'api/chatflows' @@ -50,6 +51,8 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl const [conversationStartersDialogProps, setConversationStartersDialogProps] = useState({}) const [viewMessagesDialogOpen, setViewMessagesDialogOpen] = useState(false) const [viewMessagesDialogProps, setViewMessagesDialogProps] = useState({}) + const [allowedDomainsDialogOpen, setAllowedDomainsDialogOpen] = useState(false) + const [allowedDomainsDialogProps, setAllowedDomainsDialogProps] = useState({}) const updateChatflowApi = useApi(chatflowsApi.updateChatflow) const canvas = useSelector((state) => state.canvas) @@ -65,6 +68,12 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl chatflow: chatflow }) setConversationStartersDialogOpen(true) + } else if (setting === 'allowedDomains') { + setAllowedDomainsDialogProps({ + title: 'Starter Prompts - ' + chatflow.name, + chatflow: chatflow + }) + setAllowedDomainsDialogOpen(true) } else if (setting === 'analyseChatflow') { setAnalyseDialogProps({ title: 'Analyse Chatflow', @@ -391,6 +400,12 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl onConfirm={() => setConversationStartersDialogOpen(false)} onCancel={() => setConversationStartersDialogOpen(false)} /> + setAllowedDomainsDialogOpen(false)} + onCancel={() => setAllowedDomainsDialogOpen(false)} + /> Date: Tue, 20 Feb 2024 17:00:45 +0530 Subject: [PATCH 02/11] Update dialog title and description --- packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js | 5 ++++- packages/ui/src/views/canvas/CanvasHeader.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js index 7048c29e2b2..38c97e8bf79 100644 --- a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js +++ b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js @@ -169,7 +169,10 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { flexDirection: 'column' }} > - Your chatbot will only work when used from the following domains + + Your chatbot will only work when used from the following domains. When adding domains, exclude the{' '} +
http://
or
https://
part. +
:not(style)': { m: 1 }, pt: 2 }}> diff --git a/packages/ui/src/views/canvas/CanvasHeader.js b/packages/ui/src/views/canvas/CanvasHeader.js index 094b382f15c..e9c0b7f00ce 100644 --- a/packages/ui/src/views/canvas/CanvasHeader.js +++ b/packages/ui/src/views/canvas/CanvasHeader.js @@ -70,7 +70,7 @@ const CanvasHeader = ({ chatflow, handleSaveFlow, handleDeleteFlow, handleLoadFl setConversationStartersDialogOpen(true) } else if (setting === 'allowedDomains') { setAllowedDomainsDialogProps({ - title: 'Starter Prompts - ' + chatflow.name, + title: 'Allowed Domains - ' + chatflow.name, chatflow: chatflow }) setAllowedDomainsDialogOpen(true) From ce16fd94f9eb1acb9cbe410d1288e356aa5a4f8b Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 27 Feb 2024 09:44:31 +0530 Subject: [PATCH 03/11] Add logging to allowed domains checks --- packages/server/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 5c1f41313fe..c78f1d5dbad 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1224,8 +1224,10 @@ export class App { }) if (!chatflow) return res.status(404).send(`Chatflow ${req.params.id} not found`) let isDomainAllowed = true + logger.debug(`[server]: Request originated from ${req.headers.host}`) if (chatflow.chatbotConfig) { const parsedConfig = JSON.parse(chatflow.chatbotConfig) + logger.debug(`[server]: Chatflow ${req.params.id} has config ${chatflow.chatbotConfig}`) if (parsedConfig.allowedDomains && parsedConfig.allowedDomains.length > 0) { isDomainAllowed = parsedConfig.allowedDomains.includes(req.headers.host) } From c07e908fefe23b55f21c11f3116ede6e2c82cdf2 Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 27 Feb 2024 11:46:41 +0530 Subject: [PATCH 04/11] Update condition for checking allowed origins --- packages/server/src/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index c78f1d5dbad..fa9562ef16f 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1224,12 +1224,11 @@ export class App { }) if (!chatflow) return res.status(404).send(`Chatflow ${req.params.id} not found`) let isDomainAllowed = true - logger.debug(`[server]: Request originated from ${req.headers.host}`) + logger.info(`[server]: Request originated from ${req.headers.host}`) if (chatflow.chatbotConfig) { const parsedConfig = JSON.parse(chatflow.chatbotConfig) - logger.debug(`[server]: Chatflow ${req.params.id} has config ${chatflow.chatbotConfig}`) - if (parsedConfig.allowedDomains && parsedConfig.allowedDomains.length > 0) { - isDomainAllowed = parsedConfig.allowedDomains.includes(req.headers.host) + if (parsedConfig.allowedOrigins && parsedConfig.allowedOrigins.length > 0) { + isDomainAllowed = parsedConfig.allowedOrigins.includes(req.headers.host) } } From 7d76c127f1276431ca531ddc3daf2ad8e5766d86 Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 27 Feb 2024 11:47:58 +0530 Subject: [PATCH 05/11] Update how allowed origins are saved in chatbot config --- .../dialog/AllowedDomainsDialog.js | 46 +++++-------------- 1 file changed, 11 insertions(+), 35 deletions(-) diff --git a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js index 38c97e8bf79..9a8968e2187 100644 --- a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js +++ b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js @@ -38,21 +38,12 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { const enqueueSnackbar = (...args) => dispatch(enqueueSnackbarAction(...args)) const closeSnackbar = (...args) => dispatch(closeSnackbarAction(...args)) - const [inputFields, setInputFields] = useState([ - { - origin: '' - } - ]) + const [inputFields, setInputFields] = useState(['']) const [chatbotConfig, setChatbotConfig] = useState({}) const addInputField = () => { - setInputFields([ - ...inputFields, - { - origin: '' - } - ]) + setInputFields([...inputFields, '']) } const removeInputFields = (index) => { const rows = [...inputFields] @@ -61,18 +52,16 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { } const handleChange = (index, evnt) => { - const { name, value } = evnt.target + const { value } = evnt.target const list = [...inputFields] - list[index][name] = value + list[index] = value setInputFields(list) } const onSave = async () => { try { let value = { - allowedOrigins: { - ...inputFields - } + allowedOrigins: [...inputFields] } chatbotConfig.allowedOrigins = value.allowedOrigins const saveResp = await chatflowsApi.updateChatflow(dialogProps.chatflow.id, { @@ -118,26 +107,13 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { let chatbotConfig = JSON.parse(dialogProps.chatflow.chatbotConfig) setChatbotConfig(chatbotConfig || {}) if (chatbotConfig.allowedOrigins) { - let inputFields = [] - Object.getOwnPropertyNames(chatbotConfig.allowedOrigins).forEach((key) => { - if (chatbotConfig.allowedOrigins[key]) { - inputFields.push(chatbotConfig.allowedOrigins[key]) - } - }) + let inputFields = [...chatbotConfig.allowedOrigins] setInputFields(inputFields) } else { - setInputFields([ - { - origin: '' - } - ]) + setInputFields(['']) } } catch (e) { - setInputFields([ - { - origin: '' - } - ]) + setInputFields(['']) } } @@ -176,7 +152,7 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { :not(style)': { m: 1 }, pt: 2 }}> - {inputFields.map((data, index) => { + {inputFields.map((origin, index) => { return (
@@ -186,8 +162,8 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { type='text' onChange={(e) => handleChange(index, e)} size='small' - value={data.prompt} - name='prompt' + value={origin} + name='origin' endAdornment={ {inputFields.length > 1 && ( From 930bdd5c5185750e6096fe070021cf2ddd0b2886 Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 27 Feb 2024 12:54:01 +0530 Subject: [PATCH 06/11] Fix how allowed domains are checked - origin not host --- packages/server/src/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index fa9562ef16f..ed666698653 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1224,11 +1224,13 @@ export class App { }) if (!chatflow) return res.status(404).send(`Chatflow ${req.params.id} not found`) let isDomainAllowed = true - logger.info(`[server]: Request originated from ${req.headers.host}`) + logger.info(`[server]: Request originated from ${req.headers.origin}`) if (chatflow.chatbotConfig) { const parsedConfig = JSON.parse(chatflow.chatbotConfig) if (parsedConfig.allowedOrigins && parsedConfig.allowedOrigins.length > 0) { - isDomainAllowed = parsedConfig.allowedOrigins.includes(req.headers.host) + const originHeader = req.headers.origin as string + const origin = new URL(originHeader).host + isDomainAllowed = parsedConfig.allowedOrigins.includes(origin) } } From f477c74e0ea335e7d509692bbc373f42b230554d Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 27 Feb 2024 15:51:23 +0530 Subject: [PATCH 07/11] Fix allowed origins not working when they're all removed --- packages/server/src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index ed666698653..ef73ab5f59f 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1227,7 +1227,9 @@ export class App { logger.info(`[server]: Request originated from ${req.headers.origin}`) if (chatflow.chatbotConfig) { const parsedConfig = JSON.parse(chatflow.chatbotConfig) - if (parsedConfig.allowedOrigins && parsedConfig.allowedOrigins.length > 0) { + // check whether the first one is not empty. if it is empty that means the user set a value and then removed it. + const isValidAllowedOrigins = parsedConfig.allowedOrigins[0] !== '' + if (parsedConfig.allowedOrigins && parsedConfig.allowedOrigins.length > 0 && isValidAllowedOrigins) { const originHeader = req.headers.origin as string const origin = new URL(originHeader).host isDomainAllowed = parsedConfig.allowedOrigins.includes(origin) From d0ddf018c790800db40eff4ebb1c6558ed206c09 Mon Sep 17 00:00:00 2001 From: Ilango Date: Wed, 28 Feb 2024 18:45:34 +0530 Subject: [PATCH 08/11] Update access denied error message --- packages/server/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 0e1410abb32..d18111e305c 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1339,7 +1339,7 @@ export class App { if (isDomainAllowed) { await this.buildChatflow(req, res, socketIO) } else { - return res.status(401).send(`This domain is not allowed to access chatflow ${req.params.id}`) + return res.status(401).send(`This site is not allowed to access this chatbot`) } } ) From d706ca389fc744740147ff59e1567b8d45b9ee93 Mon Sep 17 00:00:00 2001 From: Ilango Date: Tue, 5 Mar 2024 17:23:49 +0530 Subject: [PATCH 09/11] Detect host from list of allowed urls even if they have http/https --- packages/server/src/index.ts | 6 +++++- packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js | 5 +---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index d18111e305c..260bbdb4e31 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1332,7 +1332,11 @@ export class App { if (parsedConfig.allowedOrigins && parsedConfig.allowedOrigins.length > 0 && isValidAllowedOrigins) { const originHeader = req.headers.origin as string const origin = new URL(originHeader).host - isDomainAllowed = parsedConfig.allowedOrigins.includes(origin) + isDomainAllowed = + parsedConfig.allowedOrigins.filter((domain: string) => { + const allowedOrigin = new URL(domain).host + return origin === allowedOrigin + }).length > 0 } } diff --git a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js index 9a8968e2187..426ea1318ea 100644 --- a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js +++ b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js @@ -145,10 +145,7 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { flexDirection: 'column' }} > - - Your chatbot will only work when used from the following domains. When adding domains, exclude the{' '} -
http://
or
https://
part. -
+ Your chatbot will only work when used from the following domains.
:not(style)': { m: 1 }, pt: 2 }}> From 07503f9be8ad57adec8b885f95b274478322c37c Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 7 Mar 2024 19:08:10 +0800 Subject: [PATCH 10/11] add placeholder --- packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js index 426ea1318ea..8fd57fb6ff0 100644 --- a/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js +++ b/packages/ui/src/ui-component/dialog/AllowedDomainsDialog.js @@ -161,6 +161,7 @@ const AllowedDomainsDialog = ({ show, dialogProps, onCancel, onConfirm }) => { size='small' value={origin} name='origin' + placeholder='https://example.com' endAdornment={ {inputFields.length > 1 && ( From 3b84e718a2a0ba5ddd78fd2d077ea7994cdaa50b Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 7 Mar 2024 19:22:33 +0800 Subject: [PATCH 11/11] fix isValidAllowedOrigins check and invalid URL --- packages/server/src/index.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 260bbdb4e31..fd0635c5ff6 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1328,14 +1328,18 @@ export class App { if (chatflow.chatbotConfig) { const parsedConfig = JSON.parse(chatflow.chatbotConfig) // check whether the first one is not empty. if it is empty that means the user set a value and then removed it. - const isValidAllowedOrigins = parsedConfig.allowedOrigins[0] !== '' - if (parsedConfig.allowedOrigins && parsedConfig.allowedOrigins.length > 0 && isValidAllowedOrigins) { + const isValidAllowedOrigins = parsedConfig.allowedOrigins?.length && parsedConfig.allowedOrigins[0] !== '' + if (isValidAllowedOrigins) { const originHeader = req.headers.origin as string const origin = new URL(originHeader).host isDomainAllowed = parsedConfig.allowedOrigins.filter((domain: string) => { - const allowedOrigin = new URL(domain).host - return origin === allowedOrigin + try { + const allowedOrigin = new URL(domain).host + return origin === allowedOrigin + } catch (e) { + return false + } }).length > 0 } }