Commit e6584acf by Archer Committed by GitHub

fix: correct export config sensitive filter behavior (#6782)

* fix: correct export config sensitive filter behavior (#6778)

* docs (#6779)

---------

Co-authored-by: Ryo <whoeverimf5@gmail.com>
parent 9d1cafce
......@@ -3,15 +3,27 @@ title: 'V4.14.11(进行中)'
description: 'FastGPT V4.14.11 更新说明'
---
{/* ## 升级指南
## 升级指南
### 1. 更新镜像 tag
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.11
- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.1011
- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.11
- 更新 code-sandbox 镜像 tag: v4.14.11
- 更新 fastgpt-plugin 镜像 tag: v0.6.0
- 更新 Aiproxy 镜像 tag: v0.5.3 */}
- 更新 Aiproxy 镜像 tag: v0.5.3
### 2. 更新环境变量
> 以下环境变量均设置了默认值,可不填或不改
```dotenv
STREAM_RESUME_TTL_SECONDS=300 # Redis 流式镜像续期:生成中(秒)
STREAM_RESUME_POST_COMPLETE_TTL_SECONDS=30 # 流结束后缩短 TTL,便于回收(秒)
STREAM_RESUME_REDIS_MAXMEMORY_RATIO=0.5 # 当 Redis 已用内存 / maxmemory 达到该阈值时,停止为新请求创建流恢复镜像
STREAM_RESUME_REDIS_MEMORY_CHECK_INTERVAL_MS=5000 # Redis 内存水位检测缓存时长(毫秒),避免每个流请求都调用 INFO MEMORY
WORKFLOW_PARALLEL_MAX_CONCURRENCY=10 # 最大并发数的上限值,不能超过 WORKFLOW_MAX_LOOP_TIMES 变量
```
## 🚀 新增内容
......@@ -39,4 +51,4 @@ description: 'FastGPT V4.14.11 更新说明'
8. 工作流代码运行节点,AI 生成代码后,会讲输出值的 id 全部替换,优化成相同 key 的 id 不替换。
9. 工作流中,父级节点受到辅助线自动对齐时候,其子节点位置会偏移。
10. 评估列表权限过滤未覆盖继承权限。
11. MCP 工具和 Http 工具 raw schema 未成功保存,导致工具调用时候,schema 不准确。
\ No newline at end of file
11. MCP 工具和 Http 工具 raw schema 未成功保存,导致工具调用时候,schema 不准确。
......@@ -3,12 +3,17 @@ title: 'V4.14.12'
description: 'FastGPT V4.14.12 更新说明'
---
## 升级指南
### 1. 更新镜像 tag
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.12
- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.12
## 🐛 修复
1. 知识库三级目录 path 接口报 zod 校验出错。
2. v1/completions 接口 dataId 异常,导致 api 调用时候,对话日志里无法获取到运行详情。
3. 对话 Agent 应用敏感信息过滤勾选框无法取消。
## 🚀 新增内容
......@@ -18,4 +23,3 @@ description: 'FastGPT V4.14.12 更新说明'
## ⚙️ 优化
1. skill 接口错误处理。
......@@ -225,7 +225,7 @@
"document/content/docs/self-host/upgrading/4-14/41410.en.mdx": "2026-03-31T23:15:29+08:00",
"document/content/docs/self-host/upgrading/4-14/41410.mdx": "2026-04-18T20:47:39+08:00",
"document/content/docs/self-host/upgrading/4-14/41411.mdx": "2026-04-18T20:47:39+08:00",
"document/content/docs/self-host/upgrading/4-14/41412.mdx": "2026-04-20T15:54:50+08:00",
"document/content/docs/self-host/upgrading/4-14/41412.mdx": "2026-04-20T16:57:11+08:00",
"document/content/docs/self-host/upgrading/4-14/4142.en.mdx": "2026-03-03T17:39:47+08:00",
"document/content/docs/self-host/upgrading/4-14/4142.mdx": "2026-03-03T17:39:47+08:00",
"document/content/docs/self-host/upgrading/4-14/4143.en.mdx": "2026-03-03T17:39:47+08:00",
......
......@@ -782,6 +782,7 @@
"failed": "Failed",
"field_name": "Field Name",
"filter_sensitive_info": "Filter sensitive information",
"filter_sensitive_info_tip": "Sensitive information includes temporary keys used by system tools (leaks may cause unexpected charges, so export carefully) and dataset information configured in dataset search nodes.",
"folder.empty": "No More Items in This Directory",
"folder.open_dataset": "Open Dataset",
"folder_description": "Folder Description",
......
......@@ -782,6 +782,7 @@
"failed": "失败",
"field_name": "字段名",
"filter_sensitive_info": "过滤敏感信息",
"filter_sensitive_info_tip": "敏感信息范围:【系统工具】使用的临时密钥(泄露可能导致意外扣费,请谨慎导出),以及【知识库搜索节点】配置的知识库信息",
"folder.empty": "这个目录已经没东西可选了~",
"folder.open_dataset": "打开知识库",
"folder_description": "文件夹描述",
......
......@@ -776,6 +776,7 @@
"failed": "失敗",
"field_name": "欄位名稱",
"filter_sensitive_info": "過濾敏感信息",
"filter_sensitive_info_tip": "敏感資訊範圍:【系統工具】使用的臨時密鑰(外洩可能導致意外扣費,請謹慎匯出),以及【知識庫搜尋節點】配置的知識庫資訊",
"folder.empty": "此目錄中沒有更多項目了",
"folder.open_dataset": "開啟知識庫",
"folder_description": "資料夾描述",
......
......@@ -49,6 +49,7 @@ const AppCard = ({
const appId = appDetail._id;
const { feConfigs } = useSystemStore();
const [TeamTagsSet, setTeamTagsSet] = useState<AppSchemaType>();
const [filterSensitiveInfo, setFilterSensitiveInfo] = useState(true);
// transition to workflow
const [transitionCreateNew, setTransitionCreateNew] = useState<boolean>();
......@@ -148,6 +149,8 @@ const AppCard = ({
appName={appDetail.name}
appForm={appForm}
chatConfig={appDetail.chatConfig}
filterSensitiveInfo={filterSensitiveInfo}
onFilterSensitiveInfoChange={setFilterSensitiveInfo}
/>
</Flex>
)
......
......@@ -13,16 +13,13 @@ import { filterSensitiveFormData } from '@/web/core/app/utils';
import { type RequireOnlyOne } from '@fastgpt/global/common/type/utils';
import { type StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
import { type StoreEdgeItemType } from '@fastgpt/global/core/workflow/type/edge';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
const ExportConfigPopover = ({
appForm,
getWorkflowData,
chatConfig,
appName
}: {
type ExportConfigPopoverProps = {
appName: string;
chatConfig?: AppChatConfigType;
filterSensitiveInfo?: boolean;
onFilterSensitiveInfoChange?: (value: boolean) => void;
} & RequireOnlyOne<{
getWorkflowData: () =>
| {
......@@ -31,11 +28,32 @@ const ExportConfigPopover = ({
}
| undefined;
appForm: AppFormEditFormType;
}>) => {
}>;
const ExportConfigPopover = ({
appForm,
getWorkflowData,
chatConfig,
appName,
filterSensitiveInfo: filterSensitiveInfoProp,
onFilterSensitiveInfoChange
}: ExportConfigPopoverProps) => {
const { t } = useTranslation();
const { copyData } = useCopyData();
const [filterSensitiveInfo, setFilterSensitiveInfo] = useState<boolean>(true);
const [localFilterSensitiveInfo, setLocalFilterSensitiveInfo] = useState<boolean>(true);
const filterSensitiveInfo = filterSensitiveInfoProp ?? localFilterSensitiveInfo;
const setFilterSensitiveInfo = useCallback(
(value: boolean) => {
onFilterSensitiveInfoChange?.(value);
if (filterSensitiveInfoProp === undefined) {
setLocalFilterSensitiveInfo(value);
}
},
[filterSensitiveInfoProp, onFilterSensitiveInfoChange]
);
const onExportWorkflow = useCallback(
async (mode: 'copy' | 'json') => {
......@@ -91,7 +109,7 @@ const ExportConfigPopover = ({
offset={[0, 20]}
hasArrow
trigger={'hover'}
w={'8.6rem'}
w={'8.8rem'}
Trigger={
<MyBox display={'flex'} cursor={'pointer'} onClick={(e) => e.stopPropagation()}>
<MyIcon name={'export'} w={'16px'} mr={2} />
......@@ -137,6 +155,7 @@ const ExportConfigPopover = ({
<Flex
py={'0.38rem'}
px={1}
alignItems={'center'}
color={'myGray.600'}
_hover={{
bg: 'myGray.05',
......@@ -147,6 +166,7 @@ const ExportConfigPopover = ({
onClick={() => setFilterSensitiveInfo(!filterSensitiveInfo)}
>
<Checkbox
flex={1}
size="sm"
colorScheme="primary"
isChecked={filterSensitiveInfo}
......@@ -154,6 +174,20 @@ const ExportConfigPopover = ({
>
<Box fontSize={'mini'}>{t('common:filter_sensitive_info')}</Box>
</Checkbox>
<Box
display={'flex'}
alignItems={'center'}
ml={1}
flexShrink={0}
onClick={(e) => e.stopPropagation()}
onMouseDown={(e) => e.stopPropagation()}
>
<QuestionTip
color={'inherit'}
maxW={'320px'}
label={t('common:filter_sensitive_info_tip')}
/>
</Box>
</Flex>
</Box>
)}
......
......@@ -14,7 +14,14 @@ export function filterSensitiveFormData(appForm: AppFormEditFormType) {
const defaultAppForm = getDefaultAppForm();
return {
...appForm,
dataset: defaultAppForm.dataset
dataset: defaultAppForm.dataset,
selectedTools: appForm.selectedTools.map((tool) => ({
...tool,
inputs: tool.inputs.map((input) => ({
...input,
value: input.key === NodeInputKeyEnum.systemInputConfig ? undefined : input.value
}))
}))
};
}
......
......@@ -96,6 +96,15 @@ describe('form2AppWorkflow', () => {
describe('filterSensitiveFormData', () => {
it('should filter sensitive data from app form', () => {
const toolSecretValue = {
type: 'manual',
value: {
apiKey: {
secret: '',
value: 'secret-key'
}
}
};
const appForm: AppFormEditFormType = {
aiSettings: {
[NodeInputKeyEnum.aiModel]: 'gpt-4',
......@@ -123,15 +132,49 @@ describe('filterSensitiveFormData', () => {
datasetSearchExtensionModel: '',
datasetSearchExtensionBg: ''
},
selectedTools: [],
selectedTools: [
{
id: 'tool-1',
pluginId: 'plugin-1',
flowNodeType: FlowNodeTypeEnum.tool,
templateType: 'other',
name: 'Weather Tool',
avatar: '',
intro: '',
inputs: [
{
key: NodeInputKeyEnum.systemInputConfig,
value: toolSecretValue,
renderTypeList: [],
valueType: 'any'
},
{
key: NodeInputKeyEnum.history,
value: 5,
renderTypeList: [],
valueType: 'number'
}
],
outputs: []
} as any
],
chatConfig: {}
};
const result = filterSensitiveFormData(appForm);
const defaultForm = getDefaultAppForm();
const resultSecretInput = result.selectedTools[0].inputs.find(
(input) => input.key === NodeInputKeyEnum.systemInputConfig
);
const resultHistoryInput = result.selectedTools[0].inputs.find(
(input) => input.key === NodeInputKeyEnum.history
);
expect(result.dataset).toEqual(defaultForm.dataset);
expect(result.aiSettings).toEqual(appForm.aiSettings);
expect(resultSecretInput?.value).toBeUndefined();
expect(resultHistoryInput?.value).toBe(5);
expect(appForm.selectedTools[0].inputs[0].value).toEqual(toolSecretValue);
});
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment