diff --git a/frontend/app/(main)/waf/rules/editor/components/node-properties.test.tsx b/frontend/app/(main)/waf/rules/editor/components/node-properties.test.tsx
index 9ec88e2a..bb4f8483 100644
--- a/frontend/app/(main)/waf/rules/editor/components/node-properties.test.tsx
+++ b/frontend/app/(main)/waf/rules/editor/components/node-properties.test.tsx
@@ -5,7 +5,7 @@ import type { WAFIPGroup, WAFRuleNode } from '@/lib/services/openflare';
import { NodeProperties } from './node-properties';
-it('toggles UA check switches and match mode', () => {
+it('hides match and block until UA check is enabled', () => {
const node: WAFRuleNode = {
id: 'ua',
type: 'ua_check',
@@ -20,17 +20,31 @@ it('toggles UA check switches and match mode', () => {
},
};
const onChange = vi.fn();
- render();
+ const { rerender } = render(
+ ,
+ );
+ expect(screen.queryByLabelText('屏蔽常见爬虫 UA')).not.toBeInTheDocument();
+ expect(screen.queryByLabelText('浏览器')).not.toBeInTheDocument();
fireEvent.click(screen.getByLabelText('开启 UA 检查'));
expect(onChange).toHaveBeenCalledWith(
expect.objectContaining({
config: expect.objectContaining({ require_ua: true }),
}),
);
+ rerender(
+ ,
+ );
expect(screen.getByLabelText('屏蔽常见爬虫 UA')).toBeInTheDocument();
expect(screen.getByLabelText('屏蔽非正常 UA')).toBeInTheDocument();
expect(
- screen.getByText('命中返回 false,优先级高于匹配'),
+ screen.getByText(/浏览器或操作系统分类为 Bot/),
+ ).toBeInTheDocument();
+ expect(
+ screen.getByText(/浏览器分类为 Bot、Other 或 Unknown/),
).toBeInTheDocument();
});
diff --git a/frontend/app/(main)/waf/rules/editor/components/node-properties.tsx b/frontend/app/(main)/waf/rules/editor/components/node-properties.tsx
index f659ea7b..0b5cdda4 100644
--- a/frontend/app/(main)/waf/rules/editor/components/node-properties.tsx
+++ b/frontend/app/(main)/waf/rules/editor/components/node-properties.tsx
@@ -154,7 +154,7 @@ function PropertyFields({
开启 UA 检查
- 开启后如果请求头不携带 UA 返回 False
+ 开启后如果请求头不携带 UA 返回 False;并可配置匹配与屏蔽
-
-
-
UA 匹配
-
- 匹配模式
-
-
- 浏览器与操作系统两侧都有选择时生效
-
-
-
({
- value: option.value,
- label: option.label,
- searchText: `${option.label} ${option.value}`,
- }))}
- value={node.config.browsers}
- onChange={(browsers) =>
- onChange({ ...node, config: { ...node.config, browsers } })
- }
- />
- ({
- value: option.value,
- label: option.label,
- searchText: `${option.label} ${option.value}`,
- }))}
- value={node.config.operating_systems}
- onChange={(operating_systems) =>
- onChange({
- ...node,
- config: { ...node.config, operating_systems },
- })
- }
- />
-
-
-
-
-
屏蔽
-
命中返回 false,优先级高于匹配
-
-
-
- 屏蔽常见爬虫 UA
-
-
- onChange({
- ...node,
- config: { ...node.config, block_common_bots },
- })
- }
- />
-
-
-
- 屏蔽非正常 UA
-
-
- onChange({
- ...node,
- config: { ...node.config, block_abnormal_ua },
- })
- }
- />
-
-
+ {node.config.require_ua && (
+ <>
+
+
+
+ UA 匹配
+
+
+
+ 匹配模式
+
+
+
+ 浏览器与操作系统两侧都有选择时生效
+
+
+
({
+ value: option.value,
+ label: option.label,
+ searchText: `${option.label} ${option.value}`,
+ }))}
+ value={node.config.browsers}
+ onChange={(browsers) =>
+ onChange({ ...node, config: { ...node.config, browsers } })
+ }
+ />
+ ({
+ value: option.value,
+ label: option.label,
+ searchText: `${option.label} ${option.value}`,
+ }))}
+ value={node.config.operating_systems}
+ onChange={(operating_systems) =>
+ onChange({
+ ...node,
+ config: { ...node.config, operating_systems },
+ })
+ }
+ />
+
+
+
+
+
+ 屏蔽
+
+
+ 命中返回 false,优先级高于匹配
+
+
+
+
+
+ 屏蔽常见爬虫 UA
+
+
+ 浏览器或操作系统分类为 Bot(含 bot / spider / crawler /
+ slurp 等特征,如 Googlebot)
+
+
+
+ onChange({
+ ...node,
+ config: { ...node.config, block_common_bots },
+ })
+ }
+ />
+
+
+
+
+ 屏蔽非正常 UA
+
+
+ 浏览器分类为 Bot、Other 或 Unknown(无法识别为已知浏览器)
+
+
+
+ onChange({
+ ...node,
+ config: { ...node.config, block_abnormal_ua },
+ })
+ }
+ />
+
+
+ >
+ )}
);
if (node.type === 'pow')