1
0

model.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Package model defines the database models and data structures used by the 3x-ui panel.
  2. package model
  3. import (
  4. "fmt"
  5. "github.com/mhsanaei/3x-ui/v3/util/json_util"
  6. "github.com/mhsanaei/3x-ui/v3/xray"
  7. )
  8. // Protocol represents the protocol type for Xray inbounds.
  9. type Protocol string
  10. // Protocol constants for different Xray inbound protocols
  11. const (
  12. VMESS Protocol = "vmess"
  13. VLESS Protocol = "vless"
  14. Tunnel Protocol = "tunnel"
  15. HTTP Protocol = "http"
  16. Trojan Protocol = "trojan"
  17. Shadowsocks Protocol = "shadowsocks"
  18. Mixed Protocol = "mixed"
  19. WireGuard Protocol = "wireguard"
  20. // UI stores Hysteria v1 and v2 both as "hysteria" and uses
  21. // settings.version to discriminate. Imports from outside the panel
  22. // can carry the literal "hysteria2" string, so IsHysteria below
  23. // accepts both.
  24. Hysteria Protocol = "hysteria"
  25. Hysteria2 Protocol = "hysteria2"
  26. )
  27. // IsHysteria returns true for both "hysteria" and "hysteria2".
  28. // Use instead of a bare ==model.Hysteria check: a v2 inbound stored
  29. // with the literal v2 string would otherwise fall through (#4081).
  30. func IsHysteria(p Protocol) bool {
  31. return p == Hysteria || p == Hysteria2
  32. }
  33. // User represents a user account in the 3x-ui panel.
  34. type User struct {
  35. Id int `json:"id" gorm:"primaryKey;autoIncrement"`
  36. Username string `json:"username"`
  37. Password string `json:"password"`
  38. }
  39. // Inbound represents an Xray inbound configuration with traffic statistics and settings.
  40. type Inbound struct {
  41. Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"` // Unique identifier
  42. UserId int `json:"-"` // Associated user ID
  43. Up int64 `json:"up" form:"up"` // Upload traffic in bytes
  44. Down int64 `json:"down" form:"down"` // Download traffic in bytes
  45. Total int64 `json:"total" form:"total"` // Total traffic limit in bytes
  46. AllTime int64 `json:"allTime" form:"allTime" gorm:"default:0"` // All-time traffic usage
  47. Remark string `json:"remark" form:"remark"` // Human-readable remark
  48. Enable bool `json:"enable" form:"enable" gorm:"index:idx_enable_traffic_reset,priority:1"` // Whether the inbound is enabled
  49. ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` // Expiration timestamp
  50. TrafficReset string `json:"trafficReset" form:"trafficReset" gorm:"default:never;index:idx_enable_traffic_reset,priority:2"` // Traffic reset schedule
  51. LastTrafficResetTime int64 `json:"lastTrafficResetTime" form:"lastTrafficResetTime" gorm:"default:0"` // Last traffic reset timestamp
  52. ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"` // Client traffic statistics
  53. // Xray configuration fields
  54. Listen string `json:"listen" form:"listen"`
  55. Port int `json:"port" form:"port"`
  56. Protocol Protocol `json:"protocol" form:"protocol"`
  57. Settings string `json:"settings" form:"settings"`
  58. StreamSettings string `json:"streamSettings" form:"streamSettings"`
  59. Tag string `json:"tag" form:"tag" gorm:"unique"`
  60. Sniffing string `json:"sniffing" form:"sniffing"`
  61. // NodeID points at the remote panel (Node) where this inbound's xray
  62. // actually runs. NULL means the inbound runs on the local xray (the
  63. // pre-multi-node behaviour). Existing rows migrate to NULL with no
  64. // backfill.
  65. NodeID *int `json:"nodeId,omitempty" form:"nodeId" gorm:"index"`
  66. }
  67. // OutboundTraffics tracks traffic statistics for Xray outbound connections.
  68. type OutboundTraffics struct {
  69. Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
  70. Tag string `json:"tag" form:"tag" gorm:"unique"`
  71. Up int64 `json:"up" form:"up" gorm:"default:0"`
  72. Down int64 `json:"down" form:"down" gorm:"default:0"`
  73. Total int64 `json:"total" form:"total" gorm:"default:0"`
  74. }
  75. // InboundClientIps stores IP addresses associated with inbound clients for access control.
  76. type InboundClientIps struct {
  77. Id int `json:"id" gorm:"primaryKey;autoIncrement"`
  78. ClientEmail string `json:"clientEmail" form:"clientEmail" gorm:"unique"`
  79. Ips string `json:"ips" form:"ips"`
  80. }
  81. // HistoryOfSeeders tracks which database seeders have been executed to prevent re-running.
  82. type HistoryOfSeeders struct {
  83. Id int `json:"id" gorm:"primaryKey;autoIncrement"`
  84. SeederName string `json:"seederName"`
  85. }
  86. // GenXrayInboundConfig generates an Xray inbound configuration from the Inbound model.
  87. func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
  88. listen := i.Listen
  89. // Default to 0.0.0.0 (all interfaces) when listen is empty
  90. // This ensures proper dual-stack IPv4/IPv6 binding in systems where bindv6only=0
  91. if listen == "" {
  92. listen = "0.0.0.0"
  93. }
  94. listen = fmt.Sprintf("\"%v\"", listen)
  95. return &xray.InboundConfig{
  96. Listen: json_util.RawMessage(listen),
  97. Port: i.Port,
  98. Protocol: string(i.Protocol),
  99. Settings: json_util.RawMessage(i.Settings),
  100. StreamSettings: json_util.RawMessage(i.StreamSettings),
  101. Tag: i.Tag,
  102. Sniffing: json_util.RawMessage(i.Sniffing),
  103. }
  104. }
  105. // Setting stores key-value configuration settings for the 3x-ui panel.
  106. type Setting struct {
  107. Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
  108. Key string `json:"key" form:"key"`
  109. Value string `json:"value" form:"value"`
  110. }
  111. // Node represents a remote 3x-ui panel registered with the central panel.
  112. // The central panel polls each node's existing /panel/api/server/status
  113. // endpoint over HTTP using the per-node ApiToken to populate the runtime
  114. // status fields below.
  115. type Node struct {
  116. Id int `json:"id" gorm:"primaryKey;autoIncrement"`
  117. Name string `json:"name" gorm:"uniqueIndex"`
  118. Remark string `json:"remark"`
  119. Scheme string `json:"scheme"` // "https" | "http"
  120. Address string `json:"address"` // host or IP
  121. Port int `json:"port"`
  122. BasePath string `json:"basePath"` // "/" or "/myprefix/"
  123. ApiToken string `json:"apiToken"` // plaintext, matches existing tg/ldap pattern
  124. Enable bool `json:"enable" gorm:"default:true"`
  125. // Heartbeat-updated fields. UpdatedAt advances on every probe even when
  126. // the row is otherwise unchanged so the UI's "last seen" tooltip is
  127. // truthful without us having to read LastHeartbeat separately.
  128. Status string `json:"status" gorm:"default:unknown"` // online|offline|unknown
  129. LastHeartbeat int64 `json:"lastHeartbeat"` // unix seconds, 0 = never
  130. LatencyMs int `json:"latencyMs"`
  131. XrayVersion string `json:"xrayVersion"`
  132. CpuPct float64 `json:"cpuPct"`
  133. MemPct float64 `json:"memPct"`
  134. UptimeSecs uint64 `json:"uptimeSecs"`
  135. LastError string `json:"lastError"`
  136. CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime"`
  137. UpdatedAt int64 `json:"updatedAt" gorm:"autoUpdateTime"`
  138. }
  139. type CustomGeoResource struct {
  140. Id int `json:"id" gorm:"primaryKey;autoIncrement"`
  141. Type string `json:"type" gorm:"not null;uniqueIndex:idx_custom_geo_type_alias;column:geo_type"`
  142. Alias string `json:"alias" gorm:"not null;uniqueIndex:idx_custom_geo_type_alias"`
  143. Url string `json:"url" gorm:"not null"`
  144. LocalPath string `json:"localPath" gorm:"column:local_path"`
  145. LastUpdatedAt int64 `json:"lastUpdatedAt" gorm:"default:0;column:last_updated_at"`
  146. LastModified string `json:"lastModified" gorm:"column:last_modified"`
  147. CreatedAt int64 `json:"createdAt" gorm:"autoCreateTime;column:created_at"`
  148. UpdatedAt int64 `json:"updatedAt" gorm:"autoUpdateTime;column:updated_at"`
  149. }
  150. type ClientReverse struct {
  151. Tag string `json:"tag"`
  152. }
  153. // Client represents a client configuration for Xray inbounds with traffic limits and settings.
  154. type Client struct {
  155. ID string `json:"id,omitempty"` // Unique client identifier
  156. Security string `json:"security"` // Security method (e.g., "auto", "aes-128-gcm")
  157. Password string `json:"password,omitempty"` // Client password
  158. Flow string `json:"flow,omitempty"` // Flow control (XTLS)
  159. Reverse *ClientReverse `json:"reverse,omitempty"` // VLESS simple reverse proxy settings
  160. Auth string `json:"auth,omitempty"` // Auth password (Hysteria)
  161. Email string `json:"email"` // Client email identifier
  162. LimitIP int `json:"limitIp"` // IP limit for this client
  163. TotalGB int64 `json:"totalGB" form:"totalGB"` // Total traffic limit in GB
  164. ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` // Expiration timestamp
  165. Enable bool `json:"enable" form:"enable"` // Whether the client is enabled
  166. TgID int64 `json:"tgId" form:"tgId"` // Telegram user ID for notifications
  167. SubID string `json:"subId" form:"subId"` // Subscription identifier
  168. Comment string `json:"comment" form:"comment"` // Client comment
  169. Reset int `json:"reset" form:"reset"` // Reset period in days
  170. CreatedAt int64 `json:"created_at,omitempty"` // Creation timestamp
  171. UpdatedAt int64 `json:"updated_at,omitempty"` // Last update timestamp
  172. }