diff --git a/backend/common/utils/utils.py b/backend/common/utils/utils.py
index 8d3fc808..ec8c0d85 100644
--- a/backend/common/utils/utils.py
+++ b/backend/common/utils/utils.py
@@ -6,6 +6,7 @@
from datetime import datetime, timedelta, timezone
from logging.handlers import RotatingFileHandler
from pathlib import Path
+import re
from urllib.parse import urlparse
from fastapi import Request
@@ -266,9 +267,14 @@ def get_origin_from_referer(request: Request):
def origin_match_domain(origin: str, domain: str) -> bool:
if not origin or not domain:
return False
- origin_text = origin.rstrip('/')
- domain_list = domain.replace(" ", "").split(',')
- return origin_text in [d.rstrip('/') for d in domain_list]
+ origin_normalized = origin.rstrip('/')
+
+ for d in re.split(r'[,;]', domain):
+ if d.strip().rstrip('/') == origin_normalized:
+ return True
+
+ return False
+
def equals_ignore_case(str1: str, *args: str) -> bool:
if str1 is None:
diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json
index 88857d2c..259afd4b 100644
--- a/frontend/src/i18n/en.json
+++ b/frontend/src/i18n/en.json
@@ -577,7 +577,7 @@
"application_name": "Application name",
"application_description": "Application description",
"cross_domain_settings": "Cross-domain settings",
- "third_party_address": "Please enter the embedded third party address",
+ "third_party_address": "Please enter the embedded third party address,multiple items separated by semicolons",
"set_to_private": "Set as private",
"set_to_public": "Set as public",
"public": "Public",
@@ -586,7 +586,7 @@
"configure_interface": "Configure interface",
"interface_url": "Interface URL",
"format_is_incorrect": "format is incorrect{msg}",
- "domain_format_incorrect": ",start with http/https, no trailing slash (/), multiple domains separated by half-width commas (,)",
+ "domain_format_incorrect": ", start with http:// or https://, no trailing slash (/), multiple domains separated by semicolons",
"interface_url_incorrect": ",enter a relative path starting with /",
"aes_enable": "Enable AES encryption",
"aes_enable_tips": "The fields (host, user, password, dataBase, schema) are all encrypted using the AES-CBC-PKCS5Padding encryption method",
diff --git a/frontend/src/i18n/ko-KR.json b/frontend/src/i18n/ko-KR.json
index b86b6252..a79aa92e 100644
--- a/frontend/src/i18n/ko-KR.json
+++ b/frontend/src/i18n/ko-KR.json
@@ -577,7 +577,7 @@
"application_name": "애플리케이션 이름",
"application_description": "애플리케이션 설명",
"cross_domain_settings": "교차 도메인 설정",
- "third_party_address": "임베디드할 제3자 주소를 입력하십시오",
+ "third_party_address": "임베디드할 제3자 주소를 입력하십시오, 여러 항목을 세미콜론으로 구분",
"set_to_private": "비공개로 설정",
"set_to_public": "공개로 설정",
"public": "공개",
@@ -585,7 +585,7 @@
"configure_interface": "인터페이스 설정",
"interface_url": "인터페이스 URL",
"format_is_incorrect": "형식이 올바르지 않습니다{msg}",
- "domain_format_incorrect": ", http/https로 시작, 슬래시(/)로 끝나지 않음, 여러 도메인은 반각 쉼표(,)로 구분",
+ "domain_format_incorrect": ", http:// 또는 https://로 시작해야 하며, 슬래시(/)로 끝날 수 없습니다. 여러 도메인은 세미콜론으로 구분합니다",
"interface_url_incorrect": ", 상대 경로를 입력해주세요. /로 시작합니다",
"aes_enable": "AES 암호화 활성화",
"aes_enable_tips": "암호화 필드 (host, user, password, dataBase, schema)는 모두 AES-CBC-PKCS5Padding 암호화 방식을 사용합니다",
diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json
index fa93317e..65917ec8 100644
--- a/frontend/src/i18n/zh-CN.json
+++ b/frontend/src/i18n/zh-CN.json
@@ -577,7 +577,7 @@
"application_name": "应用名称",
"application_description": "应用描述",
"cross_domain_settings": "跨域设置",
- "third_party_address": "请输入嵌入的第三方地址",
+ "third_party_address": "请输入嵌入的第三方地址,多个以分号分割",
"set_to_private": "设为私有",
"set_to_public": "设为公共",
"public": "公共",
@@ -585,7 +585,7 @@
"configure_interface": "配置接口",
"interface_url": "接口 URL",
"format_is_incorrect": "格式不对{msg}",
- "domain_format_incorrect": ",http或https开头,不能以 / 结尾,多个域名以逗号(半角)分隔",
+ "domain_format_incorrect": ",http或https开头,不能以 / 结尾,多个域名以分号(半角)分隔",
"interface_url_incorrect": ",请填写相对路径,以/开头",
"aes_enable": "开启 AES 加密",
"aes_enable_tips": "加密字段 (host, user, password, dataBase, schema) 均采用 AES-CBC-PKCS5Padding 加密方式",
diff --git a/frontend/src/views/system/embedded/Page.vue b/frontend/src/views/system/embedded/Page.vue
index 42784bdc..d14024e4 100644
--- a/frontend/src/views/system/embedded/Page.vue
+++ b/frontend/src/views/system/embedded/Page.vue
@@ -198,7 +198,15 @@ const search = () => {
searchLoading.value = false
})
}
-
+const splitString = (str: string) => {
+ if (typeof str !== 'string') {
+ return []
+ }
+ return str
+ .split(/[,;]/)
+ .map((item) => item.trim())
+ .filter((item) => item !== '')
+}
const termFormRef = ref()
const validateUrl = (_: any, value: any, callback: any) => {
if (value === '') {
@@ -209,20 +217,15 @@ const validateUrl = (_: any, value: any, callback: any) => {
)
} else {
// var Expression = /(https?:\/\/)?([\da-z\.-]+)\.([a-z]{2,6})(:\d{1,5})?([\/\w\.-]*)*\/?(#[\S]+)?/ // eslint-disable-line
- value
- .trim()
- .split(',')
- .forEach((tempVal: string) => {
- var Expression = /^https?:\/\/[^\s/?#]+(:\d+)?/i
- var objExp = new RegExp(Expression)
- if (objExp.test(tempVal) && !tempVal.endsWith('/')) {
- callback()
- } else {
- callback(
- t('embedded.format_is_incorrect', { msg: t('embedded.domain_format_incorrect') })
- )
- }
- })
+ splitString(value).forEach((tempVal: string) => {
+ var Expression = /^https?:\/\/[^\s/?#]+(:\d+)?/i
+ var objExp = new RegExp(Expression)
+ if (objExp.test(tempVal) && !tempVal.endsWith('/')) {
+ callback()
+ } else {
+ callback(t('embedded.format_is_incorrect', { msg: t('embedded.domain_format_incorrect') }))
+ }
+ })
}
}
const rules = {
@@ -602,13 +605,10 @@ const copyCode = (row: any, key: any = 'app_secret') => {
diff --git a/frontend/src/views/system/embedded/iframe.vue b/frontend/src/views/system/embedded/iframe.vue
index 61becbde..89ea2052 100644
--- a/frontend/src/views/system/embedded/iframe.vue
+++ b/frontend/src/views/system/embedded/iframe.vue
@@ -265,6 +265,15 @@ const setUiRef = ref()
const handleSetUi = (row: any) => {
setUiRef.value.open(row)
}
+const splitString = (str: string) => {
+ if (typeof str !== 'string') {
+ return []
+ }
+ return str
+ .split(/[,;]/)
+ .map((item) => item.trim())
+ .filter((item) => item !== '')
+}
const validateUrl = (_: any, value: any, callback: any) => {
if (value === '') {
callback(
@@ -274,20 +283,15 @@ const validateUrl = (_: any, value: any, callback: any) => {
)
} else {
// var Expression = /(https?:\/\/)?([\da-z\.-]+)\.([a-z]{2,6})(:\d{1,5})?([\/\w\.-]*)*\/?(#[\S]+)?/ // eslint-disable-line
- value
- .trim()
- .split(',')
- .forEach((tempVal: string) => {
- var Expression = /^https?:\/\/[^\s/?#]+(:\d+)?/i
- var objExp = new RegExp(Expression)
- if (objExp.test(tempVal) && !tempVal.endsWith('/')) {
- callback()
- } else {
- callback(
- t('embedded.format_is_incorrect', { msg: t('embedded.domain_format_incorrect') })
- )
- }
- })
+ splitString(value).forEach((tempVal: string) => {
+ var Expression = /^https?:\/\/[^\s/?#]+(:\d+)?/i
+ var objExp = new RegExp(Expression)
+ if (objExp.test(tempVal) && !tempVal.endsWith('/')) {
+ callback()
+ } else {
+ callback(t('embedded.format_is_incorrect', { msg: t('embedded.domain_format_incorrect') }))
+ }
+ })
}
}
const rules = {
@@ -759,6 +763,8 @@ const saveHandler = () => {