refactor: replace api error handler with cosy err handler

This commit is contained in:
Jacky 2025-03-29 20:33:48 +08:00
parent 4cb4695e7b
commit b469ca7961
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
37 changed files with 268 additions and 250 deletions

View file

@ -1,38 +1,14 @@
package api package api
import ( import (
"errors"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
"gorm.io/gorm"
"net/http"
) )
func CurrentUser(c *gin.Context) *model.User { func CurrentUser(c *gin.Context) *model.User {
return c.MustGet("user").(*model.User) return c.MustGet("user").(*model.User)
} }
func ErrHandler(c *gin.Context, err error) {
logger.GetLogger().Errorln(err)
var cErr *cosy.Error
switch {
case errors.Is(err, gorm.ErrRecordNotFound):
c.JSON(http.StatusNotFound, &cosy.Error{
Code: http.StatusNotFound,
Message: gorm.ErrRecordNotFound.Error(),
})
case errors.As(err, &cErr):
c.JSON(http.StatusInternalServerError, cErr)
default:
c.JSON(http.StatusInternalServerError, &cosy.Error{
Code: http.StatusInternalServerError,
Message: err.Error(),
})
}
}
func SetSSEHeaders(c *gin.Context) { func SetSSEHeaders(c *gin.Context) {
c.Header("Content-Type", "text/event-stream") c.Header("Content-Type", "text/event-stream")
c.Header("Cache-Control", "no-cache") c.Header("Cache-Control", "no-cache")

View file

@ -1,14 +1,14 @@
package certificate package certificate
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/spf13/cast" "github.com/spf13/cast"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func GetAcmeUser(c *gin.Context) { func GetAcmeUser(c *gin.Context) {
@ -16,7 +16,7 @@ func GetAcmeUser(c *gin.Context) {
id := cast.ToUint64(c.Param("id")) id := cast.ToUint64(c.Param("id"))
user, err := u.FirstByID(id) user, err := u.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
c.JSON(http.StatusOK, user) c.JSON(http.StatusOK, user)
@ -83,17 +83,17 @@ func RegisterAcmeUser(c *gin.Context) {
u := query.AcmeUser u := query.AcmeUser
user, err := u.FirstByID(id) user, err := u.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
err = user.Register() err = user.Register()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
_, err = u.Where(u.ID.Eq(id)).Updates(user) _, err = u.Where(u.ID.Eq(id)).Updates(user)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
c.JSON(http.StatusOK, user) c.JSON(http.StatusOK, user)

View file

@ -1,7 +1,9 @@
package certificate package certificate
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
@ -12,8 +14,6 @@ import (
"github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certcrypto"
"github.com/spf13/cast" "github.com/spf13/cast"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
"os"
) )
type APICertificate struct { type APICertificate struct {
@ -74,7 +74,7 @@ func GetCert(c *gin.Context) {
certModel, err := q.FirstByID(cast.ToUint64(c.Param("id"))) certModel, err := q.FirstByID(cast.ToUint64(c.Param("id")))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -114,7 +114,7 @@ func AddCert(c *gin.Context) {
err := certModel.Insert() err := certModel.Insert()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -127,7 +127,7 @@ func AddCert(c *gin.Context) {
err = content.WriteFile() err = content.WriteFile()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -153,7 +153,7 @@ func ModifyCert(c *gin.Context) {
certModel, err := q.FirstByID(id) certModel, err := q.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -169,7 +169,7 @@ func ModifyCert(c *gin.Context) {
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -182,7 +182,7 @@ func ModifyCert(c *gin.Context) {
err = content.WriteFile() err = content.WriteFile()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -218,7 +218,7 @@ func SyncCertificate(c *gin.Context) {
err := db.Where(certModel).FirstOrCreate(certModel).Error err := db.Where(certModel).FirstOrCreate(certModel).Error
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -231,7 +231,7 @@ func SyncCertificate(c *gin.Context) {
err = content.WriteFile() err = content.WriteFile()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,14 +1,14 @@
package certificate package certificate
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/cert/dns" "github.com/0xJacky/Nginx-UI/internal/cert/dns"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/spf13/cast" "github.com/spf13/cast"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func GetDnsCredential(c *gin.Context) { func GetDnsCredential(c *gin.Context) {
@ -18,7 +18,7 @@ func GetDnsCredential(c *gin.Context) {
dnsCredential, err := d.FirstByID(id) dnsCredential, err := d.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
type apiDnsCredential struct { type apiDnsCredential struct {
@ -62,7 +62,7 @@ func AddDnsCredential(c *gin.Context) {
err := d.Create(&dnsCredential) err := d.Create(&dnsCredential)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -81,7 +81,7 @@ func EditDnsCredential(c *gin.Context) {
dnsCredential, err := d.FirstByID(id) dnsCredential, err := d.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -93,7 +93,7 @@ func EditDnsCredential(c *gin.Context) {
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -27,7 +27,7 @@ func GetEnvironment(c *gin.Context) {
env, err := envQuery.FirstByID(id) env, err := envQuery.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -161,7 +161,7 @@ func DeleteEnvironment(c *gin.Context) {
func LoadEnvironmentFromSettings(c *gin.Context) { func LoadEnvironmentFromSettings(c *gin.Context) {
err := settings.ReloadCluster() err := settings.ReloadCluster()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -3,7 +3,6 @@ package cluster
import ( import (
"net/http" "net/http"
"github.com/0xJacky/Nginx-UI/api"
analytic2 "github.com/0xJacky/Nginx-UI/internal/analytic" analytic2 "github.com/0xJacky/Nginx-UI/internal/analytic"
"github.com/0xJacky/Nginx-UI/internal/upgrader" "github.com/0xJacky/Nginx-UI/internal/upgrader"
"github.com/0xJacky/Nginx-UI/internal/version" "github.com/0xJacky/Nginx-UI/internal/version"
@ -11,6 +10,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/shirou/gopsutil/v4/cpu" "github.com/shirou/gopsutil/v4/cpu"
"github.com/shirou/gopsutil/v4/disk" "github.com/shirou/gopsutil/v4/disk"
"github.com/uozi-tech/cosy"
) )
func GetCurrentNode(c *gin.Context) { func GetCurrentNode(c *gin.Context) {
@ -23,7 +23,7 @@ func GetCurrentNode(c *gin.Context) {
runtimeInfo, err := upgrader.GetRuntimeInfo() runtimeInfo, err := upgrader.GetRuntimeInfo()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
cpuInfo, _ := cpu.Info() cpuInfo, _ := cpu.Info()

View file

@ -1,7 +1,11 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"path/filepath"
"time"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
@ -10,10 +14,6 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
"os"
"path/filepath"
"time"
) )
func AddConfig(c *gin.Context) { func AddConfig(c *gin.Context) {
@ -48,14 +48,14 @@ func AddConfig(c *gin.Context) {
if !helper.FileExists(dir) { if !helper.FileExists(dir) {
err := os.MkdirAll(dir, 0755) err := os.MkdirAll(dir, 0755)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
} }
err := os.WriteFile(path, []byte(content), 0644) err := os.WriteFile(path, []byte(content), 0644)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -70,7 +70,7 @@ func AddConfig(c *gin.Context) {
q := query.Config q := query.Config
_, err = q.Where(q.Filepath.Eq(path)).Delete() _, err = q.Where(q.Filepath.Eq(path)).Delete()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -83,13 +83,13 @@ func AddConfig(c *gin.Context) {
err = q.Create(cfg) err = q.Create(cfg)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
err = config.SyncToRemoteServer(cfg) err = config.SyncToRemoteServer(cfg)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,16 +1,17 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"path/filepath"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"net/http" "github.com/uozi-tech/cosy"
"os"
"path/filepath"
) )
type APIConfigResp struct { type APIConfigResp struct {
@ -32,20 +33,20 @@ func GetConfig(c *gin.Context) {
stat, err := os.Stat(absPath) stat, err := os.Stat(absPath)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
content, err := os.ReadFile(absPath) content, err := os.ReadFile(absPath)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
q := query.Config q := query.Config
g := query.ChatGPTLog g := query.ChatGPTLog
chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -55,7 +56,7 @@ func GetConfig(c *gin.Context) {
cfg, err := q.Where(q.Filepath.Eq(absPath)).FirstOrInit() cfg, err := q.Where(q.Filepath.Eq(absPath)).FirstOrInit()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,14 +1,15 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy/logger"
"net/http" "net/http"
"os" "os"
"strings" "strings"
"github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
) )
func GetConfigs(c *gin.Context) { func GetConfigs(c *gin.Context) {
@ -19,7 +20,7 @@ func GetConfigs(c *gin.Context) {
configFiles, err := os.ReadDir(nginx.GetConfPath(dir)) configFiles, err := os.ReadDir(nginx.GetConfPath(dir))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,13 +1,13 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
"os"
) )
func Mkdir(c *gin.Context) { func Mkdir(c *gin.Context) {
@ -28,7 +28,7 @@ func Mkdir(c *gin.Context) {
} }
err := os.Mkdir(fullPath, 0755) err := os.Mkdir(fullPath, 0755)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,7 +1,11 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"path/filepath"
"time"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
@ -11,10 +15,6 @@ import (
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"gorm.io/gen/field" "gorm.io/gen/field"
"net/http"
"os"
"path/filepath"
"time"
) )
type EditConfigJson struct { type EditConfigJson struct {
@ -43,14 +43,14 @@ func EditConfig(c *gin.Context) {
content := json.Content content := json.Content
origContent, err := os.ReadFile(absPath) origContent, err := os.ReadFile(absPath)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
if content != "" && content != string(origContent) { if content != "" && content != string(origContent) {
err = os.WriteFile(absPath, []byte(content), 0644) err = os.WriteFile(absPath, []byte(content), 0644)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
} }
@ -60,7 +60,7 @@ func EditConfig(c *gin.Context) {
Name: filepath.Base(absPath), Name: filepath.Base(absPath),
})).Where(q.Filepath.Eq(absPath)).FirstOrCreate() })).Where(q.Filepath.Eq(absPath)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -71,7 +71,7 @@ func EditConfig(c *gin.Context) {
SyncOverwrite: json.SyncOverwrite, SyncOverwrite: json.SyncOverwrite,
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -82,7 +82,7 @@ func EditConfig(c *gin.Context) {
g := query.ChatGPTLog g := query.ChatGPTLog
err = config.SyncToRemoteServer(cfg) err = config.SyncToRemoteServer(cfg)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -96,7 +96,7 @@ func EditConfig(c *gin.Context) {
chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,7 +1,11 @@
package config package config
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"path/filepath"
"strings"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
@ -9,10 +13,6 @@ import (
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
"os"
"path/filepath"
"strings"
) )
func Rename(c *gin.Context) { func Rename(c *gin.Context) {
@ -45,7 +45,7 @@ func Rename(c *gin.Context) {
stat, err := os.Stat(origFullPath) stat, err := os.Stat(origFullPath)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -58,7 +58,7 @@ func Rename(c *gin.Context) {
err = os.Rename(origFullPath, newFullPath) err = os.Rename(origFullPath, newFullPath)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -67,7 +67,7 @@ func Rename(c *gin.Context) {
q := query.Config q := query.Config
cfg, err := q.Where(q.Filepath.Eq(origFullPath)).FirstOrInit() cfg, err := q.Where(q.Filepath.Eq(origFullPath)).FirstOrInit()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
if !stat.IsDir() { if !stat.IsDir() {
@ -85,14 +85,14 @@ func Rename(c *gin.Context) {
Name: json.NewName, Name: json.NewName,
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
if len(json.SyncNodeIds) > 0 { if len(json.SyncNodeIds) > 0 {
err = config.SyncRenameOnRemoteServer(origFullPath, newFullPath, json.SyncNodeIds) err = config.SyncRenameOnRemoteServer(origFullPath, newFullPath, json.SyncNodeIds)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
} }

View file

@ -3,16 +3,16 @@ package crypto
import ( import (
"net/http" "net/http"
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/crypto" "github.com/0xJacky/Nginx-UI/internal/crypto"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
) )
// GetPublicKey generates a new ED25519 key pair and registers it in the cache // GetPublicKey generates a new ED25519 key pair and registers it in the cache
func GetPublicKey(c *gin.Context) { func GetPublicKey(c *gin.Context) {
params, err := crypto.GetCryptoParams() params, err := crypto.GetCryptoParams()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,11 +1,11 @@
package nginx package nginx
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func BuildNginxConfig(c *gin.Context) { func BuildNginxConfig(c *gin.Context) {
@ -15,7 +15,7 @@ func BuildNginxConfig(c *gin.Context) {
} }
content, err := ngxConf.BuildConfig() content, err := ngxConf.BuildConfig()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
@ -34,7 +34,7 @@ func TokenizeNginxConfig(c *gin.Context) {
ngxConfig, err := nginx.ParseNgxConfigByContent(json.Content) ngxConfig, err := nginx.ParseNgxConfigByContent(json.Content)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
c.JSON(http.StatusOK, ngxConfig) c.JSON(http.StatusOK, ngxConfig)
@ -50,7 +50,7 @@ func FormatNginxConfig(c *gin.Context) {
} }
content, err := nginx.FmtCode(json.Content) content, err := nginx.FmtCode(json.Content)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{

View file

@ -1,13 +1,13 @@
package notification package notification
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/spf13/cast" "github.com/spf13/cast"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func Get(c *gin.Context) { func Get(c *gin.Context) {
@ -18,7 +18,7 @@ func Get(c *gin.Context) {
data, err := n.FirstByID(id) data, err := n.FirstByID(id)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -39,14 +39,14 @@ func DestroyAll(c *gin.Context) {
err := db.Exec("DELETE FROM notifications").Error err := db.Exec("DELETE FROM notifications").Error
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
// reset auto increment // reset auto increment
err = db.Exec("UPDATE sqlite_sequence SET seq = 0 WHERE name = 'notifications';").Error err = db.Exec("UPDATE sqlite_sequence SET seq = 0 WHERE name = 'notifications';").Error
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,13 +1,13 @@
package openai package openai
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/sashabaranov/go-openai" "github.com/sashabaranov/go-openai"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func StoreChatGPTRecord(c *gin.Context) { func StoreChatGPTRecord(c *gin.Context) {
@ -25,7 +25,7 @@ func StoreChatGPTRecord(c *gin.Context) {
_, err := g.Where(g.Name.Eq(name)).FirstOrCreate() _, err := g.Where(g.Name.Eq(name)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -35,7 +35,7 @@ func StoreChatGPTRecord(c *gin.Context) {
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -2,14 +2,14 @@ package settings
import ( import (
"fmt" "fmt"
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/cron" "github.com/0xJacky/Nginx-UI/internal/cron"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
cSettings "github.com/uozi-tech/cosy/settings" cSettings "github.com/uozi-tech/cosy/settings"
"net/http"
) )
func GetServerName(c *gin.Context) { func GetServerName(c *gin.Context) {
@ -87,7 +87,7 @@ func SaveSettings(c *gin.Context) {
err := settings.Save() err := settings.Save()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,12 +1,12 @@
package sites package sites
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func DomainEditByAdvancedMode(c *gin.Context) { func DomainEditByAdvancedMode(c *gin.Context) {
@ -25,14 +25,14 @@ func DomainEditByAdvancedMode(c *gin.Context) {
_, err := s.Where(s.Path.Eq(path)).FirstOrCreate() _, err := s.Where(s.Path.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
_, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced) _, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,13 +1,13 @@
package sites package sites
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certcrypto"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func AddDomainToAutoCert(c *gin.Context) { func AddDomainToAutoCert(c *gin.Context) {
@ -27,7 +27,7 @@ func AddDomainToAutoCert(c *gin.Context) {
certModel, err := model.FirstOrCreateCert(name, helper.GetKeyType(json.KeyType)) certModel, err := model.FirstOrCreateCert(name, helper.GetKeyType(json.KeyType))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -40,7 +40,7 @@ func AddDomainToAutoCert(c *gin.Context) {
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -52,7 +52,7 @@ func RemoveDomainFromAutoCert(c *gin.Context) {
certModel, err := model.FirstCert(name) certModel, err := model.FirstCert(name)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -61,7 +61,7 @@ func RemoveDomainFromAutoCert(c *gin.Context) {
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
c.JSON(http.StatusOK, nil) c.JSON(http.StatusOK, nil)

View file

@ -1,11 +1,11 @@
package sites package sites
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/site" "github.com/0xJacky/Nginx-UI/internal/site"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func DuplicateSite(c *gin.Context) { func DuplicateSite(c *gin.Context) {
@ -23,7 +23,7 @@ func DuplicateSite(c *gin.Context) {
err := site.Duplicate(src, json.Name) err := site.Duplicate(src, json.Name)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,7 +1,11 @@
package sites package sites
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"path/filepath"
"strings"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
@ -9,10 +13,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/samber/lo" "github.com/samber/lo"
"github.com/spf13/cast" "github.com/spf13/cast"
"net/http" "github.com/uozi-tech/cosy"
"os"
"path/filepath"
"strings"
) )
func GetSiteList(c *gin.Context) { func GetSiteList(c *gin.Context) {
@ -24,13 +25,13 @@ func GetSiteList(c *gin.Context) {
configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available")) configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled")) enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -41,7 +42,7 @@ func GetSiteList(c *gin.Context) {
} }
sites, err := sTx.Find() sites, err := sTx.Find()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
sitesMap := lo.SliceToMap(sites, func(item *model.Site) (string, *model.Site) { sitesMap := lo.SliceToMap(sites, func(item *model.Site) (string, *model.Site) {

View file

@ -1,7 +1,9 @@
package sites package sites
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"os"
"github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cert"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/internal/site" "github.com/0xJacky/Nginx-UI/internal/site"
@ -12,8 +14,6 @@ import (
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger" "github.com/uozi-tech/cosy/logger"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"net/http"
"os"
) )
func GetSite(c *gin.Context) { func GetSite(c *gin.Context) {
@ -36,7 +36,7 @@ func GetSite(c *gin.Context) {
g := query.ChatGPTLog g := query.ChatGPTLog
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -47,7 +47,7 @@ func GetSite(c *gin.Context) {
s := query.Site s := query.Site
siteModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate() siteModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -59,7 +59,7 @@ func GetSite(c *gin.Context) {
if siteModel.Advanced { if siteModel.Advanced {
origContent, err := os.ReadFile(path) origContent, err := os.ReadFile(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -78,7 +78,7 @@ func GetSite(c *gin.Context) {
nginxConfig, err := nginx.ParseNgxConfig(path) nginxConfig, err := nginx.ParseNgxConfig(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -126,7 +126,7 @@ func SaveSite(c *gin.Context) {
err := site.Save(name, json.Content, json.Overwrite, json.SiteCategoryID, json.SyncNodeIDs) err := site.Save(name, json.Content, json.Overwrite, json.SiteCategoryID, json.SyncNodeIDs)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -144,7 +144,7 @@ func RenameSite(c *gin.Context) {
err := site.Rename(oldName, json.NewName) err := site.Rename(oldName, json.NewName)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -156,7 +156,7 @@ func RenameSite(c *gin.Context) {
func EnableSite(c *gin.Context) { func EnableSite(c *gin.Context) {
err := site.Enable(c.Param("name")) err := site.Enable(c.Param("name"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -168,7 +168,7 @@ func EnableSite(c *gin.Context) {
func DisableSite(c *gin.Context) { func DisableSite(c *gin.Context) {
err := site.Disable(c.Param("name")) err := site.Disable(c.Param("name"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -180,7 +180,7 @@ func DisableSite(c *gin.Context) {
func DeleteSite(c *gin.Context) { func DeleteSite(c *gin.Context) {
err := site.Delete(c.Param("name")) err := site.Delete(c.Param("name"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -3,7 +3,6 @@ package streams
import ( import (
"net/http" "net/http"
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -26,14 +25,14 @@ func AdvancedEdit(c *gin.Context) {
_, err := s.Where(s.Path.Eq(path)).FirstOrCreate() _, err := s.Where(s.Path.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
_, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced) _, err = s.Where(s.Path.Eq(path)).Update(s.Advanced, json.Advanced)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,12 +1,12 @@
package streams package streams
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/helper"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"net/http"
) )
func Duplicate(c *gin.Context) { func Duplicate(c *gin.Context) {
@ -35,7 +35,7 @@ func Duplicate(c *gin.Context) {
_, err := helper.CopyFile(src, dst) _, err := helper.CopyFile(src, dst)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -6,7 +6,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/config"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/internal/stream" "github.com/0xJacky/Nginx-UI/internal/stream"
@ -35,13 +34,13 @@ func GetStreams(c *gin.Context) {
configFiles, err := os.ReadDir(nginx.GetConfPath("streams-available")) configFiles, err := os.ReadDir(nginx.GetConfPath("streams-available"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
enabledConfig, err := os.ReadDir(nginx.GetConfPath("streams-enabled")) enabledConfig, err := os.ReadDir(nginx.GetConfPath("streams-enabled"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -98,7 +97,7 @@ func GetStream(c *gin.Context) {
chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -109,14 +108,14 @@ func GetStream(c *gin.Context) {
s := query.Stream s := query.Stream
streamModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate() streamModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
if streamModel.Advanced { if streamModel.Advanced {
origContent, err := os.ReadFile(path) origContent, err := os.ReadFile(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -136,7 +135,7 @@ func GetStream(c *gin.Context) {
nginxConfig, err := nginx.ParseNgxConfig(path) nginxConfig, err := nginx.ParseNgxConfig(path)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -168,7 +167,7 @@ func SaveStream(c *gin.Context) {
err := stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs) err := stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -178,7 +177,7 @@ func SaveStream(c *gin.Context) {
func EnableStream(c *gin.Context) { func EnableStream(c *gin.Context) {
err := stream.Enable(c.Param("name")) err := stream.Enable(c.Param("name"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -190,7 +189,7 @@ func EnableStream(c *gin.Context) {
func DisableStream(c *gin.Context) { func DisableStream(c *gin.Context) {
err := stream.Disable(c.Param("name")) err := stream.Disable(c.Param("name"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -202,7 +201,7 @@ func DisableStream(c *gin.Context) {
func DeleteStream(c *gin.Context) { func DeleteStream(c *gin.Context) {
err := stream.Delete(c.Param("name")) err := stream.Delete(c.Param("name"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -222,7 +221,7 @@ func RenameStream(c *gin.Context) {
err := stream.Rename(oldName, json.NewName) err := stream.Rename(oldName, json.NewName)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -9,7 +9,6 @@ import (
"strings" "strings"
"time" "time"
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/backup" "github.com/0xJacky/Nginx-UI/internal/backup"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/jpillora/overseer" "github.com/jpillora/overseer"
@ -18,9 +17,9 @@ import (
// RestoreResponse contains the response data for restore operation // RestoreResponse contains the response data for restore operation
type RestoreResponse struct { type RestoreResponse struct {
NginxUIRestored bool `json:"nginx_ui_restored"` NginxUIRestored bool `json:"nginx_ui_restored"`
NginxRestored bool `json:"nginx_restored"` NginxRestored bool `json:"nginx_restored"`
HashMatch bool `json:"hash_match"` HashMatch bool `json:"hash_match"`
} }
// CreateBackup creates a backup of nginx-ui and nginx configurations // CreateBackup creates a backup of nginx-ui and nginx configurations
@ -28,7 +27,7 @@ type RestoreResponse struct {
func CreateBackup(c *gin.Context) { func CreateBackup(c *gin.Context) {
result, err := backup.Backup() result, err := backup.Backup()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -65,20 +64,20 @@ func RestoreBackup(c *gin.Context) {
// Get backup file // Get backup file
backupFile, err := c.FormFile("backup_file") backupFile, err := c.FormFile("backup_file")
if err != nil { if err != nil {
api.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrBackupFileNotFound, err.Error())) cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrBackupFileNotFound, err.Error()))
return return
} }
// Validate security token // Validate security token
if securityToken == "" { if securityToken == "" {
api.ErrHandler(c, backup.ErrInvalidSecurityToken) cosy.ErrHandler(c, backup.ErrInvalidSecurityToken)
return return
} }
// Split security token to get Key and IV // Split security token to get Key and IV
parts := strings.Split(securityToken, ":") parts := strings.Split(securityToken, ":")
if len(parts) != 2 { if len(parts) != 2 {
api.ErrHandler(c, backup.ErrInvalidSecurityToken) cosy.ErrHandler(c, backup.ErrInvalidSecurityToken)
return return
} }
@ -88,20 +87,20 @@ func RestoreBackup(c *gin.Context) {
// Decode Key and IV from base64 // Decode Key and IV from base64
key, err := base64.StdEncoding.DecodeString(aesKey) key, err := base64.StdEncoding.DecodeString(aesKey)
if err != nil { if err != nil {
api.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESKey, err.Error())) cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESKey, err.Error()))
return return
} }
iv, err := base64.StdEncoding.DecodeString(aesIv) iv, err := base64.StdEncoding.DecodeString(aesIv)
if err != nil { if err != nil {
api.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESIV, err.Error())) cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrInvalidAESIV, err.Error()))
return return
} }
// Create temporary directory for files // Create temporary directory for files
tempDir, err := os.MkdirTemp("", "nginx-ui-restore-upload-*") tempDir, err := os.MkdirTemp("", "nginx-ui-restore-upload-*")
if err != nil { if err != nil {
api.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrCreateTempDir, err.Error())) cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrCreateTempDir, err.Error()))
return return
} }
defer os.RemoveAll(tempDir) defer os.RemoveAll(tempDir)
@ -109,14 +108,14 @@ func RestoreBackup(c *gin.Context) {
// Save backup file // Save backup file
backupPath := filepath.Join(tempDir, backupFile.Filename) backupPath := filepath.Join(tempDir, backupFile.Filename)
if err := c.SaveUploadedFile(backupFile, backupPath); err != nil { if err := c.SaveUploadedFile(backupFile, backupPath); err != nil {
api.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrCreateBackupFile, err.Error())) cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrCreateBackupFile, err.Error()))
return return
} }
// Create temporary directory for restore operation // Create temporary directory for restore operation
restoreDir, err := os.MkdirTemp("", "nginx-ui-restore-*") restoreDir, err := os.MkdirTemp("", "nginx-ui-restore-*")
if err != nil { if err != nil {
api.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrCreateRestoreDir, err.Error())) cosy.ErrHandler(c, cosy.WrapErrorWithParams(backup.ErrCreateRestoreDir, err.Error()))
return return
} }
@ -136,7 +135,7 @@ func RestoreBackup(c *gin.Context) {
if err != nil { if err != nil {
// Clean up temporary directory on error // Clean up temporary directory on error
os.RemoveAll(restoreDir) os.RemoveAll(restoreDir)
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -1,8 +1,11 @@
package system package system
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"time"
"github.com/0xJacky/Nginx-UI/internal/kernel" "github.com/0xJacky/Nginx-UI/internal/kernel"
"github.com/0xJacky/Nginx-UI/internal/system"
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
@ -11,16 +14,36 @@ import (
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
cSettings "github.com/uozi-tech/cosy/settings" cSettings "github.com/uozi-tech/cosy/settings"
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
"net/http"
) )
// System startup time
var startupTime time.Time
func init() {
// Record system startup time
startupTime = time.Now()
}
func installLockStatus() bool { func installLockStatus() bool {
return settings.NodeSettings.SkipInstallation || "" != cSettings.AppSettings.JwtSecret return settings.NodeSettings.SkipInstallation || "" != cSettings.AppSettings.JwtSecret
} }
// Check if installation time limit (10 minutes) is exceeded
func isInstallTimeoutExceeded() bool {
return time.Since(startupTime) > 10*time.Minute
}
func InstallLockCheck(c *gin.Context) { func InstallLockCheck(c *gin.Context) {
locked := installLockStatus()
timeout := false
if !locked {
timeout = isInstallTimeoutExceeded()
}
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"lock": installLockStatus(), "lock": locked,
"timeout": timeout,
}) })
} }
@ -39,6 +62,13 @@ func InstallNginxUI(c *gin.Context) {
}) })
return return
} }
// Check if installation time limit (10 minutes) is exceeded
if isInstallTimeoutExceeded() {
cosy.ErrHandler(c, system.ErrInstallTimeout)
return
}
var json InstallJson var json InstallJson
ok := cosy.BindAndValid(c, &json) ok := cosy.BindAndValid(c, &json)
if !ok { if !ok {
@ -54,7 +84,7 @@ func InstallNginxUI(c *gin.Context) {
err := settings.Save() err := settings.Save()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -70,7 +100,7 @@ func InstallNginxUI(c *gin.Context) {
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -4,24 +4,24 @@ import (
"net/http" "net/http"
"os" "os"
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/upgrader" "github.com/0xJacky/Nginx-UI/internal/upgrader"
"github.com/0xJacky/Nginx-UI/internal/version" "github.com/0xJacky/Nginx-UI/internal/version"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger" "github.com/uozi-tech/cosy/logger"
) )
func GetRelease(c *gin.Context) { func GetRelease(c *gin.Context) {
data, err := upgrader.GetRelease(c.Query("channel")) data, err := upgrader.GetRelease(c.Query("channel"))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
runtimeInfo, err := upgrader.GetRuntimeInfo() runtimeInfo, err := upgrader.GetRuntimeInfo()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
type resp struct { type resp struct {

View file

@ -1,11 +1,13 @@
package template package template
import ( import (
"github.com/0xJacky/Nginx-UI/api" "net/http"
"github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/nginx"
"github.com/0xJacky/Nginx-UI/internal/template" "github.com/0xJacky/Nginx-UI/internal/template"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"net/http"
"github.com/uozi-tech/cosy"
) )
func GetDefaultSiteTemplate(c *gin.Context) { func GetDefaultSiteTemplate(c *gin.Context) {
@ -40,7 +42,7 @@ func GetDefaultSiteTemplate(c *gin.Context) {
content, err := ngxConfig.BuildConfig() content, err := ngxConfig.BuildConfig()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -55,7 +57,7 @@ func GetTemplateConfList(c *gin.Context) {
configList, err := template.GetTemplateList("conf") configList, err := template.GetTemplateList("conf")
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -67,7 +69,7 @@ func GetTemplateConfList(c *gin.Context) {
func GetTemplateBlockList(c *gin.Context) { func GetTemplateBlockList(c *gin.Context) {
configList, err := template.GetTemplateList("block") configList, err := template.GetTemplateList("block")
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -91,7 +93,7 @@ func GetTemplateBlock(c *gin.Context) {
detail, err := template.ParseTemplate("block", c.Param("name"), bindData) detail, err := template.ParseTemplate("block", c.Param("name"), bindData)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
info.Variables = bindData info.Variables = bindData

View file

@ -81,17 +81,17 @@ func Start2FASecureSessionByOTP(c *gin.Context) {
} }
u := api.CurrentUser(c) u := api.CurrentUser(c)
if !u.EnabledOTP() { if !u.EnabledOTP() {
api.ErrHandler(c, user.ErrUserNotEnabledOTPAs2FA) cosy.ErrHandler(c, user.ErrUserNotEnabledOTPAs2FA)
return return
} }
if json.OTP == "" && json.RecoveryCode == "" { if json.OTP == "" && json.RecoveryCode == "" {
api.ErrHandler(c, user.ErrOTPOrRecoveryCodeEmpty) cosy.ErrHandler(c, user.ErrOTPOrRecoveryCodeEmpty)
return return
} }
if err := user.VerifyOTP(u, json.OTP, json.RecoveryCode); err != nil { if err := user.VerifyOTP(u, json.OTP, json.RecoveryCode); err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -104,14 +104,14 @@ func Start2FASecureSessionByOTP(c *gin.Context) {
func BeginStart2FASecureSessionByPasskey(c *gin.Context) { func BeginStart2FASecureSessionByPasskey(c *gin.Context) {
if !passkey.Enabled() { if !passkey.Enabled() {
api.ErrHandler(c, user.ErrWebAuthnNotConfigured) cosy.ErrHandler(c, user.ErrWebAuthnNotConfigured)
return return
} }
webauthnInstance := passkey.GetInstance() webauthnInstance := passkey.GetInstance()
u := api.CurrentUser(c) u := api.CurrentUser(c)
options, sessionData, err := webauthnInstance.BeginLogin(u) options, sessionData, err := webauthnInstance.BeginLogin(u)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
passkeySessionID := uuid.NewString() passkeySessionID := uuid.NewString()
@ -124,13 +124,13 @@ func BeginStart2FASecureSessionByPasskey(c *gin.Context) {
func FinishStart2FASecureSessionByPasskey(c *gin.Context) { func FinishStart2FASecureSessionByPasskey(c *gin.Context) {
if !passkey.Enabled() { if !passkey.Enabled() {
api.ErrHandler(c, user.ErrWebAuthnNotConfigured) cosy.ErrHandler(c, user.ErrWebAuthnNotConfigured)
return return
} }
passkeySessionID := c.GetHeader("X-Passkey-Session-ID") passkeySessionID := c.GetHeader("X-Passkey-Session-ID")
sessionDataBytes, ok := cache.Get(passkeySessionID) sessionDataBytes, ok := cache.Get(passkeySessionID)
if !ok { if !ok {
api.ErrHandler(c, user.ErrSessionNotFound) cosy.ErrHandler(c, user.ErrSessionNotFound)
return return
} }
sessionData := sessionDataBytes.(*webauthn.SessionData) sessionData := sessionDataBytes.(*webauthn.SessionData)
@ -138,7 +138,7 @@ func FinishStart2FASecureSessionByPasskey(c *gin.Context) {
u := api.CurrentUser(c) u := api.CurrentUser(c)
credential, err := webauthnInstance.FinishLogin(u, *sessionData, c.Request) credential, err := webauthnInstance.FinishLogin(u, *sessionData, c.Request)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
rawID := strings.TrimRight(base64.StdEncoding.EncodeToString(credential.ID), "=") rawID := strings.TrimRight(base64.StdEncoding.EncodeToString(credential.ID), "=")

View file

@ -1,18 +1,18 @@
package user package user
import ( import (
"github.com/0xJacky/Nginx-UI/api"
"github.com/0xJacky/Nginx-UI/internal/user"
"github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"errors" "errors"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
"math/rand/v2" "math/rand/v2"
"net/http" "net/http"
"sync" "sync"
"time" "time"
"github.com/0xJacky/Nginx-UI/internal/user"
"github.com/0xJacky/Nginx-UI/query"
"github.com/0xJacky/Nginx-UI/settings"
"github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
"github.com/uozi-tech/cosy/logger"
) )
var mutex = &sync.Mutex{} var mutex = &sync.Mutex{}
@ -75,7 +75,7 @@ func Login(c *gin.Context) {
case errors.Is(err, user.ErrUserBanned): case errors.Is(err, user.ErrUserBanned):
c.JSON(http.StatusForbidden, user.ErrUserBanned) c.JSON(http.StatusForbidden, user.ErrUserBanned)
default: default:
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
} }
user.BanIP(clientIP) user.BanIP(clientIP)
return return

View file

@ -1,18 +1,18 @@
package user package user
import ( import (
"errors"
"fmt" "fmt"
"github.com/0xJacky/Nginx-UI/api" "net/http"
"net/url"
"os"
"github.com/0xJacky/Nginx-UI/internal/user" "github.com/0xJacky/Nginx-UI/internal/user"
"github.com/0xJacky/Nginx-UI/settings" "github.com/0xJacky/Nginx-UI/settings"
"github.com/casdoor/casdoor-go-sdk/casdoorsdk" "github.com/casdoor/casdoor-go-sdk/casdoorsdk"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"errors"
"github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy"
"gorm.io/gorm" "gorm.io/gorm"
"net/http"
"net/url"
"os"
) )
type CasdoorLoginUser struct { type CasdoorLoginUser struct {
@ -44,7 +44,7 @@ func CasdoorCallback(c *gin.Context) {
certBytes, err := os.ReadFile(certificatePath) certBytes, err := os.ReadFile(certificatePath)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -52,13 +52,13 @@ func CasdoorCallback(c *gin.Context) {
token, err := casdoorsdk.GetOAuthToken(loginUser.Code, loginUser.State) token, err := casdoorsdk.GetOAuthToken(loginUser.Code, loginUser.State)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
claims, err := casdoorsdk.ParseJwtToken(token.AccessToken) claims, err := casdoorsdk.ParseJwtToken(token.AccessToken)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -69,14 +69,14 @@ func CasdoorCallback(c *gin.Context) {
"message": "User not exist", "message": "User not exist",
}) })
} else { } else {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
} }
return return
} }
userToken, err := user.GenerateJWT(u) userToken, err := user.GenerateJWT(u)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -32,7 +32,7 @@ func GenerateTOTP(c *gin.Context) {
} }
otpKey, err := totp.Generate(otpOpts) otpKey, err := totp.Generate(otpOpts)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -75,14 +75,14 @@ func EnrollTOTP(c *gin.Context) {
ciphertext, err := crypto.AesEncrypt([]byte(twoFA.Secret)) ciphertext, err := crypto.AesEncrypt([]byte(twoFA.Secret))
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
u := query.User u := query.User
_, err = u.Where(u.ID.Eq(cUser.ID)).Update(u.OTPSecret, ciphertext) _, err = u.Where(u.ID.Eq(cUser.ID)).Update(u.OTPSecret, ciphertext)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -91,7 +91,7 @@ func EnrollTOTP(c *gin.Context) {
cUser.RecoveryCodes = recoveryCodes cUser.RecoveryCodes = recoveryCodes
_, err = u.Where(u.ID.Eq(cUser.ID)).Updates(cUser) _, err = u.Where(u.ID.Eq(cUser.ID)).Updates(cUser)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -106,7 +106,7 @@ func ResetOTP(c *gin.Context) {
u := query.User u := query.User
_, err := u.Where(u.ID.Eq(cUser.ID)).UpdateSimple(u.OTPSecret.Null(), u.RecoveryCodes.Null()) _, err := u.Where(u.ID.Eq(cUser.ID)).UpdateSimple(u.OTPSecret.Null(), u.RecoveryCodes.Null())
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -40,7 +40,7 @@ func BeginPasskeyRegistration(c *gin.Context) {
options, sessionData, err := webauthnInstance.BeginRegistration(u) options, sessionData, err := webauthnInstance.BeginRegistration(u)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
cache.Set(buildCachePasskeyRegKey(u.ID), sessionData, passkeyTimeout) cache.Set(buildCachePasskeyRegKey(u.ID), sessionData, passkeyTimeout)
@ -53,14 +53,14 @@ func FinishPasskeyRegistration(c *gin.Context) {
webauthnInstance := passkey.GetInstance() webauthnInstance := passkey.GetInstance()
sessionDataBytes, ok := cache.Get(buildCachePasskeyRegKey(cUser.ID)) sessionDataBytes, ok := cache.Get(buildCachePasskeyRegKey(cUser.ID))
if !ok { if !ok {
api.ErrHandler(c, user.ErrSessionNotFound) cosy.ErrHandler(c, user.ErrSessionNotFound)
return return
} }
sessionData := sessionDataBytes.(*webauthn.SessionData) sessionData := sessionDataBytes.(*webauthn.SessionData)
credential, err := webauthnInstance.FinishRegistration(cUser, *sessionData, c.Request) credential, err := webauthnInstance.FinishRegistration(cUser, *sessionData, c.Request)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
cache.Del(buildCachePasskeyRegKey(cUser.ID)) cache.Del(buildCachePasskeyRegKey(cUser.ID))
@ -76,7 +76,7 @@ func FinishPasskeyRegistration(c *gin.Context) {
LastUsedAt: time.Now().Unix(), LastUsedAt: time.Now().Unix(),
}) })
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -87,13 +87,13 @@ func FinishPasskeyRegistration(c *gin.Context) {
func BeginPasskeyLogin(c *gin.Context) { func BeginPasskeyLogin(c *gin.Context) {
if !passkey.Enabled() { if !passkey.Enabled() {
api.ErrHandler(c, user.ErrWebAuthnNotConfigured) cosy.ErrHandler(c, user.ErrWebAuthnNotConfigured)
return return
} }
webauthnInstance := passkey.GetInstance() webauthnInstance := passkey.GetInstance()
options, sessionData, err := webauthnInstance.BeginDiscoverableLogin() options, sessionData, err := webauthnInstance.BeginDiscoverableLogin()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
sessionID := uuid.NewString() sessionID := uuid.NewString()
@ -107,13 +107,13 @@ func BeginPasskeyLogin(c *gin.Context) {
func FinishPasskeyLogin(c *gin.Context) { func FinishPasskeyLogin(c *gin.Context) {
if !passkey.Enabled() { if !passkey.Enabled() {
api.ErrHandler(c, user.ErrWebAuthnNotConfigured) cosy.ErrHandler(c, user.ErrWebAuthnNotConfigured)
return return
} }
sessionId := c.GetHeader("X-Passkey-Session-ID") sessionId := c.GetHeader("X-Passkey-Session-ID")
sessionDataBytes, ok := cache.Get(sessionId) sessionDataBytes, ok := cache.Get(sessionId)
if !ok { if !ok {
api.ErrHandler(c, user.ErrSessionNotFound) cosy.ErrHandler(c, user.ErrSessionNotFound)
return return
} }
webauthnInstance := passkey.GetInstance() webauthnInstance := passkey.GetInstance()
@ -134,7 +134,7 @@ func FinishPasskeyLogin(c *gin.Context) {
return outUser, err return outUser, err
}, *sessionData, c.Request) }, *sessionData, c.Request)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -167,7 +167,7 @@ func GetPasskeyList(c *gin.Context) {
p := query.Passkey p := query.Passkey
passkeys, err := p.Where(p.UserID.Eq(u.ID)).Find() passkeys, err := p.Where(p.UserID.Eq(u.ID)).Find()
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -10,6 +10,7 @@ import (
"github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/model"
"github.com/0xJacky/Nginx-UI/query" "github.com/0xJacky/Nginx-UI/query"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/uozi-tech/cosy"
) )
type RecoveryCodesResponse struct { type RecoveryCodesResponse struct {
@ -41,7 +42,7 @@ func ViewRecoveryCodes(c *gin.Context) {
user.RecoveryCodes.LastViewed = &t user.RecoveryCodes.LastViewed = &t
_, err := u.Where(u.ID.Eq(user.ID)).Updates(user) _, err := u.Where(u.ID.Eq(user.ID)).Updates(user)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }
@ -61,7 +62,7 @@ func GenerateRecoveryCodes(c *gin.Context) {
u := query.User u := query.User
_, err := u.Where(u.ID.Eq(user.ID)).Updates(user) _, err := u.Where(u.ID.Eq(user.ID)).Updates(user)
if err != nil { if err != nil {
api.ErrHandler(c, err) cosy.ErrHandler(c, err)
return return
} }

View file

@ -165,14 +165,14 @@ function handleCopy(copy) {
line-height: 1.6; line-height: 1.6;
} }
/* 暗夜模式优化 */ /* Dark mode optimization */
:deep(.backup-token-modal) { :deep(.backup-token-modal) {
/* 模态框背景 */ /* Modal background */
.ant-modal-content { .ant-modal-content {
background-color: #1f1f1f; background-color: #1f1f1f;
} }
/* 模态框标题 */ /* Modal title */
.ant-modal-header { .ant-modal-header {
background-color: #1f1f1f; background-color: #1f1f1f;
border-bottom: 1px solid #303030; border-bottom: 1px solid #303030;
@ -182,24 +182,24 @@ function handleCopy(copy) {
color: #e6e6e6; color: #e6e6e6;
} }
/* 模态框内容 */ /* Modal content */
.ant-modal-body { .ant-modal-body {
color: #e6e6e6; color: #e6e6e6;
} }
/* 模态框底部 */ /* Modal footer */
.ant-modal-footer { .ant-modal-footer {
border-top: 1px solid #303030; border-top: 1px solid #303030;
background-color: #1f1f1f; background-color: #1f1f1f;
} }
/* 关闭按钮 */ /* Close button */
.ant-modal-close-x { .ant-modal-close-x {
color: #e6e6e6; color: #e6e6e6;
} }
} }
/* 令牌容器暗夜模式样式 */ /* Token container dark mode styles */
.dark { .dark {
.token-container { .token-container {
background-color: #262626 !important; background-color: #262626 !important;
@ -211,7 +211,7 @@ function handleCopy(copy) {
color: #d9d9d9; color: #d9d9d9;
} }
/* 警告框暗夜模式 */ /* Warning box dark mode */
.warning-box { .warning-box {
background-color: rgba(255, 77, 79, 0.1); background-color: rgba(255, 77, 79, 0.1);
border-color: rgba(255, 77, 79, 0.3); border-color: rgba(255, 77, 79, 0.3);
@ -222,7 +222,7 @@ function handleCopy(copy) {
} }
} }
/* 媒体查询方式添加暗夜模式支持 */ /* Dark mode support via media query */
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
.token-container { .token-container {
background-color: #262626 !important; background-color: #262626 !important;

View file

@ -0,0 +1,9 @@
package system
import "github.com/uozi-tech/cosy"
// System error definitions
var (
e = cosy.NewErrorScope("system")
ErrInstallTimeout = e.New(40308, "installation is not allowed after 10 minutes of system startup")
)