diff --git a/backend/models/frontend.py b/backend/models/frontend.py index 8dc810c..fd7cd1c 100644 --- a/backend/models/frontend.py +++ b/backend/models/frontend.py @@ -108,8 +108,8 @@ class FrontendConfig(BaseModel): raise ValueError('Frontend name cannot be empty') # HAProxy names cannot contain spaces or special characters - if not re.match(r'^[a-zA-Z0-9_-]+$', v.strip()): - raise ValueError('Frontend name can only contain letters, numbers, underscore (_) and dash (-). Spaces and special characters are not allowed.') + if not re.match(r'^[a-zA-Z0-9_.-]+$', v.strip()): + raise ValueError('Frontend name can only contain letters, numbers, dot (.), underscore (_) and dash (-). Spaces and special characters are not allowed.') if len(v.strip()) > 50: raise ValueError('Frontend name cannot exceed 50 characters') @@ -147,8 +147,8 @@ class FrontendConfig(BaseModel): @validator('default_backend') def validate_default_backend(cls, v): - if v and not re.match(r'^[a-zA-Z0-9_-]+$', v.strip()): - raise ValueError('Default backend name can only contain letters, numbers, underscore (_) and dash (-)') + if v and not re.match(r'^[a-zA-Z0-9_.-]+$', v.strip()): + raise ValueError('Default backend name can only contain letters, numbers, dot (.), underscore (_) and dash (-)') return v.strip() if v else None @validator('ssl_certificate_id') @@ -288,7 +288,7 @@ class FrontendConfig(BaseModel): continue # Basic ACL syntax validation - if not re.match(r'^[a-zA-Z0-9_-]+\s+', rule): + if not re.match(r'^[a-zA-Z0-9_.-]+\s+', rule): raise ValueError(f'Invalid ACL rule syntax: "{rule}". Must start with ACL name followed by condition.') # Check for dangerous patterns diff --git a/backend/models/waf.py b/backend/models/waf.py index d34b1ed..6fd353d 100644 --- a/backend/models/waf.py +++ b/backend/models/waf.py @@ -22,8 +22,8 @@ class WAFRule(BaseModel): raise ValueError('WAF rule name cannot be empty') # HAProxy ACL names cannot contain spaces or special characters - if not re.match(r'^[a-zA-Z0-9_-]+$', v.strip()): - raise ValueError('WAF rule name can only contain letters, numbers, underscore (_) and dash (-). Spaces and special characters are not allowed.') + if not re.match(r'^[a-zA-Z0-9_.-]+$', v.strip()): + raise ValueError('WAF rule name can only contain letters, numbers, dot (.), underscore (_) and dash (-). Spaces and special characters are not allowed.') if len(v.strip()) > 50: raise ValueError('WAF rule name cannot exceed 50 characters') diff --git a/backend/utils/haproxy_validator.py b/backend/utils/haproxy_validator.py index 37ed425..50bbf01 100644 --- a/backend/utils/haproxy_validator.py +++ b/backend/utils/haproxy_validator.py @@ -156,11 +156,11 @@ class HAProxyConfigValidator: section_name = parts[1] # Check name format - if not re.match(r'^[a-zA-Z0-9_-]+$', section_name): + if not re.match(r'^[a-zA-Z0-9_.-]+$', section_name): self._add_result( ValidationLevel.WARNING, f"Section name '{section_name}' contains invalid characters", - suggestion="Use only letters, numbers, underscore and hyphen" + suggestion="Use only letters, numbers, dot, underscore and hyphen" ) # Set current section for validation @@ -265,12 +265,12 @@ class HAProxyConfigValidator: server_addr = args[1] # Check server name format - if not re.match(r'^[a-zA-Z0-9_-]+$', server_name): + if not re.match(r'^[a-zA-Z0-9_.-]+$', server_name): self._add_result( ValidationLevel.WARNING, f"Server name '{server_name}' contains invalid characters", directive="server", - suggestion="Use only letters, numbers, underscore and hyphen" + suggestion="Use only letters, numbers, dot, underscore and hyphen" ) # Check address format diff --git a/frontend/src/components/ACLRuleBuilder.js b/frontend/src/components/ACLRuleBuilder.js index 628edfc..3a07cc6 100644 --- a/frontend/src/components/ACLRuleBuilder.js +++ b/frontend/src/components/ACLRuleBuilder.js @@ -313,7 +313,7 @@ function ACLDefinitionCard({ rule, index, onChange, onDelete }) { onChange(index, { ...rule, name: e.target.value.replace(/[^a-zA-Z0-9_-]/g, '') })} + onChange={(e) => onChange(index, { ...rule, name: e.target.value.replace(/[^a-zA-Z0-9_.-]/g, '') })} placeholder="acl_name" size="small" addonBefore={} diff --git a/frontend/src/components/BackendServers.js b/frontend/src/components/BackendServers.js index 4da8cd5..fe7e88b 100644 --- a/frontend/src/components/BackendServers.js +++ b/frontend/src/components/BackendServers.js @@ -1646,7 +1646,7 @@ const BackendServers = () => { label="Backend Name" rules={[ { required: true, message: 'Please enter backend name' }, - { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Only alphanumeric, underscore and dash allowed' } + { pattern: /^[a-zA-Z0-9_.-]+$/, message: 'Only alphanumeric, dot, underscore and dash allowed' } ]} > @@ -1939,7 +1939,7 @@ const BackendServers = () => { label="Server Name" rules={[ { required: true, message: 'Please enter server name' }, - { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Only alphanumeric, underscore and dash allowed' } + { pattern: /^[a-zA-Z0-9_.-]+$/, message: 'Only alphanumeric, dot, underscore and dash allowed' } ]} > diff --git a/frontend/src/components/FrontendManagement.js b/frontend/src/components/FrontendManagement.js index f471f1b..cccba03 100644 --- a/frontend/src/components/FrontendManagement.js +++ b/frontend/src/components/FrontendManagement.js @@ -1381,7 +1381,7 @@ const FrontendManagement = () => { extra="Unique identifier for this frontend" rules={[ { required: true, message: 'Please enter frontend name' }, - { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Only alphanumeric, underscore and dash allowed' } + { pattern: /^[a-zA-Z0-9_.-]+$/, message: 'Only alphanumeric, dot, underscore and dash allowed' } ]} > diff --git a/frontend/src/components/SSLManagement.js b/frontend/src/components/SSLManagement.js index 8ab900e..41555d8 100644 --- a/frontend/src/components/SSLManagement.js +++ b/frontend/src/components/SSLManagement.js @@ -934,7 +934,7 @@ const SSLManagement = () => { label="Certificate Name" rules={[ { required: true, message: 'Please enter certificate name' }, - { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Only alphanumeric, underscore and dash allowed' } + { pattern: /^[a-zA-Z0-9_.-]+$/, message: 'Only alphanumeric, dot, underscore and dash allowed' } ]} extra={selectedCertificate && selectedCertificate.id ? "Certificate name cannot be changed (used as file path on servers)" : "Used as file path: /etc/ssl/haproxy/{name}.pem"} tooltip={selectedCertificate && selectedCertificate.id ? "Certificate name is immutable after creation to maintain file system references" : null} diff --git a/frontend/src/components/WAFManagement.js b/frontend/src/components/WAFManagement.js index 7f4a476..6dc5050 100644 --- a/frontend/src/components/WAFManagement.js +++ b/frontend/src/components/WAFManagement.js @@ -1442,7 +1442,7 @@ const WAFManagement = () => { label="Rule Name" rules={[ { required: true, message: 'Please enter rule name' }, - { pattern: /^[a-zA-Z0-9_-]+$/, message: 'Only alphanumeric, underscore and dash allowed' } + { pattern: /^[a-zA-Z0-9_.-]+$/, message: 'Only alphanumeric, dot, underscore and dash allowed' } ]} >