mirror of
https://github.com/yhl452493373/frps-panel.git
synced 2026-04-04 06:16:59 +08:00
add an api proxy url to access frp server info
This commit is contained in:
@@ -14,6 +14,22 @@ section {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.layui-header{
|
||||
line-height: 60px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.layui-title{
|
||||
position: absolute;
|
||||
left: 200px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
padding: 0 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#searchForm input {
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
|
||||
@@ -5,37 +5,20 @@ var loadServerInfo = (function ($) {
|
||||
* get server info
|
||||
* @param lang {{}} language json
|
||||
*/
|
||||
function loadServerInfo(lang) {
|
||||
function loadServerInfo(lang, title) {
|
||||
console.log(title)
|
||||
$("#title").text(title);
|
||||
$('#content').empty();
|
||||
var loading = layui.layer.load();
|
||||
|
||||
$.ajax({
|
||||
url: 'http://127.0.0.1:7500/api/serverinfo',
|
||||
dataType: 'jsonp',
|
||||
success: function (result) {
|
||||
result = {
|
||||
"version": "0.51.3",
|
||||
"bind_port": 7000,
|
||||
"vhost_http_port": 80,
|
||||
"vhost_https_port": 443,
|
||||
"tcpmux_httpconnect_port": 0,
|
||||
"kcp_bind_port": 7000,
|
||||
"quic_bind_port": 0,
|
||||
"subdomain_host": "frp.yanghuanglin.com",
|
||||
"max_pool_count": 100,
|
||||
"max_ports_per_client": 0,
|
||||
"heart_beat_timeout": 90,
|
||||
"total_traffic_in": 1669491,
|
||||
"total_traffic_out": 54422369,
|
||||
"cur_conns": 0,
|
||||
"client_counts": 1,
|
||||
"proxy_type_count": {"http": 9, "https": 8, "tcp": 7}
|
||||
};
|
||||
renderServerInfo(result);
|
||||
},
|
||||
complete: function () {
|
||||
layui.layer.close(loading);
|
||||
$.getJSON('/proxy/api/serverinfo').done(function (result) {
|
||||
if (result.success) {
|
||||
renderServerInfo(JSON.parse(result.data));
|
||||
} else {
|
||||
layui.layer.msg(result.message);
|
||||
}
|
||||
}).always(function () {
|
||||
layui.layer.close(loading);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,8 @@ var loadUserList = (function ($) {
|
||||
* load i18n language
|
||||
* @param lang {{}} language json
|
||||
*/
|
||||
function loadUserList(lang) {
|
||||
function loadUserList(lang, title) {
|
||||
$("#title").text(title);
|
||||
var html = layui.laytpl($('#userListTemplate').html()).render();
|
||||
$('#content').html(html);
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
$.getJSON('/lang').done(function (lang) {
|
||||
layui.element.on('nav(leftNav)', function (elem) {
|
||||
if (elem.attr('id') === 'serverInfo') {
|
||||
loadServerInfo(lang);
|
||||
loadServerInfo(lang, elem.text().trim());
|
||||
} else if (elem.attr('id') === 'userList') {
|
||||
loadUserList(lang);
|
||||
loadUserList(lang, elem.text().trim());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 322 KiB |
@@ -2,13 +2,13 @@
|
||||
<html lang="">
|
||||
<head>
|
||||
<title>${ .UserManage }</title>
|
||||
<link rel="stylesheet" href="./static/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="./static/lib/layui/css/layui.css">
|
||||
<link rel="stylesheet" href="./static/css/layui-theme-dark.css">
|
||||
<link rel="stylesheet" href="./static/css/index.css">
|
||||
<link rel="stylesheet" href="./static/css/index-color.css">
|
||||
<script src="./static/layui/layui.js"></script>
|
||||
<script src="./static/js/echarts.min.js"></script>
|
||||
<script src="./static/js/filesize.min.js"></script>
|
||||
<script src="./static/lib/layui/layui.js"></script>
|
||||
<script src="./static/lib/echarts.min.js"></script>
|
||||
<script src="./static/lib/filesize.min.js"></script>
|
||||
<script src="./static/js/index-server-info.js"></script>
|
||||
<script src="./static/js/index-user-list.js"></script>
|
||||
<script src="./static/js/index.js"></script>
|
||||
@@ -22,13 +22,7 @@
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
.layui-header {
|
||||
width: 200px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-body {
|
||||
top: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -37,6 +31,7 @@
|
||||
<div class="layui-layout layui-layout-admin">
|
||||
<div class="layui-header">
|
||||
<div class="layui-logo layui-hide-xs layui-bg-black">${ .FrpsMultiuser }</div>
|
||||
<div class="layui-title" id="title"></div>
|
||||
</div>
|
||||
<div class="layui-side layui-bg-black">
|
||||
<div class="layui-side-scroll">
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -103,24 +102,14 @@ func ParseConfigFile(file string) (controller.CommonInfo, map[string]controller.
|
||||
log.Printf("fail to get [common] section from file %s : %v", file, err)
|
||||
return common, nil, nil, nil, nil, iniFile, err
|
||||
}
|
||||
pluginAddr := commonSection.Key("plugin_addr").Value()
|
||||
if len(pluginAddr) != 0 {
|
||||
common.PluginAddr = pluginAddr
|
||||
} else {
|
||||
common.PluginAddr = "0.0.0.0"
|
||||
}
|
||||
pluginPort := commonSection.Key("plugin_port").Value()
|
||||
if len(pluginPort) != 0 {
|
||||
port, err := strconv.Atoi(pluginPort)
|
||||
if err != nil {
|
||||
return common, nil, nil, nil, nil, iniFile, err
|
||||
}
|
||||
common.PluginPort = port
|
||||
} else {
|
||||
common.PluginPort = 7200
|
||||
}
|
||||
common.PluginAddr = commonSection.Key("plugin_addr").MustString("0.0.0.0")
|
||||
common.PluginPort = commonSection.Key("plugin_port").MustInt(7200)
|
||||
common.User = commonSection.Key("admin_user").Value()
|
||||
common.Pwd = commonSection.Key("admin_pwd").Value()
|
||||
common.DashboardAddr = commonSection.Key("dashboard_addr").MustString("127.0.0.1")
|
||||
common.DashboardPort = commonSection.Key("dashboard_port").MustInt(7500)
|
||||
common.DashboardUser = commonSection.Key("dashboard_user").Value()
|
||||
common.DashboardPwd = commonSection.Key("dashboard_pwd").Value()
|
||||
|
||||
portsSection, err := iniFile.GetSection("ports")
|
||||
if err != nil {
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
; basic options
|
||||
[common]
|
||||
; frps config info
|
||||
plugin_addr = 127.0.0.1
|
||||
plugin_port = 7200
|
||||
admin_user = admin
|
||||
admin_pwd = admin
|
||||
|
||||
; frp dashboard config info
|
||||
dashboard_addr = 127.0.0.1
|
||||
dashboard_port = 7500
|
||||
dashboard_user = admin
|
||||
dashboard_pwd = admin
|
||||
|
||||
; user tokens
|
||||
[users]
|
||||
user1 = token1
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
plugin "github.com/fatedier/frp/pkg/plugin/server"
|
||||
ginI18n "github.com/gin-contrib/i18n"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@@ -21,6 +24,7 @@ const (
|
||||
SaveError = 3
|
||||
UserFormatError = 4
|
||||
TokenFormatError = 5
|
||||
FrpServerError = 6
|
||||
)
|
||||
|
||||
var UserFormatReg = regexp.MustCompile("^\\w+$")
|
||||
@@ -42,6 +46,10 @@ type CommonInfo struct {
|
||||
PluginPort int
|
||||
User string
|
||||
Pwd string
|
||||
DashboardAddr string
|
||||
DashboardPort int
|
||||
DashboardUser string
|
||||
DashboardPwd string
|
||||
}
|
||||
|
||||
type TokenInfo struct {
|
||||
@@ -67,6 +75,11 @@ type OperationResponse struct {
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type ProxyResponse struct {
|
||||
OperationResponse
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type TokenSearch struct {
|
||||
TokenInfo
|
||||
Page int `form:"page"`
|
||||
@@ -632,3 +645,45 @@ func (c *HandleController) MakeEnableTokensFunc() func(context *gin.Context) {
|
||||
context.JSON(http.StatusOK, &response)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *HandleController) MakeProxyFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
res := ProxyResponse{}
|
||||
host := c.CommonInfo.DashboardAddr
|
||||
port := c.CommonInfo.DashboardPort
|
||||
requestUrl := "http://" + host + ":" + strconv.Itoa(port) + context.Param("serverApi")
|
||||
request, _ := http.NewRequest("GET", requestUrl, nil)
|
||||
username := c.CommonInfo.DashboardUser
|
||||
if len(strings.TrimSpace(username)) != 0 {
|
||||
password := c.CommonInfo.DashboardPwd
|
||||
auth := []byte(username + ":" + password)
|
||||
request.Header.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString(auth))
|
||||
}
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
|
||||
if err != nil {
|
||||
res.Code = FrpServerError
|
||||
res.Success = false
|
||||
res.Message = err.Error()
|
||||
context.JSON(http.StatusOK, &res)
|
||||
return
|
||||
}
|
||||
|
||||
res.Code = response.StatusCode
|
||||
body, err := io.ReadAll(response.Body)
|
||||
|
||||
if err != nil {
|
||||
res.Success = false
|
||||
res.Message = err.Error()
|
||||
} else {
|
||||
if res.Code == http.StatusOK {
|
||||
res.Success = true
|
||||
res.Data = string(body)
|
||||
} else {
|
||||
res.Success = false
|
||||
res.Message = string(body)
|
||||
}
|
||||
}
|
||||
context.JSON(http.StatusOK, &res)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ func (c *HandleController) Register(rootDir string, engine *gin.Engine) {
|
||||
group.POST("/remove", c.MakeRemoveTokensFunc())
|
||||
group.POST("/disable", c.MakeDisableTokensFunc())
|
||||
group.POST("/enable", c.MakeEnableTokensFunc())
|
||||
group.GET("/proxy/*serverApi", c.MakeProxyFunc())
|
||||
}
|
||||
|
||||
func (c *HandleController) HandleLogin(content *plugin.LoginContent) plugin.Response {
|
||||
|
||||
Reference in New Issue
Block a user