From 7105213ba5f4fb08ddd6042dbbbad48ad6abf19a Mon Sep 17 00:00:00 2001 From: taylanbakircioglu Date: Thu, 19 Mar 2026 12:02:07 +0300 Subject: [PATCH] feat: add UI-level validation to prevent invalid HAProxy ACL configurations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Enforce mutual exclusivity for -m flags (only one match method at a time) - Show error status on value field when -f flag is used without absolute file path, with tooltip explaining the requirement - Replace free-text input with Select dropdown for redirect scheme type, restricting to valid values (http/https) only - Fix flag serialization order (-i → -m → -f) to prevent HAProxy parse errors Made-with: Cursor --- frontend/src/components/ACLRuleBuilder.js | 80 ++++++++++++++++------- 1 file changed, 56 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/ACLRuleBuilder.js b/frontend/src/components/ACLRuleBuilder.js index f186b71..a579ae7 100644 --- a/frontend/src/components/ACLRuleBuilder.js +++ b/frontend/src/components/ACLRuleBuilder.js @@ -348,7 +348,15 @@ function ACLDefinitionCard({ rule, index, onChange, onDelete }) { - {rule.matchType === 'ssl_fc' ? ( - (no value needed) - ) : rule.matchType === 'custom' ? ( - onChange(index, { ...rule, value: e.target.value })} - placeholder="Custom expression..." - size="small" - /> - ) : ( - onChange(index, { ...rule, value: e.target.value })} - placeholder={(rule.flags || []).includes('-f') ? '/path/to/patterns.txt' : (matchDef?.placeholder || 'Value')} - size="small" - /> - )} + {(() => { + const hasFileFlag = (rule.flags || []).includes('-f'); + const badFilePath = hasFileFlag && rule.value && !rule.value.startsWith('/'); + if (rule.matchType === 'ssl_fc') { + return (no value needed); + } + if (rule.matchType === 'custom') { + return ( + onChange(index, { ...rule, value: e.target.value })} + placeholder="Custom expression..." + size="small" + /> + ); + } + return ( + + onChange(index, { ...rule, value: e.target.value })} + placeholder={hasFileFlag ? '/path/to/patterns.txt' : (matchDef?.placeholder || 'Value')} + size="small" + status={badFilePath ? 'error' : undefined} + /> + + ); + })()} @@ -532,12 +551,25 @@ function RedirectRuleCard({ rule, index, onChange, onDelete }) { - onChange(index, { ...rule, target: e.target.value })} - placeholder={rule.type === 'scheme' ? 'https' : 'https://example.com'} - size="small" - /> + {rule.type === 'scheme' ? ( + + ) : ( + onChange(index, { ...rule, target: e.target.value })} + placeholder="https://example.com" + size="small" + /> + )}