* Validates if the origin is allowed for a specific chatflow * @param chatflowId - The chatflow ID to validate against * @param origin - The origin URL to validate * @param workspaceId - Optional workspace ID for enterprise features * @returns Promise - True if domain is allowed, false
(chatflowId: string, origin: string, workspaceId?: string)
| 20 | * @returns Promise<boolean> - True if domain is allowed, false otherwise |
| 21 | */ |
| 22 | async function validateChatflowDomain(chatflowId: string, origin: string, workspaceId?: string): Promise<boolean> { |
| 23 | try { |
| 24 | if (!chatflowId || !isValidUUID(chatflowId)) { |
| 25 | throw new Error('Invalid chatflowId format - must be a valid UUID') |
| 26 | } |
| 27 | |
| 28 | const chatflow = workspaceId |
| 29 | ? await chatflowsService.getChatflowById(chatflowId, workspaceId) |
| 30 | : await chatflowsService.getChatflowById(chatflowId) |
| 31 | |
| 32 | if (!chatflow?.chatbotConfig) { |
| 33 | return true |
| 34 | } |
| 35 | |
| 36 | const config = JSON.parse(chatflow.chatbotConfig) |
| 37 | |
| 38 | // If no allowed origins configured or first entry is empty, allow all |
| 39 | if (!config.allowedOrigins?.length || config.allowedOrigins[0] === '') { |
| 40 | return true |
| 41 | } |
| 42 | |
| 43 | const originHost = new URL(origin).host |
| 44 | const isAllowed = config.allowedOrigins.some((domain: string) => { |
| 45 | try { |
| 46 | const allowedOrigin = new URL(domain).host |
| 47 | return originHost === allowedOrigin |
| 48 | } catch (error) { |
| 49 | logger.warn(`Invalid domain format in allowedOrigins: ${domain}`) |
| 50 | return false |
| 51 | } |
| 52 | }) |
| 53 | |
| 54 | return isAllowed |
| 55 | } catch (error) { |
| 56 | logger.error(`Error validating domain for chatflow ${chatflowId}:`, error) |
| 57 | return false |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | // NOTE: This function extracts the chatflow ID from a prediction URL. |
| 62 | // It assumes the URL format is /prediction/{chatflowId}. |
no test coverage detected