fix: enhance security header profile handling in ProxyHost to support UUIDs and improve form data normalization
This commit is contained in:
@@ -216,6 +216,38 @@ func (h *ProxyHostHandler) resolveAccessListReference(value any) (*uint, error)
|
||||
return &id, nil
|
||||
}
|
||||
|
||||
func (h *ProxyHostHandler) resolveSecurityHeaderProfileReference(value any) (*uint, error) {
|
||||
if value == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
parsedID, _, parseErr := parseNullableUintField(value, "security_header_profile_id")
|
||||
if parseErr == nil {
|
||||
return parsedID, nil
|
||||
}
|
||||
|
||||
uuidValue, isString := value.(string)
|
||||
if !isString {
|
||||
return nil, parseErr
|
||||
}
|
||||
|
||||
trimmed := strings.TrimSpace(uuidValue)
|
||||
if trimmed == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var profile models.SecurityHeaderProfile
|
||||
if err := h.db.Select("id").Where("uuid = ?", trimmed).First(&profile).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("security header profile not found")
|
||||
}
|
||||
return nil, fmt.Errorf("failed to resolve security header profile")
|
||||
}
|
||||
|
||||
id := profile.ID
|
||||
return &id, nil
|
||||
}
|
||||
|
||||
func parseForwardPortField(value any) (int, error) {
|
||||
switch v := value.(type) {
|
||||
case float64:
|
||||
@@ -301,6 +333,15 @@ func (h *ProxyHostHandler) Create(c *gin.Context) {
|
||||
payload["access_list_id"] = resolvedAccessListID
|
||||
}
|
||||
|
||||
if rawSecurityHeaderRef, ok := payload["security_header_profile_id"]; ok {
|
||||
resolvedSecurityHeaderID, resolveErr := h.resolveSecurityHeaderProfileReference(rawSecurityHeaderRef)
|
||||
if resolveErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": resolveErr.Error()})
|
||||
return
|
||||
}
|
||||
payload["security_header_profile_id"] = resolvedSecurityHeaderID
|
||||
}
|
||||
|
||||
payloadBytes, marshalErr := json.Marshal(payload)
|
||||
if marshalErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request payload"})
|
||||
@@ -508,12 +549,12 @@ func (h *ProxyHostHandler) Update(c *gin.Context) {
|
||||
|
||||
// Security Header Profile: update only if provided
|
||||
if v, ok := payload["security_header_profile_id"]; ok {
|
||||
parsedID, _, parseErr := parseNullableUintField(v, "security_header_profile_id")
|
||||
if parseErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": parseErr.Error()})
|
||||
resolvedSecurityHeaderID, resolveErr := h.resolveSecurityHeaderProfileReference(v)
|
||||
if resolveErr != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": resolveErr.Error()})
|
||||
return
|
||||
}
|
||||
host.SecurityHeaderProfileID = parsedID
|
||||
host.SecurityHeaderProfileID = resolvedSecurityHeaderID
|
||||
}
|
||||
|
||||
// Locations: replace only if provided
|
||||
|
||||
@@ -49,10 +49,10 @@ export interface ProxyHost {
|
||||
description: string;
|
||||
type: string;
|
||||
} | null;
|
||||
security_header_profile_id?: number | null;
|
||||
security_header_profile_id?: number | string | null;
|
||||
dns_provider_id?: number | null;
|
||||
security_header_profile?: {
|
||||
id: number;
|
||||
id?: number;
|
||||
uuid: string;
|
||||
name: string;
|
||||
description: string;
|
||||
|
||||
@@ -124,7 +124,7 @@ function buildInitialFormData(host?: ProxyHost): Partial<ProxyHost> & {
|
||||
enabled: host?.enabled ?? true,
|
||||
certificate_id: host?.certificate_id,
|
||||
access_list_id: host?.access_list?.uuid ?? host?.access_list_id,
|
||||
security_header_profile_id: host?.security_header_profile_id,
|
||||
security_header_profile_id: host?.security_header_profile?.uuid ?? host?.security_header_profile_id,
|
||||
dns_provider_id: host?.dns_provider_id || null,
|
||||
}
|
||||
}
|
||||
@@ -173,6 +173,20 @@ function normalizeAccessListReference(value: unknown): number | string | null |
|
||||
return trimmed === '' ? null : trimmed
|
||||
}
|
||||
|
||||
function normalizeSecurityHeaderReference(value: unknown): number | string | null | undefined {
|
||||
const numericValue = normalizeNullableID(value)
|
||||
if (numericValue !== undefined) {
|
||||
return numericValue
|
||||
}
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const trimmed = value.trim()
|
||||
return trimmed === '' ? null : trimmed
|
||||
}
|
||||
|
||||
function resolveSelectToken(value: number | string | null | undefined): string {
|
||||
if (value === null || value === undefined) {
|
||||
return 'none'
|
||||
@@ -546,7 +560,7 @@ export default function ProxyHostForm({ host, onSubmit, onCancel }: ProxyHostFor
|
||||
const submitPayload: Partial<ProxyHost> = {
|
||||
...payloadWithoutUptime,
|
||||
access_list_id: normalizeAccessListReference(payloadWithoutUptime.access_list_id),
|
||||
security_header_profile_id: normalizeNullableID(payloadWithoutUptime.security_header_profile_id),
|
||||
security_header_profile_id: normalizeSecurityHeaderReference(payloadWithoutUptime.security_header_profile_id),
|
||||
}
|
||||
|
||||
const res = await onSubmit(submitPayload)
|
||||
|
||||
Reference in New Issue
Block a user