mirror of
https://github.com/nezhahq/nezha.git
synced 2025-01-23 13:18:13 -05:00
Compare commits
No commits in common. "5128bfff613ab81b4803f92bef9f4dc51bf8aa36" and "672063f4de1ab56db0fa2d18d7df3a0e63d27dad" have entirely different histories.
5128bfff61
...
672063f4de
@ -17,7 +17,6 @@ import (
|
|||||||
// @Schemes
|
// @Schemes
|
||||||
// @Description List Alert rules
|
// @Description List Alert rules
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.AlertRule]
|
// @Success 200 {object} model.CommonResponse[[]model.AlertRule]
|
||||||
// @Router /alert-rule [get]
|
// @Router /alert-rule [get]
|
||||||
|
@ -247,8 +247,7 @@ func listHandler[S ~[]E, E model.CommonInterface](handler handlerFunc[S]) func(*
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
filtered := filter(c, data)
|
c.JSON(http.StatusOK, model.CommonResponse[S]{Success: true, Data: filter(c, data)})
|
||||||
c.JSON(http.StatusOK, model.CommonResponse[S]{Success: true, Data: model.SearchByIDCtx(c, filtered)})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
// @Schemes
|
// @Schemes
|
||||||
// @Description List schedule tasks
|
// @Description List schedule tasks
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.Cron]
|
// @Success 200 {object} model.CommonResponse[[]model.Cron]
|
||||||
// @Router /cron [get]
|
// @Router /cron [get]
|
||||||
|
@ -17,7 +17,6 @@ import (
|
|||||||
// @Description List DDNS profiles
|
// @Description List DDNS profiles
|
||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.DDNSProfile]
|
// @Success 200 {object} model.CommonResponse[[]model.DDNSProfile]
|
||||||
// @Router /ddns [get]
|
// @Router /ddns [get]
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
// @Description List NAT profiles
|
// @Description List NAT profiles
|
||||||
// @Security BearerAuth
|
// @Security BearerAuth
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.NAT]
|
// @Success 200 {object} model.CommonResponse[[]model.NAT]
|
||||||
// @Router /nat [get]
|
// @Router /nat [get]
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
// @Schemes
|
// @Schemes
|
||||||
// @Description List notification
|
// @Description List notification
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.Notification]
|
// @Success 200 {object} model.CommonResponse[[]model.Notification]
|
||||||
// @Router /notification [get]
|
// @Router /notification [get]
|
||||||
|
@ -19,7 +19,6 @@ import (
|
|||||||
// @Schemes
|
// @Schemes
|
||||||
// @Description List server
|
// @Description List server
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.Server]
|
// @Success 200 {object} model.CommonResponse[[]model.Server]
|
||||||
// @Router /server [get]
|
// @Router /server [get]
|
||||||
|
@ -50,7 +50,6 @@ func showService(c *gin.Context) (*model.ServiceResponse, error) {
|
|||||||
// @Schemes
|
// @Schemes
|
||||||
// @Description List service
|
// @Description List service
|
||||||
// @Tags auth required
|
// @Tags auth required
|
||||||
// @Param id query uint false "Resource ID"
|
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} model.CommonResponse[[]model.Service]
|
// @Success 200 {object} model.CommonResponse[[]model.Service]
|
||||||
// @Router /service [get]
|
// @Router /service [get]
|
||||||
|
@ -33,7 +33,7 @@ func listBlockedAddress(c *gin.Context) (*model.Value[[]*model.WAF], error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var waf []*model.WAF
|
var waf []*model.WAF
|
||||||
if err := singleton.DB.Order("block_timestamp DESC").Limit(limit).Offset(offset).Find(&waf).Error; err != nil {
|
if err := singleton.DB.Limit(limit).Offset(offset).Find(&waf).Error; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,14 +119,7 @@ func serverStream(c *gin.Context) (any, error) {
|
|||||||
userIp = c.RemoteIP()
|
userIp = c.RemoteIP()
|
||||||
}
|
}
|
||||||
|
|
||||||
u, isMember := c.Get(model.CtxKeyAuthorizedUser)
|
|
||||||
var userId uint64
|
|
||||||
if isMember {
|
|
||||||
userId = u.(*model.User).ID
|
|
||||||
}
|
|
||||||
|
|
||||||
singleton.AddOnlineUser(connId, &model.OnlineUser{
|
singleton.AddOnlineUser(connId, &model.OnlineUser{
|
||||||
UserID: userId,
|
|
||||||
IP: userIp,
|
IP: userIp,
|
||||||
ConnectedAt: time.Now(),
|
ConnectedAt: time.Now(),
|
||||||
Conn: conn,
|
Conn: conn,
|
||||||
@ -135,7 +128,7 @@ func serverStream(c *gin.Context) (any, error) {
|
|||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
for {
|
for {
|
||||||
stat, err := getServerStat(count == 0, isMember)
|
stat, err := getServerStat(c, count == 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -156,7 +149,9 @@ func serverStream(c *gin.Context) (any, error) {
|
|||||||
|
|
||||||
var requestGroup singleflight.Group
|
var requestGroup singleflight.Group
|
||||||
|
|
||||||
func getServerStat(withPublicNote, authorized bool) ([]byte, error) {
|
func getServerStat(c *gin.Context, withPublicNote bool) ([]byte, error) {
|
||||||
|
_, isMember := c.Get(model.CtxKeyAuthorizedUser)
|
||||||
|
authorized := isMember // TODO || isViewPasswordVerfied
|
||||||
v, err, _ := requestGroup.Do(fmt.Sprintf("serverStats::%t", authorized), func() (interface{}, error) {
|
v, err, _ := requestGroup.Do(fmt.Sprintf("serverStats::%t", authorized), func() (interface{}, error) {
|
||||||
singleton.SortedServerLock.RLock()
|
singleton.SortedServerLock.RLock()
|
||||||
defer singleton.SortedServerLock.RUnlock()
|
defer singleton.SortedServerLock.RUnlock()
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmp"
|
|
||||||
"slices"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/nezhahq/nezha/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -66,56 +61,6 @@ func FindByUserID[S ~[]E, E CommonInterface](s S, uid uint64) []uint64 {
|
|||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
func SearchByIDCtx[S ~[]E, E CommonInterface](c *gin.Context, x S) S {
|
|
||||||
switch any(x).(type) {
|
|
||||||
case []*Server:
|
|
||||||
l := searchByIDCtxServer(c, any(x).([]*Server))
|
|
||||||
return any(l).(S)
|
|
||||||
default:
|
|
||||||
var s S
|
|
||||||
for _, idStr := range strings.Split(c.Query("id"), ",") {
|
|
||||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := slices.BinarySearchFunc(x, id, func(e E, t uint64) int {
|
|
||||||
return cmp.Compare(e.GetID(), t)
|
|
||||||
}); ok {
|
|
||||||
s = append(s, x[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return utils.IfOr(len(s) > 0, s, x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func searchByIDCtxServer(c *gin.Context, x []*Server) []*Server {
|
|
||||||
list1, list2 := SplitList(x)
|
|
||||||
|
|
||||||
var clist1, clist2 []*Server
|
|
||||||
for _, idStr := range strings.Split(c.Query("id"), ",") {
|
|
||||||
id, err := strconv.ParseUint(idStr, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := slices.BinarySearchFunc(list1, id, func(e *Server, t uint64) int {
|
|
||||||
return cmp.Compare(e.ID, t)
|
|
||||||
}); ok {
|
|
||||||
clist1 = append(clist1, list1[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
if i, ok := slices.BinarySearchFunc(list2, id, func(e *Server, t uint64) int {
|
|
||||||
return cmp.Compare(e.ID, t)
|
|
||||||
}); ok {
|
|
||||||
clist2 = append(clist2, list2[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
l := slices.Concat(clist1, clist2)
|
|
||||||
return utils.IfOr(len(l) > 0, l, x)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Code int `json:"code,omitempty"`
|
Code int `json:"code,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
|
@ -2,7 +2,6 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"slices"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@ -55,20 +54,3 @@ func (s *Server) AfterFind(tx *gorm.DB) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split a sorted server list into two separate lists:
|
|
||||||
// The first list contains servers with a priority set (DisplayIndex != 0).
|
|
||||||
// The second list contains servers without a priority set (DisplayIndex == 0).
|
|
||||||
// The original slice is not modified. If no server without a priority is found, it returns nil.
|
|
||||||
func SplitList(x []*Server) ([]*Server, []*Server) {
|
|
||||||
pri := func(s *Server) bool {
|
|
||||||
return s.DisplayIndex == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
i := slices.IndexFunc(x, pri)
|
|
||||||
if i == -1 {
|
|
||||||
return nil, x
|
|
||||||
}
|
|
||||||
|
|
||||||
return x[:i], x[i:]
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
name: "Official"
|
name: "Official"
|
||||||
repository: "https://github.com/hamster1963/nezha-dash-v1"
|
repository: "https://github.com/hamster1963/nezha-dash-v1"
|
||||||
author: "hamster1963"
|
author: "hamster1963"
|
||||||
version: "v1.8.1"
|
version: "v1.8.0"
|
||||||
isofficial: true
|
isofficial: true
|
||||||
- path: "nazhua-dist"
|
- path: "nazhua-dist"
|
||||||
name: "Nazhua"
|
name: "Nazhua"
|
||||||
|
Loading…
Reference in New Issue
Block a user