mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-10-27 10:30:08 +00:00
Compare commits
No commits in common. "254e5a6761e1ad600556956973be7c2b7c35c211" and "fb9839cb3d53a1a9649f4c29b45fde4e49d3a407" have entirely different histories.
254e5a6761
...
fb9839cb3d
27 changed files with 147 additions and 463 deletions
|
|
@ -1,11 +1,5 @@
|
||||||
# API 文档
|
# API 文档
|
||||||
|
|
||||||
要向 REST API v2 发送请求,您需要在每个请求中包含带有 Bearer 类型的 Authorization 头和令牌。
|
|
||||||
|
|
||||||
```
|
|
||||||
Authorization: Bearer {token}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Inbounds
|
## Inbounds
|
||||||
|
|
||||||
### 获取所有 Inbounds
|
### 获取所有 Inbounds
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
# API Documentation
|
# API Documentation
|
||||||
|
|
||||||
To make requests to REST API v2, you need to include the Authorization header with the Bearer type and the token in each request.
|
|
||||||
|
|
||||||
```
|
|
||||||
Authorization: Bearer {token}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Inbounds
|
## Inbounds
|
||||||
|
|
||||||
### Get All Inbounds
|
### Get All Inbounds
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
# Documentación de la API
|
# Documentación de la API
|
||||||
|
|
||||||
Para realizar solicitudes al REST API v2, es necesario incluir en cada solicitud el encabezado Authorization con el tipo Bearer y el token.
|
|
||||||
|
|
||||||
```
|
|
||||||
Authorization: Bearer {token}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Inbounds
|
## Inbounds
|
||||||
|
|
||||||
### Obtener todos los Inbounds
|
### Obtener todos los Inbounds
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
# مستندات API
|
# مستندات API
|
||||||
|
|
||||||
برای انجام درخواستها به REST API v2، در هر درخواست باید هدر Authorization با نوع Bearer و توکن ارسال شود.
|
|
||||||
|
|
||||||
```
|
|
||||||
Authorization: Bearer {token}
|
|
||||||
```
|
|
||||||
|
|
||||||
## ورودیها (Inbounds)
|
## ورودیها (Inbounds)
|
||||||
|
|
||||||
### دریافت تمام ورودیها
|
### دریافت تمام ورودیها
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,5 @@
|
||||||
# API Documentation
|
# API Documentation
|
||||||
|
|
||||||
Для выполнения запросов к REST API v2 в каждом запросе необходимо передавать заголовок Authorization с типом Bearer и указанием токена.
|
|
||||||
|
|
||||||
```
|
|
||||||
Authorization: Bearer {token}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Inbounds
|
## Inbounds
|
||||||
|
|
||||||
### Get All Inbounds
|
### Get All Inbounds
|
||||||
|
|
|
||||||
|
|
@ -57,20 +57,6 @@ class HttpUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async delete(url, params, options = {}) {
|
|
||||||
try {
|
|
||||||
const resp = await axios.delete(url, { params, ...options });
|
|
||||||
const msg = this._respToMsg(resp);
|
|
||||||
this._handleMsg(msg);
|
|
||||||
return msg;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('DELETE request failed:', error);
|
|
||||||
const errorMsg = new Msg(false, error.response?.data?.message || error.message || 'Request failed');
|
|
||||||
this._handleMsg(errorMsg);
|
|
||||||
return errorMsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static async postWithModal(url, data, modal) {
|
static async postWithModal(url, data, modal) {
|
||||||
if (modal) {
|
if (modal) {
|
||||||
modal.loading(true);
|
modal.loading(true);
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ func (a *APIController) createBackup(c *gin.Context) {
|
||||||
|
|
||||||
func (controller *APIController) initApiV2Router(router *gin.RouterGroup) {
|
func (controller *APIController) initApiV2Router(router *gin.RouterGroup) {
|
||||||
apiV2 := router.Group("/api/v2")
|
apiV2 := router.Group("/api/v2")
|
||||||
apiV2.Use(controller.apiTokenGuard)
|
apiV2.Use(controller.checkLogin)
|
||||||
|
|
||||||
serverApiGroup := apiV2.Group("/server")
|
serverApiGroup := apiV2.Group("/server")
|
||||||
inboundsApiGroup := apiV2.Group("/inbounds")
|
inboundsApiGroup := apiV2.Group("/inbounds")
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,16 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"x-ui/logger"
|
"x-ui/logger"
|
||||||
"x-ui/web/locale"
|
"x-ui/web/locale"
|
||||||
"x-ui/web/session"
|
"x-ui/web/session"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"x-ui/web/service"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BaseController struct{
|
type BaseController struct{}
|
||||||
settingService service.SettingService
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *BaseController) checkLogin(c *gin.Context) {
|
func (a *BaseController) checkLogin(c *gin.Context) {
|
||||||
if !session.IsLogin(c) {
|
if !session.IsLogin(c) {
|
||||||
|
|
@ -40,39 +35,3 @@ func I18nWeb(c *gin.Context, name string, params ...string) string {
|
||||||
msg := i18nFunc(locale.Web, name, params...)
|
msg := i18nFunc(locale.Web, name, params...)
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *BaseController) apiTokenGuard(c *gin.Context) {
|
|
||||||
bearerToken := c.Request.Header.Get("Authorization")
|
|
||||||
tokenParts := strings.Split(bearerToken, " ")
|
|
||||||
if len(tokenParts) != 2 {
|
|
||||||
pureJsonMsg(c, http.StatusUnauthorized, false, "Invalid token format")
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
reqToken := tokenParts[1]
|
|
||||||
token, err := a.settingService.GetApiToken()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
pureJsonMsg(c, http.StatusUnauthorized, false, err.Error())
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if reqToken != token {
|
|
||||||
pureJsonMsg(c, http.StatusUnauthorized, false, "Auth failed")
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userService := service.UserService{}
|
|
||||||
user, err := userService.GetFirstUser()
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("get current user info failed, error info:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
session.SetSessionUser(c, user)
|
|
||||||
|
|
||||||
c.Next()
|
|
||||||
|
|
||||||
session.ClearSession(c)
|
|
||||||
}
|
|
||||||
|
|
@ -45,7 +45,7 @@ func (a *InboundController) initRouter(g *gin.RouterGroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *InboundController) getInbounds(c *gin.Context) {
|
func (a *InboundController) getInbounds(c *gin.Context) {
|
||||||
user := session.GetSessionUser(c)
|
user := session.GetLoginUser(c)
|
||||||
inbounds, err := a.inboundService.GetInbounds(user.Id)
|
inbounds, err := a.inboundService.GetInbounds(user.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.obtain"), err)
|
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.obtain"), err)
|
||||||
|
|
@ -54,19 +54,10 @@ func (a *InboundController) getInbounds(c *gin.Context) {
|
||||||
jsonObj(c, inbounds, nil)
|
jsonObj(c, inbounds, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *InboundController) getAllInbounds(c *gin.Context) {
|
|
||||||
inbounds, err := a.inboundService.GetAllInbounds()
|
|
||||||
if err != nil {
|
|
||||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.toasts.obtain"), err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
jsonObj(c, inbounds, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *InboundController) getInbound(c *gin.Context) {
|
func (a *InboundController) getInbound(c *gin.Context) {
|
||||||
id, err := strconv.Atoi(c.Param("id"))
|
id, err := strconv.Atoi(c.Param("id"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jsonMsg(c, I18nWeb(c, "get"), errors.New("Invalid inbound id"))
|
jsonMsg(c, I18nWeb(c, "get"), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
inbound, err := a.inboundService.GetInbound(id)
|
inbound, err := a.inboundService.GetInbound(id)
|
||||||
|
|
@ -104,7 +95,7 @@ func (a *InboundController) addInbound(c *gin.Context) {
|
||||||
jsonMsg(c, I18nWeb(c, "pages.inbounds.create"), err)
|
jsonMsg(c, I18nWeb(c, "pages.inbounds.create"), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := session.GetSessionUser(c)
|
user := session.GetLoginUser(c)
|
||||||
inbound.UserId = user.Id
|
inbound.UserId = user.Id
|
||||||
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
|
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
|
||||||
inbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port)
|
inbound.Tag = fmt.Sprintf("inbound-%v", inbound.Port)
|
||||||
|
|
@ -352,7 +343,7 @@ func (a *InboundController) importInbound(c *gin.Context) {
|
||||||
jsonMsg(c, "Something went wrong!", err)
|
jsonMsg(c, "Something went wrong!", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := session.GetSessionUser(c)
|
user := session.GetLoginUser(c)
|
||||||
inbound.Id = 0
|
inbound.Id = 0
|
||||||
inbound.UserId = user.Id
|
inbound.UserId = user.Id
|
||||||
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
|
if inbound.Listen == "" || inbound.Listen == "0.0.0.0" || inbound.Listen == "::" || inbound.Listen == "::0" {
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ func (a *IndexController) login(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
session.SetMaxAge(c, sessionMaxAge*60)
|
session.SetMaxAge(c, sessionMaxAge*60)
|
||||||
session.SetSessionUser(c, user)
|
session.SetLoginUser(c, user)
|
||||||
if err := sessions.Default(c).Save(); err != nil {
|
if err := sessions.Default(c).Save(); err != nil {
|
||||||
logger.Warning("Unable to save session: ", err)
|
logger.Warning("Unable to save session: ", err)
|
||||||
return
|
return
|
||||||
|
|
@ -97,7 +97,7 @@ func (a *IndexController) login(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *IndexController) logout(c *gin.Context) {
|
func (a *IndexController) logout(c *gin.Context) {
|
||||||
user := session.GetSessionUser(c)
|
user := session.GetLoginUser(c)
|
||||||
if user != nil {
|
if user != nil {
|
||||||
logger.Infof("%s logged out successfully", user.Username)
|
logger.Infof("%s logged out successfully", user.Username)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,6 @@ package controller
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
"crypto/rand"
|
|
||||||
"crypto/sha512"
|
|
||||||
"encoding/hex"
|
|
||||||
|
|
||||||
"x-ui/web/entity"
|
"x-ui/web/entity"
|
||||||
"x-ui/web/service"
|
"x-ui/web/service"
|
||||||
|
|
@ -31,10 +28,6 @@ type SettingController struct {
|
||||||
panelService service.PanelService
|
panelService service.PanelService
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApiTokenResponse struct {
|
|
||||||
Token string `json:"token"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSettingController(g *gin.RouterGroup) *SettingController {
|
func NewSettingController(g *gin.RouterGroup) *SettingController {
|
||||||
a := &SettingController{}
|
a := &SettingController{}
|
||||||
a.initRouter(g)
|
a.initRouter(g)
|
||||||
|
|
@ -52,10 +45,6 @@ func (a *SettingController) initRouter(g *gin.RouterGroup) {
|
||||||
g.GET("/getDefaultJsonConfig", a.getDefaultXrayConfig)
|
g.GET("/getDefaultJsonConfig", a.getDefaultXrayConfig)
|
||||||
g.POST("/updateUserSecret", a.updateSecret)
|
g.POST("/updateUserSecret", a.updateSecret)
|
||||||
g.POST("/getUserSecret", a.getUserSecret)
|
g.POST("/getUserSecret", a.getUserSecret)
|
||||||
|
|
||||||
g.GET("/apiToken", a.getApiToken)
|
|
||||||
g.POST("/apiToken", a.generateApiToken)
|
|
||||||
g.DELETE("/apiToken", a.removeApiToken)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *SettingController) getAllSetting(c *gin.Context) {
|
func (a *SettingController) getAllSetting(c *gin.Context) {
|
||||||
|
|
@ -94,7 +83,7 @@ func (a *SettingController) updateUser(c *gin.Context) {
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user := session.GetSessionUser(c)
|
user := session.GetLoginUser(c)
|
||||||
if user.Username != form.OldUsername || user.Password != form.OldPassword {
|
if user.Username != form.OldUsername || user.Password != form.OldPassword {
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), errors.New(I18nWeb(c, "pages.settings.toasts.originalUserPassIncorrect")))
|
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), errors.New(I18nWeb(c, "pages.settings.toasts.originalUserPassIncorrect")))
|
||||||
return
|
return
|
||||||
|
|
@ -107,7 +96,7 @@ func (a *SettingController) updateUser(c *gin.Context) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user.Username = form.NewUsername
|
user.Username = form.NewUsername
|
||||||
user.Password = form.NewPassword
|
user.Password = form.NewPassword
|
||||||
session.SetSessionUser(c, user)
|
session.SetLoginUser(c, user)
|
||||||
}
|
}
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), err)
|
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), err)
|
||||||
}
|
}
|
||||||
|
|
@ -123,17 +112,17 @@ func (a *SettingController) updateSecret(c *gin.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifySettings"), err)
|
||||||
}
|
}
|
||||||
user := session.GetSessionUser(c)
|
user := session.GetLoginUser(c)
|
||||||
err = a.userService.UpdateUserSecret(user.Id, form.LoginSecret)
|
err = a.userService.UpdateUserSecret(user.Id, form.LoginSecret)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
user.LoginSecret = form.LoginSecret
|
user.LoginSecret = form.LoginSecret
|
||||||
session.SetSessionUser(c, user)
|
session.SetLoginUser(c, user)
|
||||||
}
|
}
|
||||||
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), err)
|
jsonMsg(c, I18nWeb(c, "pages.settings.toasts.modifyUser"), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *SettingController) getUserSecret(c *gin.Context) {
|
func (a *SettingController) getUserSecret(c *gin.Context) {
|
||||||
loginUser := session.GetSessionUser(c)
|
loginUser := session.GetLoginUser(c)
|
||||||
user := a.userService.GetUserSecret(loginUser.Id)
|
user := a.userService.GetUserSecret(loginUser.Id)
|
||||||
if user != nil {
|
if user != nil {
|
||||||
jsonObj(c, user, nil)
|
jsonObj(c, user, nil)
|
||||||
|
|
@ -148,50 +137,3 @@ func (a *SettingController) getDefaultXrayConfig(c *gin.Context) {
|
||||||
}
|
}
|
||||||
jsonObj(c, defaultJsonConfig, nil)
|
jsonObj(c, defaultJsonConfig, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *SettingController) getApiToken(c *gin.Context) {
|
|
||||||
response := &ApiTokenResponse{}
|
|
||||||
token, err := a.settingService.GetApiToken()
|
|
||||||
if err != nil {
|
|
||||||
jsonObj(c, response , err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
response.Token = token
|
|
||||||
|
|
||||||
jsonObj(c, response , nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *SettingController) generateApiToken(c *gin.Context) {
|
|
||||||
response := &ApiTokenResponse{}
|
|
||||||
randomBytes := make([]byte, 32)
|
|
||||||
|
|
||||||
_, err := rand.Read(randomBytes)
|
|
||||||
if err != nil {
|
|
||||||
jsonObj(c, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := sha512.Sum512(randomBytes)
|
|
||||||
response.Token = hex.EncodeToString(hash[:])
|
|
||||||
|
|
||||||
saveErr := a.settingService.SaveApiToken(response.Token)
|
|
||||||
|
|
||||||
if saveErr != nil {
|
|
||||||
jsonObj(c, nil, saveErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonMsgObj(c, I18nWeb(c, "pages.settings.security.apiTokenGeneratedSuccess"), response, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *SettingController) removeApiToken(c *gin.Context) {
|
|
||||||
err := a.settingService.RemoveApiToken()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
jsonObj(c, nil, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonMsg(c, "Removed", nil)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,6 @@ type AllSetting struct {
|
||||||
SubJsonMux string `json:"subJsonMux" form:"subJsonMux"`
|
SubJsonMux string `json:"subJsonMux" form:"subJsonMux"`
|
||||||
SubJsonRules string `json:"subJsonRules" form:"subJsonRules"`
|
SubJsonRules string `json:"subJsonRules" form:"subJsonRules"`
|
||||||
Datepicker string `json:"datepicker" form:"datepicker"`
|
Datepicker string `json:"datepicker" form:"datepicker"`
|
||||||
ApiToken string `json:"apiToken" form:"apiToken"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AllSetting) CheckValid() error {
|
func (s *AllSetting) CheckValid() error {
|
||||||
|
|
|
||||||
|
|
@ -235,28 +235,6 @@
|
||||||
</a-list-item>
|
</a-list-item>
|
||||||
<a-button type="primary" :loading="this.changeSecret" @click="updateSecret">{{ i18n "confirm" }}</a-button>
|
<a-button type="primary" :loading="this.changeSecret" @click="updateSecret">{{ i18n "confirm" }}</a-button>
|
||||||
</a-form>
|
</a-form>
|
||||||
|
|
||||||
<a-divider>{{ i18n "pages.settings.security.apiTitle"}}</a-divider>
|
|
||||||
<a-list-item>
|
|
||||||
<a-row>
|
|
||||||
<a-col :lg="24" :xl="12" style="white-space: pre-line;">
|
|
||||||
<a-list-item-meta description='{{ i18n "pages.settings.security.apiDescription" }}'>
|
|
||||||
</a-list-item-meta>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="24" :xl="12">
|
|
||||||
<a-tag class="tr-info-tag" color="green" v-if="apiToken">[[ apiToken ]]</a-tag>
|
|
||||||
<div style="display: flex; flex-direction: row; align-items: center; gap: 0.5rem; margin-top: 0.5rem">
|
|
||||||
<a-tooltip title='{{ i18n "copy" }}' v-if="apiToken">
|
|
||||||
<a-button style="min-width: 24px;" size="small" icon="snippets" :id="'copy-api-token'" @click="copyApiToken"></a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
<a-button @click="this.generateApiToken">{{ i18n "pages.settings.security.apiGenerateToken" }}</a-button>
|
|
||||||
<a-tooltip title='{{ i18n "delete" }}' v-if="apiToken">
|
|
||||||
<a-button type="danger" style="min-width: 24px;" size="small" icon="delete" :id="'copy-api-token'" @click="removeApiToken"></a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
</div>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
|
||||||
</a-list-item>
|
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane key="3" tab='{{ i18n "pages.settings.TGBotSettings"}}'>
|
<a-tab-pane key="3" tab='{{ i18n "pages.settings.TGBotSettings"}}'>
|
||||||
<a-list item-layout="horizontal">
|
<a-list item-layout="horizontal">
|
||||||
|
|
@ -423,7 +401,6 @@
|
||||||
</a-layout-content>
|
</a-layout-content>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
<script src="{{ .base_path }}assets/clipboard/clipboard.min.js?{{ .cur_ver }}"></script>
|
|
||||||
{{template "js" .}}
|
{{template "js" .}}
|
||||||
<script src="{{ .base_path }}assets/js/model/setting.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/model/setting.js?{{ .cur_ver }}"></script>
|
||||||
{{template "component/themeSwitcher" .}}
|
{{template "component/themeSwitcher" .}}
|
||||||
|
|
@ -545,8 +522,7 @@
|
||||||
sample = []
|
sample = []
|
||||||
this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
|
this.remarkModel.forEach(r => sample.push(this.remarkModels[r]));
|
||||||
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
|
this.remarkSample = sample.length == 0 ? '' : sample.join(this.remarkSeparator);
|
||||||
},
|
}
|
||||||
apiToken: null,
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
loading(spinning = true) {
|
loading(spinning = true) {
|
||||||
|
|
@ -559,7 +535,6 @@
|
||||||
if (msg.success) {
|
if (msg.success) {
|
||||||
this.oldAllSetting = new AllSetting(msg.obj);
|
this.oldAllSetting = new AllSetting(msg.obj);
|
||||||
this.allSetting = new AllSetting(msg.obj);
|
this.allSetting = new AllSetting(msg.obj);
|
||||||
this.apiToken = msg.obj.apiToken;
|
|
||||||
app.changeRemarkSample();
|
app.changeRemarkSample();
|
||||||
this.saveBtnDisable = true;
|
this.saveBtnDisable = true;
|
||||||
}
|
}
|
||||||
|
|
@ -673,38 +648,6 @@
|
||||||
updatedNoises[index] = { ...updatedNoises[index], delay: value };
|
updatedNoises[index] = { ...updatedNoises[index], delay: value };
|
||||||
this.noisesArray = updatedNoises;
|
this.noisesArray = updatedNoises;
|
||||||
},
|
},
|
||||||
async generateApiToken() {
|
|
||||||
this.loading(true);
|
|
||||||
const msg = await HttpUtil.post("/panel/setting/apiToken");
|
|
||||||
if (msg && msg.obj) {
|
|
||||||
this.apiToken = msg.obj.token;
|
|
||||||
}
|
|
||||||
this.loading(false);
|
|
||||||
},
|
|
||||||
copyApiToken() {
|
|
||||||
ClipboardJS.copy(this.apiToken);
|
|
||||||
app.$message.success('{{ i18n "copied" }}')
|
|
||||||
},
|
|
||||||
async removeApiToken() {
|
|
||||||
await new Promise(() => {
|
|
||||||
this.$confirm({
|
|
||||||
title: '{{ i18n "pages.settings.security.apiConfirmRemoveTokenTitle" }}',
|
|
||||||
content: '{{ i18n "pages.settings.security.apiConfirmRemoveTokenText" }}',
|
|
||||||
class: themeSwitcher.currentTheme,
|
|
||||||
okText: '{{ i18n "delete"}}',
|
|
||||||
cancelText: '{{ i18n "cancel" }}',
|
|
||||||
onOk: async () => {
|
|
||||||
this.loading(true);
|
|
||||||
const msg = await HttpUtil.delete("/panel/setting/apiToken");
|
|
||||||
if (msg && msg.success) {
|
|
||||||
app.$message.success('{{ i18n "deleted" }}')
|
|
||||||
this.apiToken = null;
|
|
||||||
}
|
|
||||||
this.loading(false);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
fragment: {
|
fragment: {
|
||||||
|
|
|
||||||
|
|
@ -596,46 +596,3 @@ func (s *SettingService) GetDefaultSettings(host string) (interface{}, error) {
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (s *SettingService) GetApiToken() (token string, err error) {
|
|
||||||
db := database.GetDB()
|
|
||||||
setting := &model.Setting{}
|
|
||||||
err = db.Model(model.Setting{}).Where("key = 'apiToken'").Find(setting).Error
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return setting.Value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) SaveApiToken(token string) error {
|
|
||||||
db := database.GetDB()
|
|
||||||
setting := &model.Setting{}
|
|
||||||
err := db.Model(model.Setting{}).Where("key = 'apiToken'").Find(setting).Error
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if setting.Value == "" {
|
|
||||||
newSetting := model.Setting{
|
|
||||||
Key: "apiToken",
|
|
||||||
Value: token,
|
|
||||||
}
|
|
||||||
fmt.Println("New setting created")
|
|
||||||
return db.Model(model.Setting{}).Create(&newSetting).Error
|
|
||||||
}
|
|
||||||
return db.Model(model.Setting{}).
|
|
||||||
Where("key = 'apiToken'").
|
|
||||||
Update("value", token).Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SettingService) RemoveApiToken() error {
|
|
||||||
db := database.GetDB()
|
|
||||||
setting := &model.Setting{}
|
|
||||||
err := db.Model(model.Setting{}).Where("key = 'apiToken'").Find(setting).Error
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return db.Model(model.Setting{}).Delete(setting, setting.Id).Error
|
|
||||||
}
|
|
||||||
|
|
@ -18,7 +18,7 @@ func init() {
|
||||||
gob.Register(model.User{})
|
gob.Register(model.User{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetSessionUser(c *gin.Context, user *model.User) {
|
func SetLoginUser(c *gin.Context, user *model.User) {
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -35,7 +35,7 @@ func SetMaxAge(c *gin.Context, maxAge int) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSessionUser(c *gin.Context) *model.User {
|
func GetLoginUser(c *gin.Context) *model.User {
|
||||||
s := sessions.Default(c)
|
s := sessions.Default(c)
|
||||||
obj := s.Get(loginUserKey)
|
obj := s.Get(loginUserKey)
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
|
|
@ -51,7 +51,7 @@ func GetSessionUser(c *gin.Context) *model.User {
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsLogin(c *gin.Context) bool {
|
func IsLogin(c *gin.Context) bool {
|
||||||
return GetSessionUser(c) != nil
|
return GetLoginUser(c) != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ClearSession(c *gin.Context) {
|
func ClearSession(c *gin.Context) {
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Adds an additional layer of authentication to provide more security."
|
"loginSecurityDesc" = "Adds an additional layer of authentication to provide more security."
|
||||||
"secretToken" = "Secret Token"
|
"secretToken" = "Secret Token"
|
||||||
"secretTokenDesc" = "Please securely store this token in a safe place. This token is required for login and cannot be recovered."
|
"secretTokenDesc" = "Please securely store this token in a safe place. This token is required for login and cannot be recovered."
|
||||||
"apiDescription" = "To make requests to REST API v2, you need to include the Authorization header with the Bearer type and the token in each request.\nExample: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Generate token"
|
|
||||||
"apiTokenGeneratedSuccess" = "Token generated"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Confirm token deletion"
|
|
||||||
"apiConfirmRemoveTokenText" = "After deleting the token, access to the API will be unavailable, and making requests will no longer be possible."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Modify Settings"
|
"modifySettings" = "Modify Settings"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Habilitar un paso adicional de seguridad para el inicio de sesión de usuarios."
|
"loginSecurityDesc" = "Habilitar un paso adicional de seguridad para el inicio de sesión de usuarios."
|
||||||
"secretToken" = "Token Secreto"
|
"secretToken" = "Token Secreto"
|
||||||
"secretTokenDesc" = "Por favor, copia y guarda este token de forma segura en un lugar seguro. Este token es necesario para iniciar sesión y no se puede recuperar con la herramienta de comando x-ui."
|
"secretTokenDesc" = "Por favor, copia y guarda este token de forma segura en un lugar seguro. Este token es necesario para iniciar sesión y no se puede recuperar con la herramienta de comando x-ui."
|
||||||
"apiDescription" = "Para realizar solicitudes al REST API v2, es necesario incluir en cada solicitud el encabezado Authorization con el tipo Bearer y el token.\nEjemplo: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Generar token"
|
|
||||||
"apiTokenGeneratedSuccess" = "Token generado con éxito"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Confirmar eliminación del token"
|
|
||||||
"apiConfirmRemoveTokenText" = "Después de eliminar el token, el acceso al API no estará disponible y no se podrán realizar solicitudes."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Modificar Configuraciones "
|
"modifySettings" = "Modificar Configuraciones "
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "یک لایه اضافی از احراز هویت برای ایجاد امنیت بیشتر اضافه می کند"
|
"loginSecurityDesc" = "یک لایه اضافی از احراز هویت برای ایجاد امنیت بیشتر اضافه می کند"
|
||||||
"secretToken" = "توکن مخفی"
|
"secretToken" = "توکن مخفی"
|
||||||
"secretTokenDesc" = "لطفاً این توکن را در مکانی امن ذخیره کنید. این توکن برای ورود به سیستم مورد نیاز است و قابل بازیابی نیست"
|
"secretTokenDesc" = "لطفاً این توکن را در مکانی امن ذخیره کنید. این توکن برای ورود به سیستم مورد نیاز است و قابل بازیابی نیست"
|
||||||
"apiDescription" = "برای انجام درخواستها به REST API v2، در هر درخواست باید هدر Authorization با نوع Bearer و توکن ارسال شود.\nمثال: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "توکن ایجاد کنید"
|
|
||||||
"apiTokenGeneratedSuccessful" = "توکن با موفقیت ایجاد شد"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "تایید حذف توکن"
|
|
||||||
"apiConfirmRemoveTokenText" = "پس از حذف توکن، دسترسی به API غیرفعال میشود و انجام درخواستها امکانپذیر نخواهد بود."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "ویرایش تنظیمات"
|
"modifySettings" = "ویرایش تنظیمات"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Menambahkan lapisan otentikasi tambahan untuk memberikan keamanan lebih."
|
"loginSecurityDesc" = "Menambahkan lapisan otentikasi tambahan untuk memberikan keamanan lebih."
|
||||||
"secretToken" = "Token Rahasia"
|
"secretToken" = "Token Rahasia"
|
||||||
"secretTokenDesc" = "Simpan token ini dengan aman di tempat yang aman. Token ini diperlukan untuk login dan tidak dapat dipulihkan."
|
"secretTokenDesc" = "Simpan token ini dengan aman di tempat yang aman. Token ini diperlukan untuk login dan tidak dapat dipulihkan."
|
||||||
"apiDescription" = "Untuk melakukan permintaan ke REST API v2, Anda perlu menyertakan header Authorization dengan tipe Bearer dan token di setiap permintaan.\nContoh: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Buat token"
|
|
||||||
"apiTokenGeneratedSuccessful" = "Token berhasil dibuat"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Konfirmasi penghapusan token"
|
|
||||||
"apiConfirmRemoveTokenText" = "Setelah menghapus token, akses ke API akan tidak tersedia, dan permintaan tidak dapat dilakukan."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Ubah Pengaturan"
|
"modifySettings" = "Ubah Pengaturan"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "追加の認証を追加してセキュリティを向上させる"
|
"loginSecurityDesc" = "追加の認証を追加してセキュリティを向上させる"
|
||||||
"secretToken" = "セキュリティトークン"
|
"secretToken" = "セキュリティトークン"
|
||||||
"secretTokenDesc" = "このトークンを安全な場所に保管してください。このトークンはログインに使用され、紛失すると回復できません。"
|
"secretTokenDesc" = "このトークンを安全な場所に保管してください。このトークンはログインに使用され、紛失すると回復できません。"
|
||||||
"apiDescription" = "REST API v2 にリクエストを送信するには、Authorization ヘッダーに Bearer タイプのトークンを含める必要があります。\n例: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "トークンを生成"
|
|
||||||
"apiTokenGeneratedSuccessful" = "トークンが正常に生成されました"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "トークン削除の確認"
|
|
||||||
"apiConfirmRemoveTokenText" = "トークンを削除すると、API へのアクセスができなくなり、リクエストを送信できなくなります。"
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "設定を変更"
|
"modifySettings" = "設定を変更"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Adiciona uma camada extra de autenticação para fornecer mais segurança."
|
"loginSecurityDesc" = "Adiciona uma camada extra de autenticação para fornecer mais segurança."
|
||||||
"secretToken" = "Token Secreto"
|
"secretToken" = "Token Secreto"
|
||||||
"secretTokenDesc" = "Por favor, armazene este token em um local seguro. Este token é necessário para o login e não pode ser recuperado."
|
"secretTokenDesc" = "Por favor, armazene este token em um local seguro. Este token é necessário para o login e não pode ser recuperado."
|
||||||
"apiDescription" = "Para fazer solicitações à REST API v2, você precisa incluir o cabeçalho Authorization com o tipo Bearer e o token em cada solicitação.\nExemplo: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Gerar token"
|
|
||||||
"apiTokenGeneratedSuccessful" = "Token gerado com sucesso"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Confirmar exclusão do token"
|
|
||||||
"apiConfirmRemoveTokenText" = "Após excluir o token, o acesso à API não estará mais disponível e não será possível fazer solicitações."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Modificar Configurações"
|
"modifySettings" = "Modificar Configurações"
|
||||||
|
|
|
||||||
|
|
@ -446,12 +446,6 @@
|
||||||
"loginSecurityDesc" = "Включить дополнительные меры безопасности входа пользователя"
|
"loginSecurityDesc" = "Включить дополнительные меры безопасности входа пользователя"
|
||||||
"secretToken" = "Секретный токен"
|
"secretToken" = "Секретный токен"
|
||||||
"secretTokenDesc" = "Пожалуйста, скопируйте и сохраните этот токен в безопасном месте. Этот токен необходим для входа в систему и не может быть восстановлен с помощью инструмента x-ui"
|
"secretTokenDesc" = "Пожалуйста, скопируйте и сохраните этот токен в безопасном месте. Этот токен необходим для входа в систему и не может быть восстановлен с помощью инструмента x-ui"
|
||||||
"apiTitle" = "REST API"
|
|
||||||
"apiDescription" = "Для выполнения запросов к REST API v2 в каждом запросе необходимо передавать заголовок Authorization с типом Bearer и указанием токена.\nПример: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Сгенерировать токен"
|
|
||||||
"apiTokenGeneratedSuccess" = "Токен сгенерирован"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Подтвердите удаление токена"
|
|
||||||
"apiConfirmRemoveTokenText" = "После удаления токена доступ к API станет недоступным, и выполнение запросов будет невозможно."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Изменение настроек"
|
"modifySettings" = "Изменение настроек"
|
||||||
|
|
@ -460,8 +454,6 @@
|
||||||
"originalUserPassIncorrect" = "Неверное имя пользователя или пароль"
|
"originalUserPassIncorrect" = "Неверное имя пользователя или пароль"
|
||||||
"userPassMustBeNotEmpty" = "Новое имя пользователя и новый пароль должны быть заполнены"
|
"userPassMustBeNotEmpty" = "Новое имя пользователя и новый пароль должны быть заполнены"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[tgbot]
|
[tgbot]
|
||||||
"keyboardClosed" = "❌ Закрыта настраиваемая клавиатура!"
|
"keyboardClosed" = "❌ Закрыта настраиваемая клавиатура!"
|
||||||
"noResult" = "❗ Нет результатов!"
|
"noResult" = "❗ Нет результатов!"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Daha fazla güvenlik sağlamak için ek bir kimlik doğrulama katmanı ekler."
|
"loginSecurityDesc" = "Daha fazla güvenlik sağlamak için ek bir kimlik doğrulama katmanı ekler."
|
||||||
"secretToken" = "Gizli Anahtar"
|
"secretToken" = "Gizli Anahtar"
|
||||||
"secretTokenDesc" = "Bu anahtarı güvenli bir yerde saklayın. Bu anahtar giriş için gereklidir ve geri alınamaz."
|
"secretTokenDesc" = "Bu anahtarı güvenli bir yerde saklayın. Bu anahtar giriş için gereklidir ve geri alınamaz."
|
||||||
"apiDescription" = "REST API v2'ye istek gönderebilmek için, her isteğe Bearer türünde bir yetkilendirme (Authorization) başlığı ve token eklemeniz gerekir.\nÖrnek: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Token oluştur"
|
|
||||||
"apiTokenGeneratedSuccessful" = "Token başarıyla oluşturuldu"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Token silme onayı"
|
|
||||||
"apiConfirmRemoveTokenText" = "Token silindikten sonra API erişimi mümkün olmayacak ve istek gönderilemeyecektir."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Ayarları Değiştir"
|
"modifySettings" = "Ayarları Değiştir"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Додає додатковий рівень автентифікації для забезпечення більшої безпеки."
|
"loginSecurityDesc" = "Додає додатковий рівень автентифікації для забезпечення більшої безпеки."
|
||||||
"secretToken" = "Секретний маркер"
|
"secretToken" = "Секретний маркер"
|
||||||
"secretTokenDesc" = "Будь ласка, надійно зберігайте цей маркер у безпечному місці. Цей маркер потрібен для входу, і його неможливо відновити."
|
"secretTokenDesc" = "Будь ласка, надійно зберігайте цей маркер у безпечному місці. Цей маркер потрібен для входу, і його неможливо відновити."
|
||||||
"apiDescription" = "Щоб надсилати запити до REST API v2, вам потрібно додати заголовок Authorization із типом Bearer і токен у кожен запит.\nПриклад: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Створити токен"
|
|
||||||
"apiTokenGeneratedSuccessful" = "Токен успішно створено"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Підтвердження видалення токена"
|
|
||||||
"apiConfirmRemoveTokenText" = "Після видалення токена доступ до API буде неможливим, і надсилати запити більше не вдасться."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Змінити налаштування"
|
"modifySettings" = "Змінити налаштування"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "Bật bước bảo mật đăng nhập bổ sung cho người dùng"
|
"loginSecurityDesc" = "Bật bước bảo mật đăng nhập bổ sung cho người dùng"
|
||||||
"secretToken" = "Mã bí mật"
|
"secretToken" = "Mã bí mật"
|
||||||
"secretTokenDesc" = "Vui lòng sao chép và lưu trữ mã này một cách an toàn ở nơi an toàn. Mã này cần thiết để đăng nhập và không thể phục hồi từ công cụ lệnh x-ui."
|
"secretTokenDesc" = "Vui lòng sao chép và lưu trữ mã này một cách an toàn ở nơi an toàn. Mã này cần thiết để đăng nhập và không thể phục hồi từ công cụ lệnh x-ui."
|
||||||
"apiDescription" = "Để gửi yêu cầu đến REST API v2, bạn cần bao gồm tiêu đề Authorization với loại Bearer và token trong mỗi yêu cầu.\nVí dụ: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "Tạo token"
|
|
||||||
"apiTokenGeneratedSuccessful" = "Token đã được tạo thành công"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "Xác nhận xóa token"
|
|
||||||
"apiConfirmRemoveTokenText" = "Sau khi xóa token, quyền truy cập API sẽ không còn khả dụng và bạn sẽ không thể gửi yêu cầu nữa."
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "Chỉnh sửa cài đặt "
|
"modifySettings" = "Chỉnh sửa cài đặt "
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "添加额外的身份验证以提高安全性"
|
"loginSecurityDesc" = "添加额外的身份验证以提高安全性"
|
||||||
"secretToken" = "安全令牌"
|
"secretToken" = "安全令牌"
|
||||||
"secretTokenDesc" = "请将此令牌存储在安全的地方。此令牌用于登录,丢失无法恢复。"
|
"secretTokenDesc" = "请将此令牌存储在安全的地方。此令牌用于登录,丢失无法恢复。"
|
||||||
"apiDescription" = "要向 REST API v2 发送请求,您需要在每个请求中包含带有 Bearer 类型的 Authorization 头和令牌。\n示例: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "生成令牌"
|
|
||||||
"apiTokenGeneratedSuccessful" = "令牌生成成功"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "确认删除令牌"
|
|
||||||
"apiConfirmRemoveTokenText" = "删除令牌后,将无法访问 API,并且无法再发送请求。"
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "修改设置"
|
"modifySettings" = "修改设置"
|
||||||
|
|
|
||||||
|
|
@ -446,11 +446,6 @@
|
||||||
"loginSecurityDesc" = "新增額外的身份驗證以提高安全性"
|
"loginSecurityDesc" = "新增額外的身份驗證以提高安全性"
|
||||||
"secretToken" = "安全令牌"
|
"secretToken" = "安全令牌"
|
||||||
"secretTokenDesc" = "請將此令牌儲存在安全的地方。此令牌用於登入,丟失無法恢復。"
|
"secretTokenDesc" = "請將此令牌儲存在安全的地方。此令牌用於登入,丟失無法恢復。"
|
||||||
"apiDescription" = "要向 REST API v2 發送請求,您需要在每個請求中包含帶有 Bearer 類型的 Authorization 標頭和權杖。\n示例: Authorization: Bearer {token}"
|
|
||||||
"apiGenerateToken" = "生成權杖"
|
|
||||||
"apiTokenGeneratedSuccessful" = "權杖生成成功"
|
|
||||||
"apiConfirmRemoveTokenTitle" = "確認刪除權杖"
|
|
||||||
"apiConfirmRemoveTokenText" = "刪除權杖後,將無法存取 API,並且無法再發送請求。"
|
|
||||||
|
|
||||||
[pages.settings.toasts]
|
[pages.settings.toasts]
|
||||||
"modifySettings" = "修改設定"
|
"modifySettings" = "修改設定"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue