精简: 去掉双重验证(2FA): 登录校验/设置守卫/VerifyTwoFactorCode/CLI resetTwoFactor 标志
This commit is contained in:
@@ -17,9 +17,8 @@ import (
|
|||||||
|
|
||||||
// LoginForm represents the login request structure.
|
// LoginForm represents the login request structure.
|
||||||
type LoginForm struct {
|
type LoginForm struct {
|
||||||
Username string `json:"username" form:"username"`
|
Username string `json:"username" form:"username"`
|
||||||
Password string `json:"password" form:"password"`
|
Password string `json:"password" form:"password"`
|
||||||
TwoFactorCode string `json:"twoFactorCode" form:"twoFactorCode"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexController handles the main index and login-related routes.
|
// IndexController handles the main index and login-related routes.
|
||||||
@@ -38,14 +37,13 @@ func NewIndexController(g *gin.RouterGroup) *IndexController {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
// initRouter sets up the routes for index, login, logout, and two-factor authentication.
|
// initRouter sets up the routes for index, login, and logout.
|
||||||
func (a *IndexController) initRouter(g *gin.RouterGroup) {
|
func (a *IndexController) initRouter(g *gin.RouterGroup) {
|
||||||
g.GET("/", a.index)
|
g.GET("/", a.index)
|
||||||
g.GET("/csrf-token", a.csrfToken)
|
g.GET("/csrf-token", a.csrfToken)
|
||||||
|
|
||||||
g.POST("/login", middleware.CSRFMiddleware(), a.login)
|
g.POST("/login", middleware.CSRFMiddleware(), a.login)
|
||||||
g.POST("/logout", middleware.CSRFMiddleware(), a.logout)
|
g.POST("/logout", middleware.CSRFMiddleware(), a.logout)
|
||||||
g.POST("/getTwoFactorEnable", middleware.CSRFMiddleware(), a.getTwoFactorEnable)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// index handles the root route, redirecting logged-in users to the panel or showing the login page.
|
// index handles the root route, redirecting logged-in users to the panel or showing the login page.
|
||||||
@@ -92,7 +90,7 @@ func (a *IndexController) login(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user, checkErr := a.userService.CheckUser(form.Username, form.Password, form.TwoFactorCode)
|
user, checkErr := a.userService.CheckUser(form.Username, form.Password)
|
||||||
|
|
||||||
if user == nil {
|
if user == nil {
|
||||||
reason := loginFailureReason(checkErr)
|
reason := loginFailureReason(checkErr)
|
||||||
@@ -159,9 +157,3 @@ func (a *IndexController) csrfToken(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"success": true, "obj": token})
|
c.JSON(http.StatusOK, gin.H{"success": true, "obj": token})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTwoFactorEnable retrieves the current status of two-factor authentication.
|
|
||||||
func (a *IndexController) getTwoFactorEnable(c *gin.Context) {
|
|
||||||
status, err := a.settingService.GetTwoFactorEnable()
|
|
||||||
jsonObj(c, status, err)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
||||||
@@ -21,22 +20,20 @@ import (
|
|||||||
|
|
||||||
// updateUserForm represents the form for updating user credentials.
|
// updateUserForm represents the form for updating user credentials.
|
||||||
type updateUserForm struct {
|
type updateUserForm struct {
|
||||||
OldUsername string `json:"oldUsername" form:"oldUsername"`
|
OldUsername string `json:"oldUsername" form:"oldUsername"`
|
||||||
OldPassword string `json:"oldPassword" form:"oldPassword"`
|
OldPassword string `json:"oldPassword" form:"oldPassword"`
|
||||||
NewUsername string `json:"newUsername" form:"newUsername"`
|
NewUsername string `json:"newUsername" form:"newUsername"`
|
||||||
NewPassword string `json:"newPassword" form:"newPassword"`
|
NewPassword string `json:"newPassword" form:"newPassword"`
|
||||||
TwoFactorCode string `json:"twoFactorCode" form:"twoFactorCode"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSettingForm carries the persisted settings plus request-scoped fields
|
// updateSettingForm carries the persisted settings plus the explicit clear
|
||||||
// that must never land in the settings table: the 2FA confirmation code and
|
// flags for redacted secrets, which must never land in the settings table (a
|
||||||
// the explicit clear flags for redacted secrets (a blank secret alone means
|
// blank secret alone means "unchanged", so clearing needs its own signal —
|
||||||
// "unchanged", so clearing needs its own signal — see #5724).
|
// see #5724).
|
||||||
type updateSettingForm struct {
|
type updateSettingForm struct {
|
||||||
entity.AllSetting
|
entity.AllSetting
|
||||||
TwoFactorCode string `json:"twoFactorCode" form:"twoFactorCode"`
|
ClearTgBotToken bool `json:"clearTgBotToken" form:"clearTgBotToken"`
|
||||||
ClearTgBotToken bool `json:"clearTgBotToken" form:"clearTgBotToken"`
|
ClearSmtpPassword bool `json:"clearSmtpPassword" form:"clearSmtpPassword"`
|
||||||
ClearSmtpPassword bool `json:"clearSmtpPassword" form:"clearSmtpPassword"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type validateRegexForm struct {
|
type validateRegexForm struct {
|
||||||
@@ -124,33 +121,15 @@ func (a *SettingController) updateSetting(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
allSetting := &form.AllSetting
|
allSetting := &form.AllSetting
|
||||||
oldTwoFactor, twoFactorErr := a.settingService.GetTwoFactorEnable()
|
|
||||||
oldPanelOutbound, _ := a.settingService.GetPanelOutbound()
|
oldPanelOutbound, _ := a.settingService.GetPanelOutbound()
|
||||||
oldTgEnable, _ := a.settingService.GetTgbotEnabled()
|
oldTgEnable, _ := a.settingService.GetTgbotEnabled()
|
||||||
oldTgToken, _ := a.settingService.GetTgBotToken()
|
oldTgToken, _ := a.settingService.GetTgBotToken()
|
||||||
oldTgChatId, _ := a.settingService.GetTgBotChatId()
|
oldTgChatId, _ := a.settingService.GetTgBotChatId()
|
||||||
oldTgAPIServer, _ := a.settingService.GetTgBotAPIServer()
|
oldTgAPIServer, _ := a.settingService.GetTgBotAPIServer()
|
||||||
if twoFactorErr == nil && oldTwoFactor {
|
|
||||||
// Rebinding the authenticator is the same class of change as turning 2FA
|
|
||||||
// off, so both need a current code. Blank still means "unchanged".
|
|
||||||
submittedToken := strings.TrimSpace(allSetting.TwoFactorToken)
|
|
||||||
storedToken, _ := a.settingService.GetTwoFactorToken()
|
|
||||||
if !allSetting.TwoFactorEnable || (submittedToken != "" && submittedToken != storedToken) {
|
|
||||||
if err := a.settingService.VerifyTwoFactorCode(form.TwoFactorCode); err != nil {
|
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := a.settingService.UpdateAllSetting(allSetting, service.SecretClears{
|
err := a.settingService.UpdateAllSetting(allSetting, service.SecretClears{
|
||||||
TgBotToken: form.ClearTgBotToken,
|
TgBotToken: form.ClearTgBotToken,
|
||||||
SmtpPassword: form.ClearSmtpPassword,
|
SmtpPassword: form.ClearSmtpPassword,
|
||||||
})
|
})
|
||||||
if err == nil && twoFactorErr == nil && !oldTwoFactor && allSetting.TwoFactorEnable {
|
|
||||||
if bumpErr := a.userService.BumpLoginEpoch(); bumpErr != nil {
|
|
||||||
err = bumpErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err == nil && form.PanelOutbound != oldPanelOutbound {
|
if err == nil && form.PanelOutbound != oldPanelOutbound {
|
||||||
// The egress bridge lives in the generated config; reconcile the
|
// The egress bridge lives in the generated config; reconcile the
|
||||||
// running core. One SOCKS inbound plus one routing rule — both
|
// running core. One SOCKS inbound plus one routing rule — both
|
||||||
@@ -189,10 +168,6 @@ func (a *SettingController) updateUser(c *gin.Context) {
|
|||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUserError"), errors.New(I18nWeb(c, "pages.settings.toasts.userPassMustBeNotEmpty")))
|
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUserError"), errors.New(I18nWeb(c, "pages.settings.toasts.userPassMustBeNotEmpty")))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := a.settingService.VerifyTwoFactorCode(form.TwoFactorCode); err != nil {
|
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUserError"), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = a.userService.UpdateUser(user.Id, form.NewUsername, form.NewPassword)
|
err = a.userService.UpdateUser(user.Id, form.NewUsername, form.NewPassword)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user.Username = form.NewUsername
|
user.Username = form.NewUsername
|
||||||
|
|||||||
@@ -64,9 +64,7 @@ type AllSetting struct {
|
|||||||
|
|
||||||
OutboundDownThreshold int `json:"outboundDownThreshold" form:"outboundDownThreshold" validate:"gte=1,lte=100"`
|
OutboundDownThreshold int `json:"outboundDownThreshold" form:"outboundDownThreshold" validate:"gte=1,lte=100"`
|
||||||
|
|
||||||
TimeLocation string `json:"timeLocation" form:"timeLocation"`
|
TimeLocation string `json:"timeLocation" form:"timeLocation"`
|
||||||
TwoFactorEnable bool `json:"twoFactorEnable" form:"twoFactorEnable"`
|
|
||||||
TwoFactorToken string `json:"twoFactorToken" form:"twoFactorToken"`
|
|
||||||
|
|
||||||
SubEnable bool `json:"subEnable" form:"subEnable"`
|
SubEnable bool `json:"subEnable" form:"subEnable"`
|
||||||
SubJsonEnable bool `json:"subJsonEnable" form:"subJsonEnable"`
|
SubJsonEnable bool `json:"subJsonEnable" form:"subJsonEnable"`
|
||||||
@@ -113,12 +111,11 @@ type AllSetting struct {
|
|||||||
type AllSettingView struct {
|
type AllSettingView struct {
|
||||||
AllSetting
|
AllSetting
|
||||||
|
|
||||||
HasTgBotToken bool `json:"hasTgBotToken"`
|
HasTgBotToken bool `json:"hasTgBotToken"`
|
||||||
HasTwoFactorToken bool `json:"hasTwoFactorToken"`
|
HasApiToken bool `json:"hasApiToken"`
|
||||||
HasApiToken bool `json:"hasApiToken"`
|
HasWarpSecret bool `json:"hasWarpSecret"`
|
||||||
HasWarpSecret bool `json:"hasWarpSecret"`
|
HasNordSecret bool `json:"hasNordSecret"`
|
||||||
HasNordSecret bool `json:"hasNordSecret"`
|
HasSmtpPassword bool `json:"hasSmtpPassword"`
|
||||||
HasSmtpPassword bool `json:"hasSmtpPassword"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func pathHasForbiddenChar(s string) bool {
|
func pathHasForbiddenChar(s string) bool {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package panel
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/xlzd/gotp"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/database"
|
"github.com/mhsanaei/3x-ui/v3/internal/database"
|
||||||
@@ -34,7 +33,7 @@ func (s *UserService) GetFirstUser() (*model.User, error) {
|
|||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *UserService) CheckUser(username string, password string, twoFactorCode string) (*model.User, error) {
|
func (s *UserService) CheckUser(username string, password string) (*model.User, error) {
|
||||||
db := database.GetDB()
|
db := database.GetDB()
|
||||||
|
|
||||||
user := &model.User{}
|
user := &model.User{}
|
||||||
@@ -54,24 +53,6 @@ func (s *UserService) CheckUser(username string, password string, twoFactorCode
|
|||||||
return nil, errors.New("invalid credentials")
|
return nil, errors.New("invalid credentials")
|
||||||
}
|
}
|
||||||
|
|
||||||
twoFactorEnable, err := s.settingService.GetTwoFactorEnable()
|
|
||||||
if err != nil {
|
|
||||||
logger.Warning("check two factor err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if twoFactorEnable {
|
|
||||||
twoFactorToken, err := s.settingService.GetTwoFactorToken()
|
|
||||||
if err != nil {
|
|
||||||
logger.Warning("check two factor token err:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if gotp.NewDefaultTOTP(twoFactorToken).Now() != twoFactorCode {
|
|
||||||
return nil, errors.New("invalid 2fa code")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,16 +71,6 @@ func (s *UserService) UpdateUser(id int, username string, password string) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
twoFactorEnable, err := s.settingService.GetTwoFactorEnable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if twoFactorEnable {
|
|
||||||
_ = s.settingService.SetTwoFactorEnable(false)
|
|
||||||
_ = s.settingService.SetTwoFactorToken("")
|
|
||||||
}
|
|
||||||
|
|
||||||
return db.Model(model.User{}).
|
return db.Model(model.User{}).
|
||||||
Where("id = ?", id).
|
Where("id = ?", id).
|
||||||
Updates(map[string]any{
|
Updates(map[string]any{
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/xlzd/gotp"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/config"
|
"github.com/mhsanaei/3x-ui/v3/internal/config"
|
||||||
@@ -81,8 +80,6 @@ var defaultValueMap = map[string]string{
|
|||||||
"tgCpu": "80",
|
"tgCpu": "80",
|
||||||
"tgMemory": "80",
|
"tgMemory": "80",
|
||||||
"tgLang": "en-US",
|
"tgLang": "en-US",
|
||||||
"twoFactorEnable": "false",
|
|
||||||
"twoFactorToken": "",
|
|
||||||
"subEnable": "true",
|
"subEnable": "true",
|
||||||
"subJsonEnable": "false",
|
"subJsonEnable": "false",
|
||||||
"subJsonAutoDetect": "false",
|
"subJsonAutoDetect": "false",
|
||||||
@@ -246,7 +243,6 @@ func (s *SettingService) GetAllSettingView() (*entity.AllSettingView, error) {
|
|||||||
}
|
}
|
||||||
view := &entity.AllSettingView{AllSetting: *allSetting}
|
view := &entity.AllSettingView{AllSetting: *allSetting}
|
||||||
view.HasTgBotToken = secretConfigured(allSetting.TgBotToken)
|
view.HasTgBotToken = secretConfigured(allSetting.TgBotToken)
|
||||||
view.HasTwoFactorToken = secretConfigured(allSetting.TwoFactorToken)
|
|
||||||
view.HasWarpSecret = secretConfigured(mustString(s.GetWarp()))
|
view.HasWarpSecret = secretConfigured(mustString(s.GetWarp()))
|
||||||
view.HasNordSecret = secretConfigured(mustString(s.GetNord()))
|
view.HasNordSecret = secretConfigured(mustString(s.GetNord()))
|
||||||
view.HasSmtpPassword = secretConfigured(allSetting.SmtpPassword)
|
view.HasSmtpPassword = secretConfigured(allSetting.SmtpPassword)
|
||||||
@@ -255,7 +251,6 @@ func (s *SettingService) GetAllSettingView() (*entity.AllSettingView, error) {
|
|||||||
view.HasApiToken = apiTokenCount > 0
|
view.HasApiToken = apiTokenCount > 0
|
||||||
}
|
}
|
||||||
view.TgBotToken = ""
|
view.TgBotToken = ""
|
||||||
view.TwoFactorToken = ""
|
|
||||||
view.SmtpPassword = ""
|
view.SmtpPassword = ""
|
||||||
return view, nil
|
return view, nil
|
||||||
}
|
}
|
||||||
@@ -556,40 +551,6 @@ func (s *SettingService) GetTgLang() (string, error) {
|
|||||||
return s.getString("tgLang")
|
return s.getString("tgLang")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SettingService) GetTwoFactorEnable() (bool, error) {
|
|
||||||
return s.getBool("twoFactorEnable")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) SetTwoFactorEnable(value bool) error {
|
|
||||||
return s.setBool("twoFactorEnable", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) GetTwoFactorToken() (string, error) {
|
|
||||||
return s.getString("twoFactorToken")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) SetTwoFactorToken(value string) error {
|
|
||||||
return s.setString("twoFactorToken", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) VerifyTwoFactorCode(code string) error {
|
|
||||||
enabled, err := s.GetTwoFactorEnable()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !enabled {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
token, err := s.GetTwoFactorToken()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if strings.TrimSpace(token) == "" || !gotp.NewDefaultTOTP(token).Verify(strings.TrimSpace(code), time.Now().Unix()) {
|
|
||||||
return common.NewError("invalid two factor code")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) GetPort() (int, error) {
|
func (s *SettingService) GetPort() (int, error) {
|
||||||
return s.getInt("webPort")
|
return s.getInt("webPort")
|
||||||
}
|
}
|
||||||
@@ -1167,13 +1128,6 @@ func (s *SettingService) preserveRedactedSecrets(allSetting *entity.AllSetting,
|
|||||||
}
|
}
|
||||||
allSetting.TgBotToken = value
|
allSetting.TgBotToken = value
|
||||||
}
|
}
|
||||||
if allSetting.TwoFactorEnable && strings.TrimSpace(allSetting.TwoFactorToken) == "" {
|
|
||||||
value, err := s.GetTwoFactorToken()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
allSetting.TwoFactorToken = value
|
|
||||||
}
|
|
||||||
if !clears.SmtpPassword && strings.TrimSpace(allSetting.SmtpPassword) == "" {
|
if !clears.SmtpPassword && strings.TrimSpace(allSetting.SmtpPassword) == "" {
|
||||||
value, err := s.GetSmtpPassword()
|
value, err := s.GetSmtpPassword()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1223,7 +1177,7 @@ func validateRemoteRoutingURLSetting(name string, value *string) error {
|
|||||||
|
|
||||||
func (s *SettingService) UpdateSecret(key string, value string) error {
|
func (s *SettingService) UpdateSecret(key string, value string) error {
|
||||||
switch key {
|
switch key {
|
||||||
case "tgBotToken", "twoFactorToken":
|
case "tgBotToken":
|
||||||
return s.saveSetting(key, strings.TrimSpace(value))
|
return s.saveSetting(key, strings.TrimSpace(value))
|
||||||
default:
|
default:
|
||||||
return common.NewError("secret key is not replaceable:", key)
|
return common.NewError("secret key is not replaceable:", key)
|
||||||
@@ -1356,9 +1310,8 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var factoryDefaultSecretKeys = map[string]bool{
|
var factoryDefaultSecretKeys = map[string]bool{
|
||||||
"tgBotToken": true,
|
"tgBotToken": true,
|
||||||
"twoFactorToken": true,
|
"smtpPassword": true,
|
||||||
"smtpPassword": true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
_ "unsafe"
|
_ "unsafe"
|
||||||
|
|
||||||
|
"github.com/mhsanaei/3x-ui/v3/internal/agent"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/config"
|
"github.com/mhsanaei/3x-ui/v3/internal/config"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/crypto/nodetoken"
|
"github.com/mhsanaei/3x-ui/v3/internal/crypto/nodetoken"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/database"
|
"github.com/mhsanaei/3x-ui/v3/internal/database"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
"github.com/mhsanaei/3x-ui/v3/internal/logger"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/agent"
|
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/sub"
|
"github.com/mhsanaei/3x-ui/v3/internal/sub"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/tunnelmonitor"
|
"github.com/mhsanaei/3x-ui/v3/internal/tunnelmonitor"
|
||||||
"github.com/mhsanaei/3x-ui/v3/internal/util/crypto"
|
"github.com/mhsanaei/3x-ui/v3/internal/util/crypto"
|
||||||
@@ -396,8 +396,8 @@ func encryptNodeTokens() {
|
|||||||
fmt.Printf("node-token migration complete: %d re-encrypted, %d already current/skipped\n", changed, skipped)
|
fmt.Printf("node-token migration complete: %d re-encrypted, %d already current/skipped\n", changed, skipped)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateSetting updates various panel settings including port, credentials, base path, listen IP, and two-factor authentication.
|
// updateSetting updates various panel settings including port, credentials, base path, and listen IP.
|
||||||
func updateSetting(port int, username string, password string, webBasePath string, listenIP string, resetTwoFactor bool) error {
|
func updateSetting(port int, username string, password string, webBasePath string, listenIP string) error {
|
||||||
err := database.InitDB(config.GetDBPath())
|
err := database.InitDB(config.GetDBPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Database initialization failed:", err)
|
fmt.Println("Database initialization failed:", err)
|
||||||
@@ -434,17 +434,6 @@ func updateSetting(port int, username string, password string, webBasePath strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if resetTwoFactor {
|
|
||||||
err := settingService.SetTwoFactorEnable(false)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Failed to reset two-factor authentication:", err)
|
|
||||||
} else {
|
|
||||||
_ = settingService.SetTwoFactorToken("")
|
|
||||||
fmt.Println("Two-factor authentication reset successfully")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if listenIP != "" {
|
if listenIP != "" {
|
||||||
err := settingService.SetListen(listenIP)
|
err := settingService.SetListen(listenIP)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -644,7 +633,6 @@ func main() {
|
|||||||
var show bool
|
var show bool
|
||||||
var getCert bool
|
var getCert bool
|
||||||
var getApiToken bool
|
var getApiToken bool
|
||||||
var resetTwoFactor bool
|
|
||||||
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
|
settingCmd.BoolVar(&reset, "reset", false, "Reset all settings")
|
||||||
settingCmd.BoolVar(&show, "show", false, "Display current settings")
|
settingCmd.BoolVar(&show, "show", false, "Display current settings")
|
||||||
settingCmd.IntVar(&port, "port", 0, "Set panel port number")
|
settingCmd.IntVar(&port, "port", 0, "Set panel port number")
|
||||||
@@ -652,7 +640,6 @@ func main() {
|
|||||||
settingCmd.StringVar(&password, "password", "", "Set login password")
|
settingCmd.StringVar(&password, "password", "", "Set login password")
|
||||||
settingCmd.StringVar(&webBasePath, "webBasePath", "", "Set base path for Panel")
|
settingCmd.StringVar(&webBasePath, "webBasePath", "", "Set base path for Panel")
|
||||||
settingCmd.StringVar(&listenIP, "listenIP", "", "set panel listenIP IP")
|
settingCmd.StringVar(&listenIP, "listenIP", "", "set panel listenIP IP")
|
||||||
settingCmd.BoolVar(&resetTwoFactor, "resetTwoFactor", false, "Reset two-factor authentication settings")
|
|
||||||
settingCmd.BoolVar(&getListen, "getListen", false, "Display current panel listenIP IP")
|
settingCmd.BoolVar(&getListen, "getListen", false, "Display current panel listenIP IP")
|
||||||
settingCmd.BoolVar(&getCert, "getCert", false, "Display current certificate settings")
|
settingCmd.BoolVar(&getCert, "getCert", false, "Display current certificate settings")
|
||||||
settingCmd.BoolVar(&getApiToken, "getApiToken", false, "Display current API token")
|
settingCmd.BoolVar(&getApiToken, "getApiToken", false, "Display current API token")
|
||||||
@@ -734,7 +721,7 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err = updateSetting(port, username, password, webBasePath, listenIP, resetTwoFactor); err != nil {
|
if err = updateSetting(port, username, password, webBasePath, listenIP); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user