diff --git a/docs/public/openapi.json b/docs/public/openapi.json index 749ec2788..570f87ec3 100644 --- a/docs/public/openapi.json +++ b/docs/public/openapi.json @@ -3115,7 +3115,8 @@ "tun", "mtproto", "amneziawg", - "tuic" + "tuic", + "masque" ], "example": "vless", "type": "string" diff --git a/frontend/public/openapi.json b/frontend/public/openapi.json index 749ec2788..570f87ec3 100644 --- a/frontend/public/openapi.json +++ b/frontend/public/openapi.json @@ -3115,7 +3115,8 @@ "tun", "mtproto", "amneziawg", - "tuic" + "tuic", + "masque" ], "example": "vless", "type": "string" diff --git a/frontend/src/generated/schemas.ts b/frontend/src/generated/schemas.ts index 4c72b6ac7..6208b5d3f 100644 --- a/frontend/src/generated/schemas.ts +++ b/frontend/src/generated/schemas.ts @@ -3089,7 +3089,8 @@ export const SCHEMAS: Record = { "tun", "mtproto", "amneziawg", - "tuic" + "tuic", + "masque" ], "example": "vless", "type": "string" diff --git a/frontend/src/generated/zod.ts b/frontend/src/generated/zod.ts index b3fbcd047..744b93c06 100644 --- a/frontend/src/generated/zod.ts +++ b/frontend/src/generated/zod.ts @@ -757,7 +757,7 @@ export const InboundSchema = z.object({ nodeId: z.number().int().nullable().optional(), originNodeGuid: z.string().optional(), port: z.number().int().min(0).max(65535), - protocol: z.enum(['vmess', 'vless', 'trojan', 'shadowsocks', 'wireguard', 'hysteria', 'http', 'mixed', 'tunnel', 'tun', 'mtproto', 'amneziawg', 'tuic']), + protocol: z.enum(['vmess', 'vless', 'trojan', 'shadowsocks', 'wireguard', 'hysteria', 'http', 'mixed', 'tunnel', 'tun', 'mtproto', 'amneziawg', 'tuic', 'masque']), remark: z.string(), settings: z.unknown(), shareAddr: z.string(), diff --git a/internal/database/model/model.go b/internal/database/model/model.go index 831f14803..18c61158f 100644 --- a/internal/database/model/model.go +++ b/internal/database/model/model.go @@ -65,7 +65,7 @@ type Inbound struct { // Xray configuration fields Listen string `json:"listen" form:"listen"` Port int `json:"port" form:"port" validate:"gte=0,lte=65535" example:"443"` - Protocol Protocol `json:"protocol" form:"protocol" validate:"required,oneof=vmess vless trojan shadowsocks wireguard hysteria http mixed tunnel tun mtproto amneziawg tuic" example:"vless"` + Protocol Protocol `json:"protocol" form:"protocol" validate:"required,oneof=vmess vless trojan shadowsocks wireguard hysteria http mixed tunnel tun mtproto amneziawg tuic masque" example:"vless"` Settings string `json:"settings" form:"settings"` StreamSettings string `json:"streamSettings" form:"streamSettings"` Tag string `json:"tag" form:"tag" gorm:"unique" example:"in-443-tcp"` diff --git a/internal/web/middleware/validate_protocol_test.go b/internal/web/middleware/validate_protocol_test.go new file mode 100644 index 000000000..be98a5301 --- /dev/null +++ b/internal/web/middleware/validate_protocol_test.go @@ -0,0 +1,18 @@ +package middleware + +import ( + "testing" + + "github.com/mhsanaei/3x-ui/v3/internal/database/model" +) + +// The inbound add/update handlers validate the body with this validator, so a protocol +// missing from Inbound.Protocol's oneof makes every save of that protocol fail. +func TestValidateAcceptsMasqueInboundProtocol(t *testing.T) { + if err := validate.StructPartial(model.Inbound{Protocol: model.MASQUE}, "Protocol"); err != nil { + t.Fatalf("validate rejected a masque inbound: %v", err) + } + if err := validate.StructPartial(model.Inbound{Protocol: "dokodemo"}, "Protocol"); err == nil { + t.Fatal("validate accepted an unknown protocol; the oneof no longer guards it") + } +}