fix: Remove the jwt login mode (#8242)

This commit is contained in:
ssongliu 2025-03-25 17:29:34 +08:00 committed by GitHub
parent b871c710b2
commit 11349642da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 153 additions and 268 deletions

View file

@ -564,10 +564,12 @@ func loadTreeWithDir(isCheck bool, treeType, pathItem string, fileOp fileUtils.F
return lists
}
sort.Slice(files, func(i, j int) bool {
return files[i].Name() > files[j].Name()
infoI, _ := files[i].Info()
infoJ, _ := files[i].Info()
return infoI.ModTime().Before(infoJ.ModTime())
})
for _, file := range files {
if (treeType == "old_upgrade" || treeType == "upgrade") && !strings.HasPrefix(file.Name(), "upgrade_2023") {
if treeType == "old_upgrade" {
continue
}
if treeType == "task_log" && file.Name() == "ssl" {

View file

@ -2,6 +2,7 @@ package v2
import (
"encoding/base64"
"github.com/1Panel-dev/1Panel/core/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/core/app/dto"
"github.com/1Panel-dev/1Panel/core/app/model"
@ -25,7 +26,7 @@ func (b *BaseApi) Login(c *gin.Context) {
return
}
if req.AuthMethod != "jwt" && !req.IgnoreCaptcha {
if !req.IgnoreCaptcha {
if errMsg := captcha.VerifyCode(req.CaptchaID, req.Captcha); errMsg != "" {
helper.BadAuth(c, errMsg, nil)
return

View file

@ -28,7 +28,6 @@ type Login struct {
IgnoreCaptcha bool `json:"ignoreCaptcha"`
Captcha string `json:"captcha"`
CaptchaID string `json:"captchaID"`
AuthMethod string `json:"authMethod" validate:"required,oneof=jwt session"`
Language string `json:"language" validate:"required,oneof=zh en 'zh-Hant' ko ja ru ms 'pt-BR'"`
}
@ -36,7 +35,6 @@ type MFALogin struct {
Name string `json:"name" validate:"required"`
Password string `json:"password" validate:"required"`
Code string `json:"code" validate:"required"`
AuthMethod string `json:"authMethod"`
}
type SystemSetting struct {

View file

@ -10,7 +10,6 @@ import (
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/1Panel-dev/1Panel/core/global"
"github.com/1Panel-dev/1Panel/core/utils/encrypt"
"github.com/1Panel-dev/1Panel/core/utils/jwt"
"github.com/1Panel-dev/1Panel/core/utils/mfa"
"github.com/gin-gonic/gin"
)
@ -59,7 +58,7 @@ func (u *AuthService) Login(c *gin.Context, info dto.Login, entrance string) (*d
if mfa.Value == constant.StatusEnable {
return &dto.UserLoginInfo{Name: nameSetting.Value, MfaStatus: mfa.Value}, "", nil
}
res, err := u.generateSession(c, info.Name, info.AuthMethod)
res, err := u.generateSession(c, info.Name)
if err != nil {
return nil, "", err
}
@ -96,14 +95,14 @@ func (u *AuthService) MFALogin(c *gin.Context, info dto.MFALogin, entrance strin
if !success {
return nil, "ErrAuth", nil
}
res, err := u.generateSession(c, info.Name, info.AuthMethod)
res, err := u.generateSession(c, info.Name)
if err != nil {
return nil, "", err
}
return res, "", nil
}
func (u *AuthService) generateSession(c *gin.Context, name, authMethod string) (*dto.UserLoginInfo, error) {
func (u *AuthService) generateSession(c *gin.Context, name string) (*dto.UserLoginInfo, error) {
setting, err := settingRepo.Get(repo.WithByKey("SessionTimeout"))
if err != nil {
return nil, err
@ -117,18 +116,6 @@ func (u *AuthService) generateSession(c *gin.Context, name, authMethod string) (
return nil, err
}
if authMethod == constant.AuthMethodJWT {
j := jwt.NewJWT()
claims := j.CreateClaims(jwt.BaseClaims{
Name: name,
IsAgent: false,
})
token, err := j.CreateToken(claims)
if err != nil {
return nil, err
}
return &dto.UserLoginInfo{Name: name, Token: token}, nil
}
sessionUser, err := global.SESSION.Get(c)
if err != nil {
err := global.SESSION.Set(c, sessionUser, httpsSetting.Value == constant.StatusEnable, lifeTime)

View file

@ -172,7 +172,11 @@ func (u *UpgradeService) Upgrade(req dto.Upgrade) error {
_ = settingRepo.Update("SystemVersion", req.Version)
global.CONF.Base.Version = req.Version
_ = settingRepo.Update("SystemStatus", "Free")
_, _ = cmd.ExecWithTimeOut("systemctl daemon-reload && systemctl restart 1pane-agent.service && systemctl restart 1panel-core.service", 1*time.Minute)
go func() {
_, _ = cmd.ExecWithTimeOut("systemctl daemon-reload && systemctl restart 1pane-agent.service", 1*time.Minute)
}()
_, _ = cmd.ExecWithTimeOut("systemctl daemon-reload && systemctl restart 1panel-core.service", 1*time.Minute)
}()
return nil
}

View file

@ -4,10 +4,5 @@ const (
AuthMethodSession = "session"
SessionName = "psession"
AuthMethodJWT = "jwt"
JWTHeaderName = "PanelAuthorization"
JWTBufferTime = 3600
JWTIssuer = "1Panel"
PasswordExpiredName = "expired"
)

View file

@ -14,7 +14,6 @@ require (
github.com/go-playground/validator/v10 v10.22.0
github.com/go-resty/resty/v2 v2.15.3
github.com/goh-chunlin/go-onedrive v1.1.1
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/google/uuid v1.6.0
github.com/gorilla/securecookie v1.1.2
github.com/gorilla/sessions v1.4.0
@ -30,7 +29,6 @@ require (
github.com/robfig/cron/v3 v3.0.1
github.com/sirupsen/logrus v1.9.3
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.1
github.com/spf13/viper v1.19.0
github.com/studio-b12/gowebdav v0.9.0
@ -105,6 +103,7 @@ require (
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect

View file

@ -146,8 +146,6 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/goh-chunlin/go-onedrive v1.1.1 h1:HGtHk5iG0MZ92zYUtaY04czfZPBIJUr12UuFc+PW8m4=
github.com/goh-chunlin/go-onedrive v1.1.1/go.mod h1:N8qIGHD7tryO734epiBKk5oXcpGwxKET/u3LuBHciTs=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=

View file

@ -430,115 +430,134 @@ exit 0`
func loadInstallClamAV() string {
return `#!/bin/bash
# 检查是否具有 sudo 权限
if [ "$EUID" -ne 0 ]; then
echo "请使用 sudo 或以 root 用户运行此脚本"
exit 1
fi
# ClamAV 安装配置脚本
# 支持系统Ubuntu/Debian/CentOS/RHEL/Rocky/AlmaLinux
# 检测操作系统类型
# 识别系统类型
if [ -f /etc/os-release ]; then
. /etc/os-release
OS=$ID
OS_LIKE=$(echo $ID_LIKE | awk '{print $1}') # 获取类似的发行版信息
OS_VER=$VERSION_ID
elif type lsb_release >/dev/null 2>&1; then
OS=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
OS_VER=$(lsb_release -sr)
else
echo "无法检测操作系统类型"
echo "无法识别操作系统"
exit 1
fi
# 安装 ClamAV
if [ "$OS" == "ubuntu" ] || [ "$OS" == "debian" ]; then
echo "检测到 Debian/Ubuntu 系统,正在安装 ClamAV..."
# 安装ClamAV
install_clamav() {
case $OS in
ubuntu|debian)
apt-get update
apt-get install -y clamav clamav-daemon clamav-freshclam
elif [ "$OS" == "centos" ] || [ "$OS" == "rhel" ] || [ "$OS_LIKE" == "rhel" ]; then
echo "检测到 Red Hat/CentOS 系统,正在安装 ClamAV..."
apt-get install -y clamav clamav-daemon
;;
centos|rhel|rocky|almalinux)
if [[ $OS_VER == 7* ]]; then
yum install -y epel-release
yum install -y clamav clamd clamav-update
else
echo "不支持的操作系统: $OS"
else
dnf install -y clamav clamd clamav-update
fi
;;
*)
echo "不支持的OS: $OS"
exit 1
fi
;;
esac
}
# 配置 clamd
CLAMD_CONF="/etc/clamd.d/scan.conf"
if [ -f "$CLAMD_CONF" ]; then
echo "配置 clamd..."
configure_clamd() {
CLAMD_CONF=""
if [ -f "/etc/clamd.d/scan.conf" ]; then
CLAMD_CONF="/etc/clamd.d/scan.conf"
elif [ -f "/etc/clamav/clamd.conf" ]; then
CLAMD_CONF="/etc/clamav/clamd.conf"
else
echo "未找到 freshclam 配置文件,请手动配置"
exit 1
fi
echo "配置 clamd $CLAMD_CONF..."
# 备份原始配置文件
cp "$CLAMD_CONF" "$CLAMD_CONF.bak"
# 修改配置文件
sed -i 's|^#LogFile .*|LogFile /var/log/clamd.scan|' "$CLAMD_CONF"
sed -i 's|^#LogFileMaxSize .*|LogFileMaxSize 2M|' "$CLAMD_CONF"
sed -i 's|^#PidFile .*|PidFile /run/clamd.scan/clamd.pid|' "$CLAMD_CONF"
sed -i 's|^#DatabaseDirectory .*|DatabaseDirectory /var/lib/clamav|' "$CLAMD_CONF"
sed -i 's|^#LocalSocket .*|LocalSocket /run/clamd.scan/clamd.sock|' "$CLAMD_CONF"
else
echo "未找到 clamd 配置文件,请手动配置"
exit 1
fi
sed -i 's|^LogFileMaxSize .*|LogFileMaxSize 2M|' "$CLAMD_CONF"
sed -i 's|^PidFile .*|PidFile /run/clamd.scan/clamd.pid|' "$CLAMD_CONF"
sed -i 's|^DatabaseDirectory .*|DatabaseDirectory /var/lib/clamav|' "$CLAMD_CONF"
sed -i 's|^LocalSocket .*|LocalSocket /run/clamd.scan/clamd.sock|' "$CLAMD_CONF"
}
# 配置 freshclam
FRESHCLAM_CONF="/etc/freshclam.conf"
if [ -f "$FRESHCLAM_CONF" ]; then
echo "配置 freshclam..."
configure_freshclam() {
FRESHCLAM_CONF=""
if [ -f "/etc/freshclam.conf" ]; then
FRESHCLAM_CONF="/etc/freshclam.conf"
elif [ -f "/etc/clamav/freshclam.conf" ]; then
FRESHCLAM_CONF="/etc/clamav/freshclam.conf"
else
echo "未找到 freshclam 配置文件,请手动配置"
exit 1
fi
echo "freshclam.con $FRESHCLAM_CONF..."
# 备份原始配置文件
cp "$FRESHCLAM_CONF" "$FRESHCLAM_CONF.bak"
# 修改配置文件
sed -i 's|^#DatabaseDirectory .*|DatabaseDirectory /var/lib/clamav|' "$FRESHCLAM_CONF"
sed -i 's|^#UpdateLogFile .*|UpdateLogFile /var/log/freshclam.log|' "$FRESHCLAM_CONF"
sed -i 's|^#PidFile .*|PidFile /var/run/freshclam.pid|' "$FRESHCLAM_CONF"
sed -i 's|^#DatabaseMirror .*|DatabaseMirror database.clamav.net|' "$FRESHCLAM_CONF"
sed -i 's|^#Checks .*|Checks 12|' "$FRESHCLAM_CONF"
else
echo "未找到 freshclam 配置文件,请手动配置"
exit 1
fi
sed -i 's|^DatabaseDirectory .*|DatabaseDirectory /var/lib/clamav|' "$FRESHCLAM_CONF"
sed -i 's|^PidFile .*|PidFile /var/run/freshclam.pid|' "$FRESHCLAM_CONF"
sed -i 's/DatabaseMirror db.local.clamav.net/DatabaseMirror database.clamav.net/' "$FRESHCLAM_CONF"
sed -i 's|^Checks .*|Checks 12|' "$FRESHCLAM_CONF"
}
# 创建必要的目录和文件
echo "创建必要的目录和文件..."
mkdir -p /run/clamd.scan
chown clamav:clamav /run/clamd.scan
mkdir -p /var/log/clamav
chown clamav:clamav /var/log/clamav
touch /var/log/clamd.scan /var/log/freshclam.log
chown clamav:clamav /var/log/clamd.scan /var/log/freshclam.log
# 设置开机自启动并启动服务
if command -v systemctl &> /dev/null; then
echo "设置 ClamAV 开机自启动..."
systemctl enable clamav-daemon
systemctl enable clamav-freshclam
echo "启动 ClamAV 服务..."
# 服务管理
setup_service() {
case $OS in
ubuntu|debian)
systemctl stop clamav-freshclam
systemctl start clamav-daemon
systemctl enable clamav-daemon
systemctl start clamav-freshclam
if systemctl is-active --quiet clamav-daemon && systemctl is-active --quiet clamav-freshclam; then
echo "ClamAV 已成功安装并启动"
systemctl enable clamav-freshclam
;;
centos|rhel|rocky|almalinux)
if [[ $OS_VER == 7* ]]; then
systemctl stop freshclam
systemctl start clamd@scan
systemctl enable clamd@scan
systemctl start freshclam
systemctl enable freshclam
else
echo "ClamAV 启动失败,请检查日志"
exit 1
systemctl stop clamav-freshclam
systemctl start clamd@scan
systemctl enable clamd@scan
systemctl start clamav-freshclam
systemctl enable clamav-freshclam
fi
else
echo "systemctl 不可用,请手动启动 ClamAV"
exit 1
fi
;;
esac
}
# 更新病毒数据库
echo "更新 ClamAV 病毒数据库..."
freshclam
# 主执行流程
echo "正在安装 ClamAV..."
install_clamav
# 检查 ClamAV 是否正常运行
if clamscan --version &> /dev/null; then
echo "ClamAV 安装完成并正常运行!"
else
echo "ClamAV 安装或配置出现问题,请检查日志"
exit 1
fi
echo -e "\n\n配置 clamd..."
configure_clamd
exit 0`
echo -e "\n\n配置 freshclam..."
configure_freshclam
echo -e "\n\n设置服务..."
setup_service
echo -e "\n\n安装完成"
echo 0`
}
func loadUninstallClamAV() string {
return `#!/bin/bash

View file

@ -207,30 +207,29 @@ func Routers() *gin.Engine {
swaggerRouter := Router.Group("1panel")
docs.SwaggerInfo.BasePath = "/api/v2"
swaggerRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()).GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
swaggerRouter.Use(middleware.SessionAuth()).GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
PublicGroup := Router.Group("")
{
PublicGroup.Use(gzip.Gzip(gzip.DefaultCompression))
setWebStatic(PublicGroup)
}
Router.Use(middleware.OperationLog())
Router.Use(middleware.PasswordExpired())
if global.CONF.Base.IsDemo {
Router.Use(middleware.DemoHandle())
}
Router.Use(middleware.OperationLog())
Router.Use(middleware.GlobalLoading())
Router.Use(middleware.PasswordExpired())
Router.Use(middleware.WhiteAllow())
Router.Use(middleware.BindDomain())
PrivateGroup := Router.Group("/api/v2/core")
PrivateGroup.Use(middleware.WhiteAllow())
PrivateGroup.Use(middleware.BindDomain())
PrivateGroup.Use(middleware.SetPasswordPublicKey())
for _, router := range rou.RouterGroupApp {
router.InitRouter(PrivateGroup)
}
Router.Use(middleware.JwtAuth())
Router.Use(middleware.SessionAuth())
Router.Use(middleware.GlobalLoading())
Router.Use(Proxy())
Router.NoRoute(func(c *gin.Context) {
if !checkBindDomain(c) {

View file

@ -1,50 +0,0 @@
package middleware
import (
"fmt"
"strings"
"github.com/1Panel-dev/1Panel/core/app/api/v2/helper"
"github.com/1Panel-dev/1Panel/core/constant"
jwtUtils "github.com/1Panel-dev/1Panel/core/utils/jwt"
"github.com/gin-gonic/gin"
)
func JwtAuth() gin.HandlerFunc {
return func(c *gin.Context) {
if strings.HasPrefix(c.Request.URL.Path, "/api/v2/core/auth") {
c.Next()
return
}
token := c.Request.Header.Get(constant.JWTHeaderName)
if token == "" {
c.Next()
return
}
j := jwtUtils.NewJWT()
claims, err := j.ParseToken(token)
if err != nil {
helper.BadAuth(c, "ErrInternalServer", err)
return
}
if claims.BaseClaims.IsAgent {
if strings.HasPrefix(c.Request.URL.Path, "/api/v2/agent/") {
c.Set("claims", claims)
c.Set("authMethod", constant.AuthMethodJWT)
c.Next()
return
} else {
helper.BadAuth(c, "ErrInternalServer", fmt.Errorf("err token from request"))
return
}
}
if strings.HasPrefix(c.Request.URL.Path, "/api/v2/agent/") {
helper.BadAuth(c, "ErrInternalServer", fmt.Errorf("err token from request"))
return
}
c.Set("claims", claims)
c.Set("authMethod", constant.AuthMethodJWT)
c.Next()
}
}

View file

@ -22,10 +22,6 @@ func SessionAuth() gin.HandlerFunc {
c.Next()
return
}
if method, exist := c.Get("authMethod"); exist && method == constant.AuthMethodJWT {
c.Next()
return
}
panelToken := c.GetHeader("1Panel-Token")
panelTimestamp := c.GetHeader("1Panel-Timestamp")

View file

@ -10,7 +10,6 @@ type AppLauncherRouter struct{}
func (s *AppLauncherRouter) InitRouter(Router *gin.RouterGroup) {
launcherRouter := Router.Group("launcher").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())
baseApi := v2.ApiGroupApp.BaseApi

View file

@ -10,7 +10,6 @@ type CommandRouter struct{}
func (s *CommandRouter) InitRouter(Router *gin.RouterGroup) {
commandRouter := Router.Group("commands").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())
baseApi := v2.ApiGroupApp.BaseApi

View file

@ -10,7 +10,6 @@ type BackupRouter struct{}
func (s *BackupRouter) InitRouter(Router *gin.RouterGroup) {
backupRouter := Router.Group("backups").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())
baseApi := v2.ApiGroupApp.BaseApi

View file

@ -11,7 +11,6 @@ type GroupRouter struct {
func (a *GroupRouter) InitRouter(Router *gin.RouterGroup) {
groupRouter := Router.Group("groups").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())

View file

@ -10,7 +10,6 @@ type HostRouter struct{}
func (s *HostRouter) InitRouter(Router *gin.RouterGroup) {
hostRouter := Router.Group("hosts").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())
baseApi := v2.ApiGroupApp.BaseApi

View file

@ -11,7 +11,6 @@ type LogRouter struct{}
func (s *LogRouter) InitRouter(Router *gin.RouterGroup) {
operationRouter := Router.Group("logs").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())
baseApi := v2.ApiGroupApp.BaseApi

View file

@ -10,7 +10,6 @@ type ScriptRouter struct{}
func (s *ScriptRouter) InitRouter(Router *gin.RouterGroup) {
scriptRouter := Router.Group("script").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())
baseApi := v2.ApiGroupApp.BaseApi

View file

@ -10,10 +10,8 @@ type SettingRouter struct{}
func (s *SettingRouter) InitRouter(Router *gin.RouterGroup) {
router := Router.Group("settings").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth())
settingRouter := Router.Group("settings").
Use(middleware.JwtAuth()).
Use(middleware.SessionAuth()).
Use(middleware.PasswordExpired())

View file

@ -1,65 +0,0 @@
package jwt
import (
"time"
"github.com/1Panel-dev/1Panel/core/app/repo"
"github.com/1Panel-dev/1Panel/core/buserr"
"github.com/1Panel-dev/1Panel/core/constant"
"github.com/golang-jwt/jwt/v4"
)
type JWT struct {
SigningKey []byte
}
type CustomClaims struct {
BaseClaims
BufferTime int64
jwt.RegisteredClaims
}
type BaseClaims struct {
ID uint
Name string
IsAgent bool
}
func NewJWT() *JWT {
settingRepo := repo.NewISettingRepo()
jwtSign, _ := settingRepo.Get(repo.WithByKey("JWTSigningKey"))
return &JWT{
[]byte(jwtSign.Value),
}
}
func (j *JWT) CreateClaims(baseClaims BaseClaims) CustomClaims {
claims := CustomClaims{
BaseClaims: baseClaims,
BufferTime: constant.JWTBufferTime,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Second * time.Duration(constant.JWTBufferTime))),
Issuer: constant.JWTIssuer,
},
}
return claims
}
func (j *JWT) CreateToken(request CustomClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, &request)
return token.SignedString(j.SigningKey)
}
func (j *JWT) ParseToken(tokenStr string) (*CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenStr, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return j.SigningKey, nil
})
if err != nil || token == nil {
return nil, buserr.WithDetail("ErrTokenParse", "", err)
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, buserr.New("ErrTokenParse")
}

View file

@ -42,7 +42,7 @@ export const scan = () => {
return http.post<Toolbox.CleanData>(`/toolbox/scan`, {});
};
export const clean = (param: any) => {
return http.post(`/toolbox/clean`, param);
return http.post(`/toolbox/clean`, param, TimeoutEnum.T_5M);
};
// fail2ban

View file

@ -37,8 +37,7 @@ const initLog = async () => {
if (editorRef.value && scrollerElement.value == undefined) {
const parentElement = editorRef.value.$el as HTMLElement;
scrollerElement.value = parentElement.querySelector('.hljs') as HTMLElement;
scrollerElement.value.style['min-height'] = '100px';
scrollerElement.value.style['max-height'] = 'calc(100vh - ' + props.heightDiff + 'px)';
scrollerElement.value.style['height'] = 'calc(100vh - ' + props.heightDiff + 'px)';
}
};

View file

@ -78,8 +78,8 @@ const onUpgrade = async () => {
cancelButtonText: i18n.global.t('commons.button.cancel'),
type: 'info',
}).then(async () => {
globalStore.isLoading = true;
await upgrade(upgradeVersion.value);
globalStore.isLoading = true;
globalStore.isOnRestart = true;
drawerVisible.value = false;
MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));

View file

@ -1,5 +1,5 @@
<template>
<div tabindex="0">
<div>
<el-tabs
type="card"
class="terminal-tabs"
@ -168,7 +168,6 @@ const toggleFullscreen = () => {
if (screenfull.isEnabled) {
screenfull.toggle();
}
globalStore.isFullScreen = !screenfull.isFullscreen;
};
const loadTooltip = () => {
return i18n.global.t('commons.button.' + (globalStore.isFullScreen ? 'quitFullscreen' : 'fullscreen'));
@ -403,16 +402,25 @@ function syncTerminal() {
}
}
const changeFullScreen = () => {
globalStore.isFullScreen = screenfull.isFullscreen;
};
defineExpose({
acceptParams,
cleanTimer,
});
onBeforeUnmount(() => {
document.removeEventListener('fullscreenchange', changeFullScreen);
});
onMounted(() => {
if (router.currentRoute.value.query.path) {
const path = String(router.currentRoute.value.query.path);
initCmd.value = `cd "${path}" \n`;
}
document.addEventListener('fullscreenchange', changeFullScreen);
});
</script>

View file

@ -138,7 +138,7 @@
<el-option :value="500" :label="500" />
<el-option :value="1000" :label="1000" />
</el-select>
<HighlightLog :modelValue="logContent" />
<HighlightLog :modelValue="logContent" :heightDiff="533" />
</el-row>
</el-form>
</el-col>

View file

@ -643,6 +643,10 @@ function load18n(label: string) {
case 'System':
case 'Website':
return i18n.global.t('menu.' + label.toLowerCase());
case 'Compose':
return i18n.global.t('container.compose');
case 'CustomAppstore':
return i18n.global.t('xpack.customApp.name');
case 'RuntimeExtension':
return i18n.global.t('website.runtime');
case 'Image':