From b412df70f1b2e9f10b75e095a2329f10b48e01b5 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Sat, 18 Feb 2023 16:07:32 +0330 Subject: [PATCH] update pack 2 --- config/version | 2 +- database/model/model.go | 31 ++++---- go.mod | 15 ++-- go.sum | 43 ++++------- web/assets/js/model/xray.js | 6 +- web/assets/js/util/utils.js | 10 +++ web/controller/base.go | 13 ++-- web/controller/inbound.go | 25 ++++--- web/controller/index.go | 8 +-- web/controller/server.go | 4 +- web/controller/setting.go | 16 ++--- web/controller/util.go | 6 +- web/html/xui/form/protocol/trojan.html | 4 +- web/html/xui/form/protocol/vless.html | 4 +- web/html/xui/form/protocol/vmess.html | 4 +- web/html/xui/inbounds.html | 22 +++--- web/html/xui/inbounds_client_row.html | 13 +--- web/job/stats_notify_job.go | 98 +++++++++++++------------- web/service/inbound.go | 63 ++++++++--------- web/service/setting.go | 2 +- web/service/xray.go | 15 ++-- web/web.go | 18 ++--- xray/client_traffic.go | 10 +-- 23 files changed, 212 insertions(+), 220 deletions(-) diff --git a/config/version b/config/version index 1464c521..ece61c60 100644 --- a/config/version +++ b/config/version @@ -1 +1 @@ -1.0.5 \ No newline at end of file +1.0.6 \ No newline at end of file diff --git a/database/model/model.go b/database/model/model.go index 56118c73..25e0cd41 100644 --- a/database/model/model.go +++ b/database/model/model.go @@ -24,15 +24,15 @@ type User struct { } 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"` - Remark string `json:"remark" form:"remark"` - Enable bool `json:"enable" form:"enable"` - ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` - ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"` + 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"` + Remark string `json:"remark" form:"remark"` + Enable bool `json:"enable" form:"enable"` + ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` + ClientStats []xray.ClientTraffic `gorm:"foreignKey:InboundId;references:Id" json:"clientStats" form:"clientStats"` // config part Listen string `json:"listen" form:"listen"` @@ -65,11 +65,12 @@ type Setting struct { Key string `json:"key" form:"key"` Value string `json:"value" form:"value"` } + type Client struct { - ID string `json:"id"` - AlterIds uint16 `json:"alterId"` - Email string `json:"email"` - Security string `json:"security"` - TotalGB int64 `json:"totalGB" form:"totalGB"` + ID string `json:"id"` + AlterIds uint16 `json:"alterId"` + Email string `json:"email"` + Security string `json:"security"` + TotalGB int64 `json:"totalGB" form:"totalGB"` ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` -} \ No newline at end of file +} diff --git a/go.mod b/go.mod index daa5fdc2..87244cf5 100644 --- a/go.mod +++ b/go.mod @@ -18,15 +18,14 @@ require ( google.golang.org/grpc v1.53.0 gorm.io/driver/sqlite v1.3.6 gorm.io/gorm v1.23.8 - ) require ( github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect - github.com/go-playground/locales v0.14.0 // indirect - github.com/go-playground/universal-translator v0.18.0 // indirect - github.com/go-playground/validator/v10 v10.10.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.11.2 // indirect github.com/goccy/go-json v0.10.0 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -35,13 +34,14 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pires/go-proxyproto v0.6.2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect @@ -49,10 +49,9 @@ require ( github.com/ugorji/go/codec v1.2.7 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect golang.org/x/crypto v0.5.0 // indirect - golang.org/x/net v0.5.0 // indirect + golang.org/x/net v0.7.0 // indirect golang.org/x/sys v0.5.0 // indirect google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - ) diff --git a/go.sum b/go.sum index f99fd221..d37a0f62 100644 --- a/go.sum +++ b/go.sum @@ -25,17 +25,17 @@ github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU= +github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= @@ -74,12 +74,7 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/kidstuff/mongostore v0.0.0-20181113001930-e650cd85ee4b/go.mod h1:g2nVr8KZVXJSS97Jo8pJ0jgq29P6H7dG0oplUA86MQw= github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= @@ -89,8 +84,8 @@ github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= @@ -107,12 +102,11 @@ github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= -github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -127,9 +121,7 @@ github.com/refraction-networking/utls v1.2.2-0.20230207151345-a75a4b484849 h1:vN github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/sagernet/sing v0.1.6 h1:Qy63OUfKpcqKjfd5rPmUlj0RGjHZSK/PJn0duyCCsRg= github.com/sagernet/sing-shadowsocks v0.1.1-0.20230202035033-e3123545f2f7 h1:Plup6oEiyLzY3HDqQ+QsUBzgBGdVmcsgf3t8h940z9U= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= @@ -172,7 +164,6 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= @@ -185,8 +176,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -199,10 +190,9 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= @@ -212,7 +202,6 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= @@ -236,17 +225,13 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= diff --git a/web/assets/js/model/xray.js b/web/assets/js/model/xray.js index f4b874b1..23d73930 100644 --- a/web/assets/js/model/xray.js +++ b/web/assets/js/model/xray.js @@ -1359,7 +1359,7 @@ Inbound.VmessSettings = class extends Inbound.Settings { } }; Inbound.VmessSettings.Vmess = class extends XrayCommonClass { - constructor(id=RandomUtil.randomUUID(), alterId=0, email='', totalGB=0, expiryTime='') { + constructor(id=RandomUtil.randomUUID(), alterId=0, email=RandomUtil.randomText(), totalGB=0, expiryTime='') { super(); this.id = id; this.alterId = alterId; @@ -1441,7 +1441,7 @@ Inbound.VLESSSettings = class extends Inbound.Settings { }; Inbound.VLESSSettings.VLESS = class extends XrayCommonClass { - constructor(id=RandomUtil.randomUUID(), flow='', email='', totalGB=0, fingerprint = UTLS_FINGERPRINT.UTLS_CHROME, expiryTime='') { + constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomText(), totalGB=0, fingerprint = UTLS_FINGERPRINT.UTLS_CHROME, expiryTime='') { super(); this.id = id; this.flow = flow; @@ -1557,7 +1557,7 @@ Inbound.TrojanSettings = class extends Inbound.Settings { } }; Inbound.TrojanSettings.Trojan = class extends XrayCommonClass { - constructor(password=RandomUtil.randomSeq(10), flow ='', email='', totalGB=0, expiryTime='') { + constructor(password=RandomUtil.randomSeq(10), flow ='', email=RandomUtil.randomText(), totalGB=0, expiryTime='') { super(); this.password = password; this.flow = flow; diff --git a/web/assets/js/util/utils.js b/web/assets/js/util/utils.js index 6b4e5ed9..f3a412e5 100644 --- a/web/assets/js/util/utils.js +++ b/web/assets/js/util/utils.js @@ -136,6 +136,16 @@ class RandomUtil { return (c === 'x' ? r : (r & 0x7 | 0x8)).toString(16); }); } + + static randomText() { + var chars = 'abcdefghijklmnopqrstuvwxyz1234567890'; + var string = ''; + var len = 6 + Math.floor(Math.random() * 5) + for(var ii=0; ii - Username + Email - Username + Email - Username + Email row.id === dbInbound_id); const inbound = dbInbound.toInbound(); inModal.show({ title: '{{ i18n "pages.inbounds.modifyInbound"}}', diff --git a/web/html/xui/inbounds_client_row.html b/web/html/xui/inbounds_client_row.html index 6e03e4ca..0fe707e4 100644 --- a/web/html/xui/inbounds_client_row.html +++ b/web/html/xui/inbounds_client_row.html @@ -1,15 +1,8 @@ {{define "client_row"}} /usage uuid | id \n example : /usage fc3239ed-8f3b-4151-ff51-b183d5182142" - msg.ParseMode = "HTML" - } + case "get_usage": + msg.Text = "for get your usage send command like this : \n /usage uuid | id \n example : /usage fc3239ed-8f3b-4151-ff51-b183d5182142" + msg.ParseMode = "HTML" + } if _, err := bot.Send(msg); err != nil { logger.Warning(err) } } - - continue - } - if !update.Message.IsCommand() { // ignore any non-command Messages - continue - } + continue + } - // Create a new MessageConfig. We don't have text yet, - // so we leave it empty. - msg := tgbotapi.NewMessage(update.Message.Chat.ID, "") + if !update.Message.IsCommand() { // ignore any non-command Messages + continue + } - // Extract the command from the Message. - switch update.Message.Command() { - case "help": - msg.Text = "What you need?" + // Create a new MessageConfig. We don't have text yet, + // so we leave it empty. + msg := tgbotapi.NewMessage(update.Message.Chat.ID, "") + + // Extract the command from the Message. + switch update.Message.Command() { + case "help": + msg.Text = "What you need?" msg.ReplyMarkup = numericKeyboard - case "start": - msg.Text = "Hi :) \n What you need?" + case "start": + msg.Text = "Hi :) \n What you need?" msg.ReplyMarkup = numericKeyboard - case "status": - msg.Text = "bot is ok." + case "status": + msg.Text = "bot is ok." - case "usage": - msg.Text = j.getClientUsage(update.Message.CommandArguments()) - default: - msg.Text = "I don't know that command, /help" + case "usage": + msg.Text = j.getClientUsage(update.Message.CommandArguments()) + default: + msg.Text = "I don't know that command, /help" msg.ReplyMarkup = numericKeyboard - } + } - if _, err := bot.Send(msg); err != nil { - logger.Warning(err) - } - } + if _, err := bot.Send(msg); err != nil { + logger.Warning(err) + } + } return j } func (j *StatsNotifyJob) getClientUsage(id string) string { - traffic , err := j.inboundService.GetClientTrafficById(id) + traffic, err := j.inboundService.GetClientTrafficById(id) if err != nil { logger.Warning(err) return "something wrong!" @@ -241,8 +241,8 @@ func (j *StatsNotifyJob) getClientUsage(id string) string { total = fmt.Sprintf("%s", common.FormatTraffic((traffic.Total))) } output := fmt.Sprintf("💡 Active: %t\r\n📧 Email: %s\r\n🔼 Upload↑: %s\r\n🔽 Download↓: %s\r\n🔄 Total: %s / %s\r\n📅 Expire in: %s\r\n", - traffic.Enable, traffic.Email, common.FormatTraffic(traffic.Up), common.FormatTraffic(traffic.Down), common.FormatTraffic((traffic.Up + traffic.Down)), - total, expiryTime) - + traffic.Enable, traffic.Email, common.FormatTraffic(traffic.Up), common.FormatTraffic(traffic.Down), common.FormatTraffic((traffic.Up + traffic.Down)), + total, expiryTime) + return output } diff --git a/web/service/inbound.go b/web/service/inbound.go index 37888729..dedf76a0 100644 --- a/web/service/inbound.go +++ b/web/service/inbound.go @@ -1,14 +1,14 @@ package service import ( + "encoding/json" "fmt" "time" "x-ui/database" - "encoding/json" "x-ui/database/model" + "x-ui/logger" "x-ui/util/common" "x-ui/xray" - "x-ui/logger" "gorm.io/gorm" ) @@ -64,11 +64,11 @@ func (s *InboundService) getClients(inbound *model.Inbound) ([]model.Client, err return clients, nil } -func (s *InboundService) checkEmailsExist(emails map[string] bool, ignoreId int) (string, error) { +func (s *InboundService) checkEmailsExist(emails map[string]bool, ignoreId int) (string, error) { db := database.GetDB() - var inbounds []*model.Inbound - db = db.Model(model.Inbound{}).Where("Protocol in ?", []model.Protocol{model.VMess, model.VLESS}) - if (ignoreId > 0) { + var inbounds []*model.Inbound + db = db.Model(model.Inbound{}).Where("Protocol in ?", []model.Protocol{model.VMess, model.VLESS, model.Trojan}) + if ignoreId > 0 { db = db.Where("id != ?", ignoreId) } db = db.Find(&inbounds) @@ -96,25 +96,25 @@ func (s *InboundService) checkEmailExistForInbound(inbound *model.Inbound) (stri if err != nil { return "", err } - emails := make(map[string] bool) + emails := make(map[string]bool) for _, client := range clients { - if (client.Email != "") { + if client.Email != "" { if emails[client.Email] { return client.Email, nil } - emails[client.Email] = true; + emails[client.Email] = true } } return s.checkEmailsExist(emails, inbound.Id) } -func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound,error) { +func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, error) { exist, err := s.checkPortExist(inbound.Port, 0) if err != nil { return inbound, err } if exist { - return inbound, common.NewError("端口已存在:", inbound.Port) + return inbound, common.NewError("Port already exists:", inbound.Port) } existEmail, err := s.checkEmailExistForInbound(inbound) @@ -129,7 +129,7 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound,erro err = db.Save(inbound).Error if err == nil { - s.UpdateClientStat(inbound.Id,inbound.Settings) + s.UpdateClientStat(inbound.Id, inbound.Settings) } return inbound, err } @@ -141,7 +141,7 @@ func (s *InboundService) AddInbounds(inbounds []*model.Inbound) error { return err } if exist { - return common.NewError("端口已存在:", inbound.Port) + return common.NewError("Port already exists:", inbound.Port) } } @@ -187,9 +187,9 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, return inbound, err } if exist { - return inbound, common.NewError("端口已存在:", inbound.Port) + return inbound, common.NewError("Port already exists:", inbound.Port) } - + existEmail, err := s.checkEmailExistForInbound(inbound) if err != nil { return inbound, err @@ -216,7 +216,7 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound, oldInbound.Sniffing = inbound.Sniffing oldInbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port) - s.UpdateClientStat(inbound.Id,inbound.Settings) + s.UpdateClientStat(inbound.Id, inbound.Settings) db := database.GetDB() return inbound, db.Save(oldInbound).Error } @@ -276,13 +276,13 @@ func (s *InboundService) AddClientTraffic(traffics []*xray.ClientTraffic) (err e for _, traffic := range traffics { inbound := &model.Inbound{} - err := txInbound.Where("settings like ?", "%" + traffic.Email + "%").First(inbound).Error + err := txInbound.Where("settings like ?", "%"+traffic.Email+"%").First(inbound).Error traffic.InboundId = inbound.Id if err != nil { if err == gorm.ErrRecordNotFound { // delete removed client record clientErr := s.DelClientStat(tx, traffic.Email) - logger.Warning(err, traffic.Email,clientErr) + logger.Warning(err, traffic.Email, clientErr) } continue @@ -298,19 +298,19 @@ func (s *InboundService) AddClientTraffic(traffics []*xray.ClientTraffic) (err e } } if tx.Where("inbound_id = ?", inbound.Id).Where("email = ?", traffic.Email). - UpdateColumn("enable", true). - UpdateColumn("expiry_time", traffic.ExpiryTime). - UpdateColumn("total",traffic.Total). - UpdateColumn("up", gorm.Expr("up + ?", traffic.Up)). - UpdateColumn("down", gorm.Expr("down + ?", traffic.Down)).RowsAffected == 0 { + UpdateColumn("enable", true). + UpdateColumn("expiry_time", traffic.ExpiryTime). + UpdateColumn("total", traffic.Total). + UpdateColumn("up", gorm.Expr("up + ?", traffic.Up)). + UpdateColumn("down", gorm.Expr("down + ?", traffic.Down)).RowsAffected == 0 { err = tx.Create(traffic).Error } - + if err != nil { logger.Warning("AddClientTraffic update data ", err) continue } - + } return } @@ -335,7 +335,7 @@ func (s *InboundService) DisableInvalidClients() (int64, error) { count := result.RowsAffected return count, err } -func (s *InboundService) UpdateClientStat(inboundId int, inboundSettings string) (error) { +func (s *InboundService) UpdateClientStat(inboundId int, inboundSettings string) error { db := database.GetDB() // get settings clients @@ -344,8 +344,8 @@ func (s *InboundService) UpdateClientStat(inboundId int, inboundSettings string) clients := settings["clients"] for _, client := range clients { result := db.Model(xray.ClientTraffic{}). - Where("inbound_id = ? and email = ?", inboundId, client.Email). - Updates(map[string]interface{}{"enable": true, "total": client.TotalGB, "expiry_time": client.ExpiryTime}) + Where("inbound_id = ? and email = ?", inboundId, client.Email). + Updates(map[string]interface{}{"enable": true, "total": client.TotalGB, "expiry_time": client.ExpiryTime}) if result.RowsAffected == 0 { clientTraffic := xray.ClientTraffic{} clientTraffic.InboundId = inboundId @@ -361,7 +361,7 @@ func (s *InboundService) UpdateClientStat(inboundId int, inboundSettings string) if err != nil { return err } - + } return nil } @@ -369,7 +369,7 @@ func (s *InboundService) DelClientStat(tx *gorm.DB, email string) error { return tx.Where("email = ?", email).Delete(xray.ClientTraffic{}).Error } -func (s *InboundService) ResetClientTraffic(clientEmail string) (error) { +func (s *InboundService) ResetClientTraffic(clientEmail string) error { db := database.GetDB() result := db.Model(xray.ClientTraffic{}). @@ -379,7 +379,6 @@ func (s *InboundService) ResetClientTraffic(clientEmail string) (error) { err := result.Error - if err != nil { return err } @@ -390,7 +389,7 @@ func (s *InboundService) GetClientTrafficById(uuid string) (traffic *xray.Client inbound := &model.Inbound{} traffic = &xray.ClientTraffic{} - err = db.Model(model.Inbound{}).Where("settings like ?", "%" + uuid + "%").First(inbound).Error + err = db.Model(model.Inbound{}).Where("settings like ?", "%"+uuid+"%").First(inbound).Error if err != nil { if err == gorm.ErrRecordNotFound { logger.Warning(err) diff --git a/web/service/setting.go b/web/service/setting.go index 7c42b5fe..4d9231b3 100644 --- a/web/service/setting.go +++ b/web/service/setting.go @@ -69,7 +69,7 @@ func (s *SettingService) GetAllSetting() (*entity.AllSetting, error) { } if !found { - // 有些设置自动生成,不需要返回到前端给用户修改 + // Some settings are automatically generated, no need to return to the front end to modify the user return nil } diff --git a/web/service/xray.go b/web/service/xray.go index 37fd3b05..33425c3c 100644 --- a/web/service/xray.go +++ b/web/service/xray.go @@ -6,6 +6,7 @@ import ( "sync" "x-ui/logger" "x-ui/xray" + "go.uber.org/atomic" ) @@ -50,6 +51,7 @@ func (s *XrayService) GetXrayVersion() string { } return p.GetVersion() } + func RemoveIndex(s []interface{}, index int) []interface{} { return append(s[:index], s[index+1:]...) } @@ -79,25 +81,24 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { // get settings clients settings := map[string]interface{}{} json.Unmarshal([]byte(inbound.Settings), &settings) - clients, ok := settings["clients"].([]interface{}) + clients, ok := settings["clients"].([]interface{}) if ok { // check users active or not clientStats := inbound.ClientStats for _, clientTraffic := range clientStats { - + for index, client := range clients { c := client.(map[string]interface{}) if c["email"] == clientTraffic.Email { - if ! clientTraffic.Enable { - clients = RemoveIndex(clients,index) - logger.Info("Remove Inbound User",c["email"] ,"due the expire or traffic limit") + if !clientTraffic.Enable { + clients = RemoveIndex(clients, index) + logger.Info("Remove Inbound User", c["email"], "due the expire or traffic limit") } } } - } settings["clients"] = clients @@ -105,7 +106,7 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) { if err != nil { return nil, err } - + inbound.Settings = string(modifiedSettings) } inboundConfig := inbound.GenXrayInboundConfig() diff --git a/web/web.go b/web/web.go index 383203b6..7e5f73de 100644 --- a/web/web.go +++ b/web/web.go @@ -21,7 +21,7 @@ import ( "x-ui/web/network" "x-ui/web/service" - "github.com/BurntSushi/toml" + "github.com/pelletier/go-toml/v2" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" @@ -271,7 +271,7 @@ func (s *Server) initI18n(engine *gin.Engine) error { }) } - engine.FuncMap["i18n"] = I18n; + engine.FuncMap["i18n"] = I18n engine.Use(func(c *gin.Context) { //accept := c.GetHeader("Accept-Language") @@ -286,7 +286,7 @@ func (s *Server) initI18n(engine *gin.Engine) error { localizer = i18n.NewLocalizer(bundle, lang) c.Set("localizer", localizer) - c.Set("I18n" , I18n) + c.Set("I18n", I18n) c.Next() }) @@ -298,19 +298,19 @@ func (s *Server) startTask() { if err != nil { logger.Warning("start xray failed:", err) } - // 每 30 秒检查一次 xray 是否在运行 + // Check whether xray is running every 30 seconds s.cron.AddJob("@every 30s", job.NewCheckXrayRunningJob()) go func() { time.Sleep(time.Second * 5) - // 每 10 秒统计一次流量,首次启动延迟 5 秒,与重启 xray 的时间错开 + // Statistics every 10 seconds, start the delay for 5 seconds for the first time, and staggered with the time to restart xray s.cron.AddJob("@every 10s", job.NewXrayTrafficJob()) }() - // 每 30 秒检查一次 inbound 流量超出和到期的情况 + // Check the inbound traffic every 30 seconds that the traffic exceeds and expires s.cron.AddJob("@every 30s", job.NewCheckInboundJob()) - // 每一天提示一次流量情况,上海时间8点30 + // Make a traffic condition every day, 8:30 var entry cron.EntryID isTgbotenabled, err := s.settingService.GetTgbotenabled() if (err == nil) && (isTgbotenabled) { @@ -320,7 +320,7 @@ func (s *Server) startTask() { runtime = "@daily" } logger.Infof("Tg notify enabled,run at %s", runtime) - entry, err = s.cron.AddJob(runtime, job.NewStatsNotifyJob()) + _, err = s.cron.AddJob(runtime, job.NewStatsNotifyJob()) if err != nil { logger.Warning("Add NewStatsNotifyJob error", err) return @@ -333,7 +333,7 @@ func (s *Server) startTask() { } func (s *Server) Start() (err error) { - //这是一个匿名函数,没没有函数名 + //This is an anonymous function, no function name defer func() { if err != nil { s.Stop() diff --git a/xray/client_traffic.go b/xray/client_traffic.go index 4df6a502..d1302da4 100644 --- a/xray/client_traffic.go +++ b/xray/client_traffic.go @@ -1,12 +1,12 @@ package xray type ClientTraffic struct { - Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"` - InboundId int `json:"inboundId" form:"inboundId"` + Id int `json:"id" form:"id" gorm:"primaryKey;autoIncrement"` + InboundId int `json:"inboundId" form:"inboundId"` Enable bool `json:"enable" form:"enable"` - Email string `json:"email" form:"email" gorm:"unique"` - Up int64 `json:"up" form:"up"` - Down int64 `json:"down" form:"down"` + Email string `json:"email" form:"email" gorm:"unique"` + Up int64 `json:"up" form:"up"` + Down int64 `json:"down" form:"down"` ExpiryTime int64 `json:"expiryTime" form:"expiryTime"` Total int64 `json:"total" form:"total"` }