Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'database')
-rw-r--r--database/db.go11
-rw-r--r--database/model/model.go76
2 files changed, 55 insertions, 32 deletions
diff --git a/database/db.go b/database/db.go
index 8414b118..6de81d79 100644
--- a/database/db.go
+++ b/database/db.go
@@ -1,3 +1,5 @@
+// Package database provides database initialization, migration, and management utilities
+// for the 3x-ui panel using GORM with SQLite.
package database
import (
@@ -45,6 +47,7 @@ func initModels() error {
return nil
}
+// initUser creates a default admin user if the users table is empty.
func initUser() error {
empty, err := isTableEmpty("users")
if err != nil {
@@ -68,6 +71,7 @@ func initUser() error {
return nil
}
+// runSeeders migrates user passwords to bcrypt and records seeder execution to prevent re-running.
func runSeeders(isUsersEmpty bool) error {
empty, err := isTableEmpty("history_of_seeders")
if err != nil {
@@ -107,12 +111,14 @@ func runSeeders(isUsersEmpty bool) error {
return nil
}
+// isTableEmpty returns true if the named table contains zero rows.
func isTableEmpty(tableName string) (bool, error) {
var count int64
err := db.Table(tableName).Count(&count).Error
return count == 0, err
}
+// InitDB sets up the database connection, migrates models, and runs seeders.
func InitDB(dbPath string) error {
dir := path.Dir(dbPath)
err := os.MkdirAll(dir, fs.ModePerm)
@@ -151,6 +157,7 @@ func InitDB(dbPath string) error {
return runSeeders(isUsersEmpty)
}
+// CloseDB closes the database connection if it exists.
func CloseDB() error {
if db != nil {
sqlDB, err := db.DB()
@@ -162,14 +169,17 @@ func CloseDB() error {
return nil
}
+// GetDB returns the global GORM database instance.
func GetDB() *gorm.DB {
return db
}
+// IsNotFound checks if the given error is a GORM record not found error.
func IsNotFound(err error) bool {
return err == gorm.ErrRecordNotFound
}
+// IsSQLiteDB checks if the given file is a valid SQLite database by reading its signature.
func IsSQLiteDB(file io.ReaderAt) (bool, error) {
signature := []byte("SQLite format 3\x00")
buf := make([]byte, len(signature))
@@ -180,6 +190,7 @@ func IsSQLiteDB(file io.ReaderAt) (bool, error) {
return bytes.Equal(buf, signature), nil
}
+// Checkpoint performs a WAL checkpoint on the SQLite database to ensure data consistency.
func Checkpoint() error {
// Update WAL
err := db.Exec("PRAGMA wal_checkpoint;").Error
diff --git a/database/model/model.go b/database/model/model.go
index abf8075c..720f0223 100644
--- a/database/model/model.go
+++ b/database/model/model.go
@@ -1,3 +1,4 @@
+// Package model defines the database models and data structures used by the 3x-ui panel.
package model
import (
@@ -7,8 +8,10 @@ import (
"github.com/mhsanaei/3x-ui/v2/xray"
)
+// Protocol represents the protocol type for Xray inbounds.
type Protocol string
+// Protocol constants for different Xray inbound protocols
const (
VMESS Protocol = "vmess"
VLESS Protocol = "vless"
@@ -20,27 +23,29 @@ const (
WireGuard Protocol = "wireguard"
)
+// User represents a user account in the 3x-ui panel.
type User struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
Username string `json:"username"`
Password string `json:"password"`
}
+// Inbound represents an Xray inbound configuration with traffic statistics and settings.
type Inbound struct {
- Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
- UserId int `json:"-"`
- Up int64 `json:"up" form:"up"`
- Down int64 `json:"down" form:"down"`
- Total int64 `json:"total" form:"total"`
- AllTime int64 `json:"allTime" form:"allTime" gorm:"default:0"`
- Remark string `json:"remark" form:"remark"`
- Enable bool `json:"enable" form:"enable" gorm:"index:idx_enable_traffic_reset,priority:1"`
- ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
- TrafficReset string `json:"trafficReset" form:"trafficReset" gorm:"default:never;index:idx_enable_traffic_reset,priority:2"`
- LastTrafficResetTime int64 `json:"lastTrafficResetTime" form:"lastTrafficResetTime" gorm:"default:0"`
- ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"`
+ Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"` // Unique identifier
+ UserId int `json:"-"` // Associated user ID
+ Up int64 `json:"up" form:"up"` // Upload traffic in bytes
+ Down int64 `json:"down" form:"down"` // Download traffic in bytes
+ Total int64 `json:"total" form:"total"` // Total traffic limit in bytes
+ AllTime int64 `json:"allTime" form:"allTime" gorm:"default:0"` // All-time traffic usage
+ Remark string `json:"remark" form:"remark"` // Human-readable remark
+ Enable bool `json:"enable" form:"enable" gorm:"index:idx_enable_traffic_reset,priority:1"` // Whether the inbound is enabled
+ ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` // Expiration timestamp
+ TrafficReset string `json:"trafficReset" form:"trafficReset" gorm:"default:never;index:idx_enable_traffic_reset,priority:2"` // Traffic reset schedule
+ LastTrafficResetTime int64 `json:"lastTrafficResetTime" form:"lastTrafficResetTime" gorm:"default:0"` // Last traffic reset timestamp
+ ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"` // Client traffic statistics
- // config part
+ // Xray configuration fields
Listen string `json:"listen" form:"listen"`
Port int `json:"port" form:"port"`
Protocol Protocol `json:"protocol" form:"protocol"`
@@ -50,6 +55,7 @@ type Inbound struct {
Sniffing string `json:"sniffing" form:"sniffing"`
}
+// OutboundTraffics tracks traffic statistics for Xray outbound connections.
type OutboundTraffics struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
Tag string `json:"tag" form:"tag" gorm:"unique"`
@@ -58,17 +64,20 @@ type OutboundTraffics struct {
Total int64 `json:"total" form:"total" gorm:"default:0"`
}
+// InboundClientIps stores IP addresses associated with inbound clients for access control.
type InboundClientIps struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
ClientEmail string `json:"clientEmail" form:"clientEmail" gorm:"unique"`
Ips string `json:"ips" form:"ips"`
}
+// HistoryOfSeeders tracks which database seeders have been executed to prevent re-running.
type HistoryOfSeeders struct {
Id int `json:"id" gorm:"primaryKey;autoIncrement"`
SeederName string `json:"seederName"`
}
+// GenXrayInboundConfig generates an Xray inbound configuration from the Inbound model.
func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
listen := i.Listen
if listen != "" {
@@ -85,33 +94,36 @@ func (i *Inbound) GenXrayInboundConfig() *xray.InboundConfig {
}
}
+// Setting stores key-value configuration settings for the 3x-ui panel.
type Setting struct {
Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"`
Key string `json:"key" form:"key"`
Value string `json:"value" form:"value"`
}
+// Client represents a client configuration for Xray inbounds with traffic limits and settings.
type Client struct {
- ID string `json:"id"`
- Security string `json:"security"`
- Password string `json:"password"`
- Flow string `json:"flow"`
- Email string `json:"email"`
- LimitIP int `json:"limitIp"`
- TotalGB int64 `json:"totalGB" form:"totalGB"`
- ExpiryTime int64 `json:"expiryTime" form:"expiryTime"`
- Enable bool `json:"enable" form:"enable"`
- TgID int64 `json:"tgId" form:"tgId"`
- SubID string `json:"subId" form:"subId"`
- Comment string `json:"comment" form:"comment"`
- Reset int `json:"reset" form:"reset"`
- CreatedAt int64 `json:"created_at,omitempty"`
- UpdatedAt int64 `json:"updated_at,omitempty"`
+ ID string `json:"id"` // Unique client identifier
+ Security string `json:"security"` // Security method (e.g., "auto", "aes-128-gcm")
+ Password string `json:"password"` // Client password
+ Flow string `json:"flow"` // Flow control (XTLS)
+ Email string `json:"email"` // Client email identifier
+ LimitIP int `json:"limitIp"` // IP limit for this client
+ TotalGB int64 `json:"totalGB" form:"totalGB"` // Total traffic limit in GB
+ ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` // Expiration timestamp
+ Enable bool `json:"enable" form:"enable"` // Whether the client is enabled
+ TgID int64 `json:"tgId" form:"tgId"` // Telegram user ID for notifications
+ SubID string `json:"subId" form:"subId"` // Subscription identifier
+ Comment string `json:"comment" form:"comment"` // Client comment
+ Reset int `json:"reset" form:"reset"` // Reset period in days
+ CreatedAt int64 `json:"created_at,omitempty"` // Creation timestamp
+ UpdatedAt int64 `json:"updated_at,omitempty"` // Last update timestamp
}
+// VLESSSettings contains VLESS protocol-specific configuration settings.
type VLESSSettings struct {
- Clients []Client `json:"clients"`
- Decryption string `json:"decryption"`
- Encryption string `json:"encryption"`
- Fallbacks []any `json:"fallbacks"`
+ Clients []Client `json:"clients"` // List of VLESS clients
+ Decryption string `json:"decryption"` // Decryption method
+ Encryption string `json:"encryption"` // Encryption method (usually "none" for VLESS)
+ Fallbacks []any `json:"fallbacks"` // Fallback configurations
}