🏗️ implement proxy management features and refactor related services
This commit is contained in:
parent
2edbbcb871
commit
9f46ea781d
@ -1,108 +0,0 @@
|
|||||||
import {ipcMain} from "electron";
|
|
||||||
import { logDebug, logError, logInfo, LogModule, logWarn } from "../utils/log";
|
|
||||||
|
|
||||||
const {exec, spawn} = require("child_process");
|
|
||||||
|
|
||||||
type LocalPort = {
|
|
||||||
protocol: string;
|
|
||||||
ip: string;
|
|
||||||
port: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const initLocalApi = () => {
|
|
||||||
const command = process.platform === 'win32'
|
|
||||||
? 'netstat -a -n'
|
|
||||||
: 'netstat -an | grep LISTEN';
|
|
||||||
|
|
||||||
ipcMain.on("local.getLocalPorts", async (event, args) => {
|
|
||||||
logInfo(LogModule.APP, "Starting to retrieve local ports");
|
|
||||||
// 执行命令
|
|
||||||
exec(command, (error, stdout, stderr) => {
|
|
||||||
if (error) {
|
|
||||||
logError(LogModule.APP, `getLocalPorts - error: ${error.message}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (stderr) {
|
|
||||||
logWarn(LogModule.APP, `getLocalPorts - stderr: ${stderr}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
logDebug(LogModule.APP, `Command output: ${stdout}`);
|
|
||||||
let ports = [];
|
|
||||||
if (stdout) {
|
|
||||||
if (process.platform === 'win32') {
|
|
||||||
// window
|
|
||||||
ports = stdout.split('\r\n')
|
|
||||||
.filter(f => f.indexOf('TCP') !== -1 || f.indexOf('UDP') !== -1)
|
|
||||||
.map(m => {
|
|
||||||
const cols = m.split(' ')
|
|
||||||
.filter(f => f != '')
|
|
||||||
const local = cols[1]
|
|
||||||
const s = local.lastIndexOf(":")
|
|
||||||
let localIP = local.slice(0, s);
|
|
||||||
let localPort = local.slice(s - local.length + 1);
|
|
||||||
const singe: LocalPort = {
|
|
||||||
protocol: cols[0],
|
|
||||||
ip: localIP,
|
|
||||||
port: localPort
|
|
||||||
}
|
|
||||||
|
|
||||||
return singe;
|
|
||||||
})
|
|
||||||
} else if (process.platform === 'darwin') {
|
|
||||||
// mac
|
|
||||||
ports = stdout.split('\n')
|
|
||||||
.filter(m => {
|
|
||||||
const cols = m.split(' ')
|
|
||||||
.filter(f => f != '')
|
|
||||||
const local = cols[3]
|
|
||||||
return local
|
|
||||||
})
|
|
||||||
.map(m => {
|
|
||||||
const cols = m.split(' ')
|
|
||||||
.filter(f => f != '')
|
|
||||||
const local = cols[3]
|
|
||||||
const s = local.lastIndexOf(".")
|
|
||||||
let localIP = local.slice(0, s);
|
|
||||||
let localPort = local.slice(s - local.length + 1);
|
|
||||||
const singe: LocalPort = {
|
|
||||||
protocol: cols[0],
|
|
||||||
ip: localIP,
|
|
||||||
port: localPort
|
|
||||||
}
|
|
||||||
return singe;
|
|
||||||
})
|
|
||||||
|
|
||||||
} else if (process.platform === 'linux') {
|
|
||||||
ports = stdout.split('\n')
|
|
||||||
.filter(f =>
|
|
||||||
f.indexOf('tcp') !== -1||
|
|
||||||
f.indexOf('tcp6') !== -1||
|
|
||||||
f.indexOf('udp') !== -1 ||
|
|
||||||
f.indexOf('udp6') !== -1
|
|
||||||
).map(m => {
|
|
||||||
const cols = m.split(' ')
|
|
||||||
.filter(f => f != '')
|
|
||||||
const local = cols[3]
|
|
||||||
const s = local.lastIndexOf(":")
|
|
||||||
let localIP = local.slice(0, s);
|
|
||||||
let localPort = local.slice(s - local.length + 1);
|
|
||||||
const singe: LocalPort = {
|
|
||||||
protocol: cols[0],
|
|
||||||
ip: localIP,
|
|
||||||
port: localPort
|
|
||||||
}
|
|
||||||
return singe;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ports.sort((a, b) => a.port - b.port);
|
|
||||||
|
|
||||||
event.reply("local.getLocalPorts.hook", {
|
|
||||||
data: ports
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
import { ipcMain } from "electron";
|
|
||||||
import {
|
|
||||||
deleteProxyById,
|
|
||||||
getProxyById,
|
|
||||||
insertProxy,
|
|
||||||
listProxy,
|
|
||||||
updateProxyById,
|
|
||||||
updateProxyStatus
|
|
||||||
} from "../storage/proxy";
|
|
||||||
import { reloadFrpcProcess } from "./frpc";
|
|
||||||
import { logError, logInfo, LogModule, logWarn } from "../utils/log";
|
|
||||||
export const initProxyApi = () => {
|
|
||||||
ipcMain.on("proxy.getProxys", async (event, args) => {
|
|
||||||
logInfo(LogModule.APP, "Requesting to get proxies.");
|
|
||||||
listProxy((err, documents) => {
|
|
||||||
if (err) {
|
|
||||||
logError(LogModule.APP, `Error retrieving proxies: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
logInfo(LogModule.APP, "Proxies retrieved successfully.");
|
|
||||||
}
|
|
||||||
event.reply("Proxy.getProxys.hook", {
|
|
||||||
err: err,
|
|
||||||
data: documents
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on("proxy.insertProxy", async (event, args) => {
|
|
||||||
delete args["_id"];
|
|
||||||
logInfo(LogModule.APP, "Inserting a new proxy.");
|
|
||||||
insertProxy(args, (err, documents) => {
|
|
||||||
if (err) {
|
|
||||||
logError(LogModule.APP, `Error inserting proxy: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
logInfo(LogModule.APP, "Proxy inserted successfully.");
|
|
||||||
reloadFrpcProcess();
|
|
||||||
}
|
|
||||||
event.reply("Proxy.insertProxy.hook", {
|
|
||||||
err: err,
|
|
||||||
data: documents
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on("proxy.deleteProxyById", async (event, args) => {
|
|
||||||
logInfo(LogModule.APP, `Deleting proxy with ID: ${args._id}`);
|
|
||||||
deleteProxyById(args, (err, documents) => {
|
|
||||||
if (err) {
|
|
||||||
logError(LogModule.APP, `Error deleting proxy: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
logInfo(LogModule.APP, "Proxy deleted successfully.");
|
|
||||||
reloadFrpcProcess();
|
|
||||||
}
|
|
||||||
event.reply("Proxy.deleteProxyById.hook", {
|
|
||||||
err: err,
|
|
||||||
data: documents
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on("proxy.getProxyById", async (event, args) => {
|
|
||||||
logInfo(LogModule.APP, `Requesting proxy with ID: ${args._id}`);
|
|
||||||
getProxyById(args, (err, documents) => {
|
|
||||||
if (err) {
|
|
||||||
logError(LogModule.APP, `Error retrieving proxy: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
logInfo(LogModule.APP, "Proxy retrieved successfully.");
|
|
||||||
}
|
|
||||||
event.reply("Proxy.getProxyById.hook", {
|
|
||||||
err: err,
|
|
||||||
data: documents
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on("proxy.updateProxy", async (event, args) => {
|
|
||||||
if (!args._id) {
|
|
||||||
logWarn(LogModule.APP, "No proxy ID provided for update.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
logInfo(LogModule.APP, `Updating proxy with ID: ${args._id}`);
|
|
||||||
updateProxyById(args, (err, documents) => {
|
|
||||||
if (err) {
|
|
||||||
logError(LogModule.APP, `Error updating proxy: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
logInfo(LogModule.APP, "Proxy updated successfully.");
|
|
||||||
reloadFrpcProcess();
|
|
||||||
}
|
|
||||||
event.reply("Proxy.updateProxy.hook", {
|
|
||||||
err: err,
|
|
||||||
data: documents
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcMain.on("proxy.updateProxyStatus", async (event, args) => {
|
|
||||||
logInfo(LogModule.APP, `Updating status for proxy ID: ${args._id}`);
|
|
||||||
if (!args._id) {
|
|
||||||
logWarn(LogModule.APP, "No proxy ID provided for status update.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateProxyStatus(args._id, args.status, (err, documents) => {
|
|
||||||
if (err) {
|
|
||||||
logError(LogModule.APP, `Error updating proxy status: ${err.message}`);
|
|
||||||
} else {
|
|
||||||
logInfo(LogModule.APP, "Proxy status updated successfully.");
|
|
||||||
reloadFrpcProcess();
|
|
||||||
}
|
|
||||||
event.reply("Proxy.updateProxyStatus.hook", {
|
|
||||||
err: err,
|
|
||||||
data: documents
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,5 +1,17 @@
|
|||||||
import BaseController from "./BaseController";
|
import BaseController from "./BaseController";
|
||||||
|
import FrpcProcessService from "../service/FrpcProcessService";
|
||||||
|
|
||||||
class LaunchController extends BaseController {
|
class LaunchController extends BaseController {
|
||||||
|
private readonly _frpcProcessService: FrpcProcessService;
|
||||||
|
|
||||||
|
constructor(frpcProcessService: FrpcProcessService) {
|
||||||
|
super();
|
||||||
|
this._frpcProcessService = frpcProcessService;
|
||||||
|
}
|
||||||
|
|
||||||
|
launch(req: ControllerParam) {
|
||||||
|
this._frpcProcessService.startFrpcProcess().then(r => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default LaunchController;
|
@ -1,7 +1,53 @@
|
|||||||
import BaseController from "./BaseController";
|
import BaseController from "./BaseController";
|
||||||
|
import ProxyService from "../service/ProxyService";
|
||||||
|
import { success } from "../utils/response";
|
||||||
|
import ProxyDao from "../dao/ProxyDao";
|
||||||
|
|
||||||
class ProxyController extends BaseController {
|
class ProxyController extends BaseController {
|
||||||
constructor() {
|
private readonly _proxyService: ProxyService;
|
||||||
|
private readonly _proxyDao: ProxyDao;
|
||||||
|
|
||||||
|
constructor(proxyService: ProxyService, proxyDao: ProxyDao) {
|
||||||
super();
|
super();
|
||||||
|
this._proxyService = proxyService;
|
||||||
|
this._proxyDao = proxyDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
createProxy(req: ControllerParam) {
|
||||||
|
this._proxyService.insertProxy(req.args).then(data => {
|
||||||
|
req.event.reply(req.channel, success(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyProxy(req: ControllerParam) {
|
||||||
|
this._proxyService.updateProxy(req.args).then(data => {
|
||||||
|
req.event.reply(req.channel, success(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllProxies(req: ControllerParam) {
|
||||||
|
this._proxyDao.findAll().then(data => {
|
||||||
|
req.event.reply(req.channel, success(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteProxy(req: ControllerParam) {
|
||||||
|
this._proxyService.deleteProxy(req.args).then(data => {
|
||||||
|
req.event.reply(req.channel, success(data));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyProxyStatus(req: ControllerParam) {
|
||||||
|
this._proxyDao.updateProxyStatus(req.args.id, req.args.status).then(() => {
|
||||||
|
req.event.reply(req.channel, success());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getLocalPorts(req: ControllerParam) {
|
||||||
|
this._proxyService.getLocalPorts().then(data => {
|
||||||
|
req.event.reply(req.channel, success(data));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default ProxyController;
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
import BaseController from "./BaseController";
|
import BaseController from "./BaseController";
|
||||||
import ServerService from "../service/ServerService";
|
import ServerService from "../service/ServerService";
|
||||||
import { success } from "../utils/response";
|
import { success } from "../utils/response";
|
||||||
|
import FileService from "../service/FileService";
|
||||||
|
import PathUtils from "../utils/PathUtils";
|
||||||
|
|
||||||
class ServerController extends BaseController {
|
class ServerController extends BaseController {
|
||||||
private readonly _serverService: ServerService;
|
private readonly _serverService: ServerService;
|
||||||
|
private readonly _fileService: FileService;
|
||||||
|
|
||||||
constructor(serverService: ServerService) {
|
constructor(serverService: ServerService, fileService: FileService) {
|
||||||
super();
|
super();
|
||||||
this._serverService = serverService;
|
this._serverService = serverService;
|
||||||
|
this._fileService = fileService;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfig(req: ControllerParam) {
|
saveConfig(req: ControllerParam) {
|
||||||
this._serverService.saveServerConfig(req.args).then(() => {
|
this._serverService.saveServerConfig(req.args).then(() => {
|
||||||
req.event.reply(req.channel, success());
|
req.event.reply(req.channel, success());
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getServerConfig(req: ControllerParam) {
|
getServerConfig(req: ControllerParam) {
|
||||||
@ -21,7 +25,12 @@ class ServerController extends BaseController {
|
|||||||
this._serverService.getServerConfig().then(data => {
|
this._serverService.getServerConfig().then(data => {
|
||||||
req.event.reply(req.channel, success(data));
|
req.event.reply(req.channel, success(data));
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openAppData(req: ControllerParam) {
|
||||||
|
this._fileService.openLocalPath(PathUtils.getAppData()).then(data => {
|
||||||
|
req.event.reply(req.channel, success(data));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,10 @@ class VersionController extends BaseController {
|
|||||||
req.event.reply(req.channel, fail());
|
req.event.reply(req.channel, fail());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
importLocalFrpcVersion (){
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default VersionController;
|
export default VersionController;
|
||||||
|
@ -9,6 +9,11 @@ import VersionController from "../controller/VersionController";
|
|||||||
import FileService from "../service/FileService";
|
import FileService from "../service/FileService";
|
||||||
import VersionDao from "../dao/VersionDao";
|
import VersionDao from "../dao/VersionDao";
|
||||||
import GitHubService from "../service/GitHubService";
|
import GitHubService from "../service/GitHubService";
|
||||||
|
import FrpcProcessService from "../service/FrpcProcessService";
|
||||||
|
import LaunchController from "../controller/LaunchController";
|
||||||
|
import ProxyDao from "../dao/ProxyDao";
|
||||||
|
import ProxyService from "../service/ProxyService";
|
||||||
|
import ProxyController from "../controller/ProxyController";
|
||||||
|
|
||||||
export const ipcRouters: IpcRouters = {
|
export const ipcRouters: IpcRouters = {
|
||||||
SERVER: {
|
SERVER: {
|
||||||
@ -48,6 +53,38 @@ export const ipcRouters: IpcRouters = {
|
|||||||
path: "version/deleteDownloadedVersion",
|
path: "version/deleteDownloadedVersion",
|
||||||
controller: "versionController.deleteDownloadedVersion"
|
controller: "versionController.deleteDownloadedVersion"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
LAUNCH: {
|
||||||
|
launch: {
|
||||||
|
path: "launch/launch",
|
||||||
|
controller: "launchController.launch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PROXY: {
|
||||||
|
createProxy: {
|
||||||
|
path: "proxy/createProxy",
|
||||||
|
controller: "proxyController.createProxy"
|
||||||
|
},
|
||||||
|
modifyProxy: {
|
||||||
|
path: "proxy/modifyProxy",
|
||||||
|
controller: "proxyController.modifyProxy"
|
||||||
|
},
|
||||||
|
deleteProxy: {
|
||||||
|
path: "proxy/deleteProxy",
|
||||||
|
controller: "proxyController.deleteProxy"
|
||||||
|
},
|
||||||
|
getAllProxies: {
|
||||||
|
path: "proxy/getAllProxies",
|
||||||
|
controller: "proxyController.getAllProxies"
|
||||||
|
},
|
||||||
|
modifyProxyStatus: {
|
||||||
|
path: "proxy/modifyProxyStatus",
|
||||||
|
controller: "proxyController.modifyProxyStatus"
|
||||||
|
},
|
||||||
|
getLocalPorts: {
|
||||||
|
path: "proxy/getLocalPorts",
|
||||||
|
controller: "proxyController.getLocalPorts"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,8 +107,9 @@ class IpcRouterConfigurate {
|
|||||||
private initializeBeans() {
|
private initializeBeans() {
|
||||||
const serverDao = new ServerDao();
|
const serverDao = new ServerDao();
|
||||||
const versionDao = new VersionDao();
|
const versionDao = new VersionDao();
|
||||||
|
const proxyDao = new ProxyDao();
|
||||||
const fileService = new FileService();
|
const fileService = new FileService();
|
||||||
const serverService = new ServerService(serverDao);
|
const serverService = new ServerService(serverDao, proxyDao);
|
||||||
const gitHubService = new GitHubService();
|
const gitHubService = new GitHubService();
|
||||||
const versionService = new VersionService(
|
const versionService = new VersionService(
|
||||||
versionDao,
|
versionDao,
|
||||||
@ -79,19 +117,31 @@ class IpcRouterConfigurate {
|
|||||||
gitHubService
|
gitHubService
|
||||||
);
|
);
|
||||||
const logService = new LogService(fileService);
|
const logService = new LogService(fileService);
|
||||||
const serverController = new ServerController(serverService);
|
const frpcProcessService = new FrpcProcessService(
|
||||||
|
serverService,
|
||||||
|
versionDao
|
||||||
|
);
|
||||||
|
const proxyService = new ProxyService(proxyDao);
|
||||||
|
const serverController = new ServerController(serverService, fileService);
|
||||||
const versionController = new VersionController(versionService, versionDao);
|
const versionController = new VersionController(versionService, versionDao);
|
||||||
const logController = new LogController(logService);
|
const logController = new LogController(logService);
|
||||||
|
const launchController = new LaunchController(frpcProcessService);
|
||||||
|
const proxyController = new ProxyController(proxyService, proxyDao);
|
||||||
|
|
||||||
this._beans.set("serverDao", serverDao);
|
this._beans.set("serverDao", serverDao);
|
||||||
this._beans.set("versionDao", versionDao);
|
this._beans.set("versionDao", versionDao);
|
||||||
|
this._beans.set("proxyDao", proxyDao);
|
||||||
this._beans.set("fileService", fileService);
|
this._beans.set("fileService", fileService);
|
||||||
this._beans.set("serverService", serverService);
|
this._beans.set("serverService", serverService);
|
||||||
this._beans.set("versionService", versionService);
|
this._beans.set("versionService", versionService);
|
||||||
this._beans.set("logService", logService);
|
this._beans.set("logService", logService);
|
||||||
|
this._beans.set("proxyService", proxyService);
|
||||||
|
this._beans.set("frpcProcessService", frpcProcessService);
|
||||||
this._beans.set("serverController", serverController);
|
this._beans.set("serverController", serverController);
|
||||||
this._beans.set("versionController", versionController);
|
this._beans.set("versionController", versionController);
|
||||||
this._beans.set("logController", logController);
|
this._beans.set("logController", logController);
|
||||||
|
this._beans.set("launchController", launchController);
|
||||||
|
this._beans.set("proxyController", proxyController);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
26
electron/dao/ProxyDao.ts
Normal file
26
electron/dao/ProxyDao.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import BaseDao from "./BaseDao";
|
||||||
|
|
||||||
|
class ProxyDao extends BaseDao<FrpcProxy> {
|
||||||
|
constructor() {
|
||||||
|
super("proxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProxyStatus(id: string, status: number): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
this.db.update(
|
||||||
|
{ _id: id },
|
||||||
|
{ $set: { status: status } },
|
||||||
|
{},
|
||||||
|
(err, numberOfUpdated, upsert) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProxyDao;
|
@ -12,7 +12,6 @@ import { release } from "node:os";
|
|||||||
import node_path, { join } from "node:path";
|
import node_path, { join } from "node:path";
|
||||||
import { initGitHubApi } from "../api/github";
|
import { initGitHubApi } from "../api/github";
|
||||||
import { initConfigApi } from "../api/config";
|
import { initConfigApi } from "../api/config";
|
||||||
import { initProxyApi } from "../api/proxy";
|
|
||||||
import {
|
import {
|
||||||
initFrpcApi,
|
initFrpcApi,
|
||||||
startFrpWorkerProcess,
|
startFrpWorkerProcess,
|
||||||
@ -21,7 +20,6 @@ import {
|
|||||||
import { initFileApi } from "../api/file";
|
import { initFileApi } from "../api/file";
|
||||||
import { getConfig } from "../storage/config";
|
import { getConfig } from "../storage/config";
|
||||||
import { initCommonApi } from "../api/common";
|
import { initCommonApi } from "../api/common";
|
||||||
import { initLocalApi } from "../api/local";
|
|
||||||
import { initLog, logError, logInfo, LogModule } from "../utils/log";
|
import { initLog, logError, logInfo, LogModule } from "../utils/log";
|
||||||
import { maskSensitiveData } from "../utils/desensitize";
|
import { maskSensitiveData } from "../utils/desensitize";
|
||||||
import IpcRouterConfigurate from "../core/IpcRouter";
|
import IpcRouterConfigurate from "../core/IpcRouter";
|
||||||
@ -201,8 +199,6 @@ app.whenReady().then(() => {
|
|||||||
initConfigApi(win);
|
initConfigApi(win);
|
||||||
logInfo(LogModule.APP, `Config API initialized.`);
|
logInfo(LogModule.APP, `Config API initialized.`);
|
||||||
|
|
||||||
initProxyApi();
|
|
||||||
logInfo(LogModule.APP, `Proxy API initialized.`);
|
|
||||||
|
|
||||||
initFrpcApi();
|
initFrpcApi();
|
||||||
logInfo(LogModule.APP, `FRPC API initialized.`);
|
logInfo(LogModule.APP, `FRPC API initialized.`);
|
||||||
@ -215,8 +211,6 @@ app.whenReady().then(() => {
|
|||||||
initCommonApi();
|
initCommonApi();
|
||||||
logInfo(LogModule.APP, `Common API initialized.`);
|
logInfo(LogModule.APP, `Common API initialized.`);
|
||||||
|
|
||||||
initLocalApi();
|
|
||||||
logInfo(LogModule.APP, `Local API initialized.`);
|
|
||||||
|
|
||||||
// initUpdaterApi(win);
|
// initUpdaterApi(win);
|
||||||
logInfo(LogModule.APP, `Updater API initialization skipped.`);
|
logInfo(LogModule.APP, `Updater API initialization skipped.`);
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { shell } from "electron";
|
import { dialog, shell } from "electron";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import zlib from "zlib";
|
import zlib from "zlib";
|
||||||
import admZip from "adm-zip";
|
import admZip from "adm-zip";
|
||||||
import GlobalConstant from "../core/GlobalConstant";
|
import GlobalConstant from "../core/GlobalConstant";
|
||||||
|
|
||||||
|
|
||||||
// import tar from "tar";
|
// import tar from "tar";
|
||||||
const tar = require("tar");
|
const tar = require("tar");
|
||||||
|
|
||||||
@ -28,6 +29,18 @@ class FileService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openLocalPath(path: string) {
|
||||||
|
return new Promise<boolean>((resolve, reject) => {
|
||||||
|
shell.openPath(path).then(errorMessage => {
|
||||||
|
if (errorMessage) {
|
||||||
|
resolve(false);
|
||||||
|
} else {
|
||||||
|
reject(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
decompressZipFile(zipFilePath: string, targetPath: string) {
|
decompressZipFile(zipFilePath: string, targetPath: string) {
|
||||||
if (!zipFilePath.endsWith(GlobalConstant.ZIP_EXT)) {
|
if (!zipFilePath.endsWith(GlobalConstant.ZIP_EXT)) {
|
||||||
throw new Error("The file is not a .zip file");
|
throw new Error("The file is not a .zip file");
|
||||||
@ -86,6 +99,18 @@ class FileService {
|
|||||||
// );
|
// );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectLocalFile(name: string, path: any) {
|
||||||
|
dialog.showOpenDialogSync({
|
||||||
|
properties: ["openFile"],
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
extensions: path
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FileService;
|
export default FileService;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import ServerService from "./ServerService";
|
import ServerService from "./ServerService";
|
||||||
import VersionDao from "../dao/VersionDao";
|
import VersionDao from "../dao/VersionDao";
|
||||||
import PathUtils from "../utils/PathUtils";
|
import PathUtils from "../utils/PathUtils";
|
||||||
import { frpcProcess } from "../api/frpc";
|
|
||||||
import GlobalConstant from "../core/GlobalConstant";
|
import GlobalConstant from "../core/GlobalConstant";
|
||||||
import { Notification } from "electron";
|
import { Notification } from "electron";
|
||||||
|
import { logDebug, LogModule } from "../utils/log";
|
||||||
|
|
||||||
const { exec, spawn } = require("child_process");
|
const { exec, spawn } = require("child_process");
|
||||||
|
|
||||||
class FrpProcessService {
|
class FrpcProcessService {
|
||||||
private readonly _serverService: ServerService;
|
private readonly _serverService: ServerService;
|
||||||
private readonly _versionDao: VersionDao;
|
private readonly _versionDao: VersionDao;
|
||||||
private _frpcProcess: any;
|
private _frpcProcess: any;
|
||||||
@ -28,6 +28,7 @@ class FrpProcessService {
|
|||||||
config.frpcVersion
|
config.frpcVersion
|
||||||
);
|
);
|
||||||
// todo genConfigfile.
|
// todo genConfigfile.
|
||||||
|
await this._serverService.genTomlConfig();
|
||||||
const configPath = "";
|
const configPath = "";
|
||||||
const command = `${PathUtils.getFrpcFilename()} -c ${configPath}`;
|
const command = `${PathUtils.getFrpcFilename()} -c ${configPath}`;
|
||||||
this._frpcProcess = spawn(command, {
|
this._frpcProcess = spawn(command, {
|
||||||
@ -35,11 +36,11 @@ class FrpProcessService {
|
|||||||
shell: true
|
shell: true
|
||||||
});
|
});
|
||||||
|
|
||||||
frpcProcess.stdout.on("data", data => {
|
this._frpcProcess.stdout.on("data", data => {
|
||||||
// logDebug(LogModule.FRP_CLIENT, `Frpc process output: ${data}`);
|
logDebug(LogModule.FRP_CLIENT, `Frpc process output: ${data}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
frpcProcess.stdout.on("error", data => {
|
this._frpcProcess.stdout.on("error", data => {
|
||||||
// logError(LogModule.FRP_CLIENT, `Frpc process error: ${data}`);
|
// logError(LogModule.FRP_CLIENT, `Frpc process error: ${data}`);
|
||||||
// stopFrpcProcess(() => {});
|
// stopFrpcProcess(() => {});
|
||||||
this.stopFrpcProcess();
|
this.stopFrpcProcess();
|
||||||
@ -71,4 +72,4 @@ class FrpProcessService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FrpProcessService;
|
export default FrpcProcessService;
|
132
electron/service/ProxyService.ts
Normal file
132
electron/service/ProxyService.ts
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import ProxyDao from "../dao/ProxyDao";
|
||||||
|
|
||||||
|
const { exec, spawn } = require("child_process");
|
||||||
|
|
||||||
|
class ProxyService {
|
||||||
|
private readonly _proxyDao: ProxyDao;
|
||||||
|
|
||||||
|
constructor(proxyDao: ProxyDao) {
|
||||||
|
this._proxyDao = proxyDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
async insertProxy(proxy: FrpcProxy) {
|
||||||
|
return await this._proxyDao.insert(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateProxy(proxy: FrpcProxy) {
|
||||||
|
return await this._proxyDao.updateById(proxy._id, proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteProxy(proxyId: string) {
|
||||||
|
return await this._proxyDao.deleteById(proxyId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getLocalPorts(): Promise<Array<LocalPort>> {
|
||||||
|
const command =
|
||||||
|
process.platform === "win32"
|
||||||
|
? "netstat -a -n"
|
||||||
|
: "netstat -an | grep LISTEN";
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(command, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
if (stderr) {
|
||||||
|
reject(stderr);
|
||||||
|
}
|
||||||
|
let ports: Array<LocalPort> = [];
|
||||||
|
if (stdout) {
|
||||||
|
if (process.platform === "win32") {
|
||||||
|
// window
|
||||||
|
ports = stdout
|
||||||
|
.split("\r\n")
|
||||||
|
.filter(f => f.indexOf("TCP") !== -1 || f.indexOf("UDP") !== -1)
|
||||||
|
.map(m => {
|
||||||
|
const cols = m.split(" ").filter(f => f != "");
|
||||||
|
const local = cols[1];
|
||||||
|
const s = local.lastIndexOf(":");
|
||||||
|
let localIP = local.slice(0, s);
|
||||||
|
let localPort = local.slice(s - local.length + 1);
|
||||||
|
const singe: LocalPort = {
|
||||||
|
protocol: cols[0],
|
||||||
|
ip: localIP,
|
||||||
|
port: localPort
|
||||||
|
};
|
||||||
|
|
||||||
|
return singe;
|
||||||
|
});
|
||||||
|
} else if (process.platform === "darwin") {
|
||||||
|
// mac
|
||||||
|
ports = stdout
|
||||||
|
.split("\n")
|
||||||
|
.filter(m => {
|
||||||
|
const cols = m.split(" ").filter(f => f != "");
|
||||||
|
const local = cols[3];
|
||||||
|
return local;
|
||||||
|
})
|
||||||
|
.map(m => {
|
||||||
|
const cols = m.split(" ").filter(f => f != "");
|
||||||
|
const local = cols[3];
|
||||||
|
const s = local.lastIndexOf(".");
|
||||||
|
let localIP = local.slice(0, s);
|
||||||
|
let localPort = local.slice(s - local.length + 1);
|
||||||
|
const singe: LocalPort = {
|
||||||
|
protocol: cols[0],
|
||||||
|
ip: localIP,
|
||||||
|
port: localPort
|
||||||
|
};
|
||||||
|
return singe;
|
||||||
|
});
|
||||||
|
} else if (process.platform === "linux") {
|
||||||
|
ports = stdout
|
||||||
|
.split("\n")
|
||||||
|
.filter(
|
||||||
|
f =>
|
||||||
|
f.indexOf("tcp") !== -1 ||
|
||||||
|
f.indexOf("tcp6") !== -1 ||
|
||||||
|
f.indexOf("udp") !== -1 ||
|
||||||
|
f.indexOf("udp6") !== -1
|
||||||
|
)
|
||||||
|
.map(m => {
|
||||||
|
const cols = m.split(" ").filter(f => f != "");
|
||||||
|
const local = cols[3];
|
||||||
|
const s = local.lastIndexOf(":");
|
||||||
|
let localIP = local.slice(0, s);
|
||||||
|
let localPort = local.slice(s - local.length + 1);
|
||||||
|
const singe: LocalPort = {
|
||||||
|
protocol: cols[0],
|
||||||
|
ip: localIP,
|
||||||
|
port: localPort
|
||||||
|
};
|
||||||
|
return singe;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ports.sort((a, b) => a.port - b.port);
|
||||||
|
|
||||||
|
resolve(ports);
|
||||||
|
});
|
||||||
|
// exec(command, (error, stdout, stderr) => {
|
||||||
|
// if (error) {
|
||||||
|
// logError(LogModule.APP, `getLocalPorts - error: ${error.message}`);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (stderr) {
|
||||||
|
// logWarn(LogModule.APP, `getLocalPorts - stderr: ${stderr}`);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// logDebug(LogModule.APP, `Command output: ${stdout}`);
|
||||||
|
// let ports = [];
|
||||||
|
|
||||||
|
//
|
||||||
|
// event.reply("local.getLocalPorts.hook", {
|
||||||
|
// data: ports
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProxyService;
|
@ -1,33 +1,68 @@
|
|||||||
import BaseService from "./BaseService";
|
import BaseService from "./BaseService";
|
||||||
import ServerDao from "../dao/ServerDao";
|
import ServerDao from "../dao/ServerDao";
|
||||||
|
import TOML from "smol-toml";
|
||||||
|
import fs from "fs";
|
||||||
|
import PathUtils from "../utils/PathUtils";
|
||||||
|
import ProxyDao from "../dao/ProxyDao";
|
||||||
|
|
||||||
class ServerService extends BaseService<FrpcDesktopServer> {
|
class ServerService extends BaseService<FrpcDesktopServer> {
|
||||||
private readonly _serverDao: ServerDao;
|
private readonly _serverDao: ServerDao;
|
||||||
constructor(serverDao: ServerDao) {
|
private readonly _proxyDao: ProxyDao;
|
||||||
|
private readonly _serverId: string = "1";
|
||||||
|
|
||||||
|
constructor(serverDao: ServerDao, proxyDao: ProxyDao) {
|
||||||
super();
|
super();
|
||||||
this._serverDao = serverDao;
|
this._serverDao = serverDao;
|
||||||
|
this._proxyDao = proxyDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveServerConfig(
|
async saveServerConfig(
|
||||||
frpcServer: FrpcDesktopServer
|
frpcServer: FrpcDesktopServer
|
||||||
): Promise<FrpcDesktopServer> {
|
): Promise<FrpcDesktopServer> {
|
||||||
return await this._serverDao.updateById("1", frpcServer);
|
frpcServer._id = this._serverId;
|
||||||
|
return await this._serverDao.updateById(this._serverId, frpcServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getServerConfig(): Promise<FrpcDesktopServer> {
|
async getServerConfig(): Promise<FrpcDesktopServer> {
|
||||||
return await this._serverDao.findById("1");
|
return await this._serverDao.findById(this._serverId);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasServerConfig(): Promise<boolean> {
|
hasServerConfig(): Promise<boolean> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._serverDao
|
this._serverDao
|
||||||
.exists("1")
|
.exists(this._serverId)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
resolve(r);
|
resolve(r);
|
||||||
})
|
})
|
||||||
.catch(err => reject(err));
|
.catch(err => reject(err));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async genTomlConfig() {
|
||||||
|
const server = await this.getServerConfig();
|
||||||
|
const proxies = await this._proxyDao.findAll();
|
||||||
|
const enabledProxies = proxies
|
||||||
|
.filter(f => f.status === 1)
|
||||||
|
.map(proxy => {
|
||||||
|
const { _id, status, ...frpProxyConfig } = proxy;
|
||||||
|
return frpProxyConfig
|
||||||
|
});
|
||||||
|
const { frpcVersion, _id, system, ...commonConfig } = server;
|
||||||
|
const frpcConfig = { ...commonConfig };
|
||||||
|
frpcConfig.log.to = PathUtils.getFrpcLogFilePath();
|
||||||
|
const toml = TOML.stringify({ ...frpcConfig, enabledProxies });
|
||||||
|
fs.writeFile(
|
||||||
|
PathUtils.getTomlConfigFilePath(), // 配置文件目录
|
||||||
|
toml, // 配置文件内容
|
||||||
|
{ flag: "w" },
|
||||||
|
err => {
|
||||||
|
if (err) {
|
||||||
|
} else {
|
||||||
|
// callback(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ServerService;
|
export default ServerService;
|
||||||
|
@ -4,20 +4,21 @@ import GitHubService from "./GitHubService";
|
|||||||
import FileService from "./FileService";
|
import FileService from "./FileService";
|
||||||
import frpReleasesJson from "../json/frp-releases.json";
|
import frpReleasesJson from "../json/frp-releases.json";
|
||||||
import { download } from "electron-dl";
|
import { download } from "electron-dl";
|
||||||
import { BrowserWindow } from "electron";
|
import { BrowserWindow, dialog } from "electron";
|
||||||
import GlobalConstant from "../core/GlobalConstant";
|
import GlobalConstant from "../core/GlobalConstant";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import SecureUtils from "../utils/SecureUtils";
|
import SecureUtils from "../utils/SecureUtils";
|
||||||
import PathUtils from "../utils/PathUtils";
|
import PathUtils from "../utils/PathUtils";
|
||||||
import FileUtils from "../utils/FileUtils";
|
import FileUtils from "../utils/FileUtils";
|
||||||
|
import frpChecksums from "../json/frp_all_sha256_checksums.json";
|
||||||
|
|
||||||
class VersionService extends BaseService<FrpcVersion> {
|
class VersionService extends BaseService<FrpcVersion> {
|
||||||
private readonly _versionDao: VersionDao;
|
private readonly _versionDao: VersionDao;
|
||||||
private readonly _fileService: FileService;
|
private readonly _fileService: FileService;
|
||||||
private readonly _gitHubService: GitHubService;
|
private readonly _gitHubService: GitHubService;
|
||||||
private readonly _currFrpArch: Array<string>;
|
private readonly _currFrpArch: Array<string>;
|
||||||
private versions: Array<FrpcVersion> = [];
|
private _versions: Array<FrpcVersion> = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
versionDao: VersionDao,
|
versionDao: VersionDao,
|
||||||
@ -34,7 +35,7 @@ class VersionService extends BaseService<FrpcVersion> {
|
|||||||
|
|
||||||
downloadFrpVersion(githubReleaseId: number, onProgress: Function) {
|
downloadFrpVersion(githubReleaseId: number, onProgress: Function) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const version = this.versions.find(
|
const version = this._versions.find(
|
||||||
f => f.githubReleaseId === githubReleaseId
|
f => f.githubReleaseId === githubReleaseId
|
||||||
);
|
);
|
||||||
if (!version) {
|
if (!version) {
|
||||||
@ -133,8 +134,8 @@ class VersionService extends BaseService<FrpcVersion> {
|
|||||||
.then(async (releases: Array<GithubRelease>) => {
|
.then(async (releases: Array<GithubRelease>) => {
|
||||||
const versions: Array<FrpcVersion> =
|
const versions: Array<FrpcVersion> =
|
||||||
await this.githubRelease2FrpcVersion(releases);
|
await this.githubRelease2FrpcVersion(releases);
|
||||||
// const versions: Array<FrpcVersion> = (this.versions = versions);
|
// const _versions: Array<FrpcVersion> = (this._versions = _versions);
|
||||||
this.versions = versions;
|
this._versions = versions;
|
||||||
resolve(versions);
|
resolve(versions);
|
||||||
})
|
})
|
||||||
.catch(err => reject(err));
|
.catch(err => reject(err));
|
||||||
@ -158,6 +159,10 @@ class VersionService extends BaseService<FrpcVersion> {
|
|||||||
): Promise<Array<FrpcVersion>> {
|
): Promise<Array<FrpcVersion>> {
|
||||||
const allVersions = await this._versionDao.findAll();
|
const allVersions = await this._versionDao.findAll();
|
||||||
return releases
|
return releases
|
||||||
|
.filter(release => {
|
||||||
|
// only support toml version.
|
||||||
|
return release.id > 124395282;
|
||||||
|
})
|
||||||
.filter(release => {
|
.filter(release => {
|
||||||
return this.findCurrentArchitectureAsset(release.assets);
|
return this.findCurrentArchitectureAsset(release.assets);
|
||||||
})
|
})
|
||||||
@ -197,6 +202,31 @@ class VersionService extends BaseService<FrpcVersion> {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async importLocalFrpcVersion(win: BrowserWindow) {
|
||||||
|
const result = await dialog.showOpenDialog(win, {
|
||||||
|
properties: ["openFile"],
|
||||||
|
filters: [
|
||||||
|
{ name: "Frpc", extensions: ["tar.gz", "zip"] } // 允许选择的文件类型,分开后缀以确保可以选择
|
||||||
|
]
|
||||||
|
});
|
||||||
|
if (result.canceled) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const filePath = result.filePaths[0];
|
||||||
|
const checksum = FileUtils.calculateFileChecksum(filePath);
|
||||||
|
const frpName = frpChecksums[checksum];
|
||||||
|
if (frpName) {
|
||||||
|
if (this._currFrpArch.every(item => frpName.includes(item))) {
|
||||||
|
const version = this.getFrpVersionByAssetName(frpName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFrpVersionByAssetName(assetName: string) {
|
||||||
|
return this._versions.find(f => f.assetName === assetName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default VersionService;
|
export default VersionService;
|
||||||
|
@ -18,6 +18,12 @@ class FileUtils {
|
|||||||
hash.update(fileBuffer);
|
hash.update(fileBuffer);
|
||||||
return hash.digest("hex");
|
return hash.digest("hex");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static mkdir(path: string) {
|
||||||
|
if (!fs.existsSync(path)) {
|
||||||
|
fs.mkdirSync(path, { recursive: true, mode: 0o777 });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default FileUtils;
|
export default FileUtils;
|
||||||
|
@ -2,29 +2,61 @@ import SecureUtils from "./SecureUtils";
|
|||||||
|
|
||||||
import { app } from "electron";
|
import { app } from "electron";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import FileUtils from "./FileUtils";
|
||||||
|
|
||||||
class PathUtils {
|
class PathUtils {
|
||||||
public static getDownloadStoragePath() {
|
public static getDownloadStoragePath() {
|
||||||
return path.join(
|
const result = path.join(PathUtils.getAppData(), "download");
|
||||||
PathUtils.getAppData(),
|
FileUtils.mkdir(result);
|
||||||
SecureUtils.calculateMD5("download")
|
return result;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getVersionStoragePath() {
|
public static getVersionStoragePath() {
|
||||||
return path.join(
|
const result = path.join(
|
||||||
PathUtils.getAppData(),
|
PathUtils.getAppData(),
|
||||||
SecureUtils.calculateMD5("frpc")
|
SecureUtils.calculateMD5("frpc")
|
||||||
);
|
);
|
||||||
|
FileUtils.mkdir(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getConfigStoragePath() {
|
||||||
|
const result = path.join(
|
||||||
|
PathUtils.getAppData(),
|
||||||
|
// SecureUtils.calculateMD5("config")
|
||||||
|
"config"
|
||||||
|
);
|
||||||
|
FileUtils.mkdir(result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getFrpcFilename() {
|
public static getFrpcFilename() {
|
||||||
return SecureUtils.calculateMD5("frpc")
|
return SecureUtils.calculateMD5("frpc");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getAppData() {
|
public static getAppData() {
|
||||||
return app.getPath("userData");
|
return app.getPath("userData");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static getTomlConfigFilePath() {
|
||||||
|
return path.join(
|
||||||
|
PathUtils.getConfigStoragePath(),
|
||||||
|
SecureUtils.calculateMD5("frpc") + ".toml"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getFrpcLogStoragePath() {
|
||||||
|
const result = path.join(PathUtils.getAppData(), "log");
|
||||||
|
FileUtils.mkdir(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getFrpcLogFilePath() {
|
||||||
|
return path.join(
|
||||||
|
PathUtils.getFrpcLogStoragePath(),
|
||||||
|
SecureUtils.calculateMD5("frpc-log") + ".log"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PathUtils;
|
export default PathUtils;
|
||||||
|
@ -85,6 +85,7 @@
|
|||||||
"snowflakify": "^1.0.5",
|
"snowflakify": "^1.0.5",
|
||||||
"tar": "^6.2.0",
|
"tar": "^6.2.0",
|
||||||
"unused-filename": "^4.0.1",
|
"unused-filename": "^4.0.1",
|
||||||
"uuid": "^10.0.0"
|
"uuid": "^10.0.0",
|
||||||
|
"smol-toml": "^1.3.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,15 +200,12 @@ const handleSubmit = useDebounceFn(() => {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
loading.value = 1;
|
loading.value = 1;
|
||||||
const data = clone(formData.value);
|
const data = clone(formData.value);
|
||||||
ipcRenderer.send("server/saveConfig", data);
|
send(ipcRouters.SERVER.saveConfig, data);
|
||||||
|
// ipcRenderer.send("server/saveConfig", data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
const handleLoadVersions = () => {
|
|
||||||
ipcRenderer.send("config.versions");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleAuthMethodChange = e => {
|
const handleAuthMethodChange = e => {
|
||||||
if (e === "multiuser") {
|
if (e === "multiuser") {
|
||||||
ElMessageBox.alert(
|
ElMessageBox.alert(
|
||||||
@ -242,12 +239,14 @@ const handleLoadSavedConfig = () => {
|
|||||||
send(ipcRouters.SERVER.getServerConfig);
|
send(ipcRouters.SERVER.getServerConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleLoadDownloadedVersion();
|
handleLoadDownloadedVersion();
|
||||||
handleLoadSavedConfig();
|
handleLoadSavedConfig();
|
||||||
|
|
||||||
on(ipcRouters.SERVER.getServerConfig, data => {
|
on(ipcRouters.SERVER.getServerConfig, data => {
|
||||||
console.log("data", data);
|
console.log("data", data);
|
||||||
|
formData.value = data;
|
||||||
loading.value--;
|
loading.value--;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -256,6 +255,14 @@ onMounted(() => {
|
|||||||
versions.value = data;
|
versions.value = data;
|
||||||
// checkAndResetVersion();
|
// checkAndResetVersion();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
on(ipcRouters.SERVER.saveConfig, data => {
|
||||||
|
ElMessage({
|
||||||
|
type: "success",
|
||||||
|
message: "保存成功"
|
||||||
|
});
|
||||||
|
loading.value--;
|
||||||
|
});
|
||||||
// ipcRenderer.send("config.getConfig");
|
// ipcRenderer.send("config.getConfig");
|
||||||
// handleLoadVersions();
|
// handleLoadVersions();
|
||||||
// ipcRenderer.on("Config.getConfig.hook", (event, args) => {
|
// ipcRenderer.on("Config.getConfig.hook", (event, args) => {
|
||||||
|
@ -5,6 +5,8 @@ import { ipcRenderer } from "electron";
|
|||||||
import { ElMessageBox } from "element-plus";
|
import { ElMessageBox } from "element-plus";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { useDebounceFn, useIntervalFn } from "@vueuse/core";
|
import { useDebounceFn, useIntervalFn } from "@vueuse/core";
|
||||||
|
import { send } from "@/utils/ipcUtils";
|
||||||
|
import { ipcRouters } from "../../../electron/core/IpcRouter";
|
||||||
|
|
||||||
defineComponent({
|
defineComponent({
|
||||||
name: "Home"
|
name: "Home"
|
||||||
@ -13,7 +15,8 @@ defineComponent({
|
|||||||
const running = ref(false);
|
const running = ref(false);
|
||||||
|
|
||||||
const handleStartFrpc = () => {
|
const handleStartFrpc = () => {
|
||||||
ipcRenderer.send("frpc.start");
|
// ipcRenderer.send("frpc.start");
|
||||||
|
send(ipcRouters.LAUNCH.launch);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleStopFrpc = () => {
|
const handleStopFrpc = () => {
|
||||||
|
@ -15,6 +15,8 @@ import { useClipboard, useDebounceFn } from "@vueuse/core";
|
|||||||
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
|
import IconifyIconOffline from "@/components/IconifyIcon/src/iconifyIconOffline";
|
||||||
import commonIps from "./commonIp.json";
|
import commonIps from "./commonIp.json";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import { on, removeRouterListeners, send } from "@/utils/ipcUtils";
|
||||||
|
import { ipcRouters } from "../../../electron/core/IpcRouter";
|
||||||
|
|
||||||
defineComponent({
|
defineComponent({
|
||||||
name: "Proxy"
|
name: "Proxy"
|
||||||
@ -23,7 +25,7 @@ defineComponent({
|
|||||||
/**
|
/**
|
||||||
* 代理列表
|
* 代理列表
|
||||||
*/
|
*/
|
||||||
const proxys = ref<Array<Proxy>>([]);
|
const proxys = ref<Array<FrpcProxy>>([]);
|
||||||
/**
|
/**
|
||||||
* loading
|
* loading
|
||||||
*/
|
*/
|
||||||
@ -44,11 +46,13 @@ const edit = ref({
|
|||||||
visible: false
|
visible: false
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultForm = ref<Proxy>({
|
const defaultForm: FrpcProxy = {
|
||||||
_id: "",
|
_id: "",
|
||||||
|
hostHeaderRewrite: "",
|
||||||
|
locations: [],
|
||||||
name: "",
|
name: "",
|
||||||
type: "http",
|
type: "http",
|
||||||
localIp: "",
|
localIP: "",
|
||||||
localPort: "8080",
|
localPort: "8080",
|
||||||
remotePort: "8080",
|
remotePort: "8080",
|
||||||
customDomains: [""],
|
customDomains: [""],
|
||||||
@ -57,7 +61,6 @@ const defaultForm = ref<Proxy>({
|
|||||||
secretKey: "",
|
secretKey: "",
|
||||||
bindAddr: "",
|
bindAddr: "",
|
||||||
bindPort: null,
|
bindPort: null,
|
||||||
status: true,
|
|
||||||
subdomain: "",
|
subdomain: "",
|
||||||
basicAuth: false,
|
basicAuth: false,
|
||||||
httpUser: "",
|
httpUser: "",
|
||||||
@ -67,13 +70,14 @@ const defaultForm = ref<Proxy>({
|
|||||||
https2http: false,
|
https2http: false,
|
||||||
https2httpCaFile: "",
|
https2httpCaFile: "",
|
||||||
https2httpKeyFile: "",
|
https2httpKeyFile: "",
|
||||||
keepTunnelOpen: false
|
keepTunnelOpen: false,
|
||||||
});
|
status: 1
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表单内容
|
* 表单内容
|
||||||
*/
|
*/
|
||||||
const editForm = ref<Proxy>(defaultForm.value);
|
const editForm = ref<FrpcProxy>(defaultForm);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代理类型
|
* 代理类型
|
||||||
@ -104,7 +108,7 @@ const editFormRules = reactive<FormRules>({
|
|||||||
// }
|
// }
|
||||||
],
|
],
|
||||||
type: [{ required: true, message: "请选择类型", trigger: "blur" }],
|
type: [{ required: true, message: "请选择类型", trigger: "blur" }],
|
||||||
localIp: [
|
localIP: [
|
||||||
{ required: true, message: "请输入内网地址", trigger: "blur" },
|
{ required: true, message: "请输入内网地址", trigger: "blur" },
|
||||||
{
|
{
|
||||||
pattern: /^[\w-]+(\.[\w-]+)+$/,
|
pattern: /^[\w-]+(\.[\w-]+)+$/,
|
||||||
@ -247,7 +251,7 @@ const handleRangePort = () => {
|
|||||||
*/
|
*/
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!editFormRef.value) return;
|
if (!editFormRef.value) return;
|
||||||
await editFormRef.value.validate(valid => {
|
editFormRef.value.validate(valid => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (handleRangePort()) {
|
if (handleRangePort()) {
|
||||||
const lc = handleGetPortCount(editForm.value.localPort);
|
const lc = handleGetPortCount(editForm.value.localPort);
|
||||||
@ -278,9 +282,9 @@ const handleSubmit = async () => {
|
|||||||
loading.value.form = 1;
|
loading.value.form = 1;
|
||||||
const data = clone(editForm.value);
|
const data = clone(editForm.value);
|
||||||
if (data._id) {
|
if (data._id) {
|
||||||
ipcRenderer.send("proxy.updateProxy", data);
|
send(ipcRouters.PROXY.createProxy, data);
|
||||||
} else {
|
} else {
|
||||||
ipcRenderer.send("proxy.insertProxy", data);
|
send(ipcRouters.PROXY.modifyProxy, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -305,97 +309,25 @@ const handleDeleteDomain = (index: number) => {
|
|||||||
* 加载代理
|
* 加载代理
|
||||||
*/
|
*/
|
||||||
const handleLoadProxys = () => {
|
const handleLoadProxys = () => {
|
||||||
ipcRenderer.send("proxy.getProxys");
|
send(ipcRouters.PROXY.getAllProxies);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除代理
|
* 删除代理
|
||||||
* @param proxy
|
* @param proxy
|
||||||
*/
|
*/
|
||||||
const handleDeleteProxy = (proxy: Proxy) => {
|
const handleDeleteProxy = (proxy: FrpcProxy) => {
|
||||||
ipcRenderer.send("proxy.deleteProxyById", proxy._id);
|
send(ipcRouters.PROXY.deleteProxy, proxy._id);
|
||||||
|
// ipcRenderer.send("proxy.deleteProxyById", proxy._id);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置表单
|
* 重置表单
|
||||||
*/
|
*/
|
||||||
const handleResetForm = () => {
|
const handleResetForm = () => {
|
||||||
editForm.value = defaultForm.value;
|
editForm.value = defaultForm;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化回调
|
|
||||||
*/
|
|
||||||
const handleInitHook = () => {
|
|
||||||
const InsertOrUpdateHook = (message: string, args: any) => {
|
|
||||||
loading.value.form--;
|
|
||||||
const { err } = args;
|
|
||||||
if (!err) {
|
|
||||||
ElMessage({
|
|
||||||
type: "success",
|
|
||||||
message: message
|
|
||||||
});
|
|
||||||
handleResetForm();
|
|
||||||
handleLoadProxys();
|
|
||||||
edit.value.visible = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ipcRenderer.on("Proxy.insertProxy.hook", (event, args) => {
|
|
||||||
InsertOrUpdateHook("新增成功", args);
|
|
||||||
});
|
|
||||||
ipcRenderer.on("Proxy.updateProxy.hook", (event, args) => {
|
|
||||||
InsertOrUpdateHook("修改成功", args);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcRenderer.on("Proxy.updateProxyStatus.hook", (event, args) => {
|
|
||||||
if (args.data > 0) {
|
|
||||||
handleLoadProxys();
|
|
||||||
}
|
|
||||||
console.log("更新结果", args);
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcRenderer.on("local.getLocalPorts.hook", (event, args) => {
|
|
||||||
loading.value.localPorts--;
|
|
||||||
localPorts.value = args.data;
|
|
||||||
console.log("内网端口", localPorts.value);
|
|
||||||
});
|
|
||||||
// ipcRenderer.on("Proxy.updateProxy.hook", (event, args) => {
|
|
||||||
// loading.value.form--;
|
|
||||||
// const { err } = args;
|
|
||||||
// if (!err) {
|
|
||||||
// ElMessage({
|
|
||||||
// type: "success",
|
|
||||||
// message: "修改成功"
|
|
||||||
// });
|
|
||||||
// handleResetForm();
|
|
||||||
// handleLoadProxys();
|
|
||||||
// edit.value.visible = false;
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
ipcRenderer.on("Proxy.getProxys.hook", (event, args) => {
|
|
||||||
loading.value.list--;
|
|
||||||
const { err, data } = args;
|
|
||||||
if (!err) {
|
|
||||||
data.forEach(f => {
|
|
||||||
if (f.status === null || f.status === undefined) {
|
|
||||||
f.status = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
proxys.value = data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
ipcRenderer.on("Proxy.deleteProxyById.hook", (event, args) => {
|
|
||||||
const { err, data } = args;
|
|
||||||
if (!err) {
|
|
||||||
handleLoadProxys();
|
|
||||||
ElMessage({
|
|
||||||
type: "success",
|
|
||||||
message: "删除成功"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleOpenInsert = () => {
|
const handleOpenInsert = () => {
|
||||||
edit.value = {
|
edit.value = {
|
||||||
title: "新增代理",
|
title: "新增代理",
|
||||||
@ -403,10 +335,10 @@ const handleOpenInsert = () => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOpenUpdate = (proxy: Proxy) => {
|
const handleOpenUpdate = (proxy: FrpcProxy) => {
|
||||||
editForm.value = clone(proxy);
|
editForm.value = clone(proxy);
|
||||||
if (!editForm.value.fallbackTimeoutMs) {
|
if (!editForm.value.fallbackTimeoutMs) {
|
||||||
editForm.value.fallbackTimeoutMs = defaultForm.value.fallbackTimeoutMs;
|
editForm.value.fallbackTimeoutMs = defaultForm.fallbackTimeoutMs;
|
||||||
}
|
}
|
||||||
edit.value = {
|
edit.value = {
|
||||||
title: "修改代理",
|
title: "修改代理",
|
||||||
@ -414,17 +346,17 @@ const handleOpenUpdate = (proxy: Proxy) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReversalUpdate = (proxy: Proxy) => {
|
const handleReversalUpdate = (proxy: FrpcProxy) => {
|
||||||
console.log("更新", proxy);
|
send(ipcRouters.PROXY.modifyProxyStatus, {
|
||||||
ipcRenderer.send("proxy.updateProxyStatus", {
|
id: proxy._id,
|
||||||
_id: proxy._id,
|
status: proxy.status === 1 ? 0 : 1
|
||||||
status: !proxy.status
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLoadLocalPorts = () => {
|
const handleLoadLocalPorts = () => {
|
||||||
loading.value.localPorts = 1;
|
loading.value.localPorts = 1;
|
||||||
ipcRenderer.send("local.getLocalPorts");
|
// ipcRenderer.send("local.getLocalPorts");
|
||||||
|
send(ipcRouters.PROXY.getLocalPorts);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectLocalPort = useDebounceFn((port: number) => {
|
const handleSelectLocalPort = useDebounceFn((port: number) => {
|
||||||
@ -441,7 +373,7 @@ const handleOpenLocalPortDialog = () => {
|
|||||||
handleLoadLocalPorts();
|
handleLoadLocalPorts();
|
||||||
};
|
};
|
||||||
|
|
||||||
const allowCopyAccessAddress = (proxy: Proxy) => {
|
const allowCopyAccessAddress = (proxy: FrpcProxy) => {
|
||||||
if (
|
if (
|
||||||
(proxy.type === "http" || proxy.type === "https") &&
|
(proxy.type === "http" || proxy.type === "https") &&
|
||||||
(proxy.customDomains.length < 1 || !proxy.customDomains[0])
|
(proxy.customDomains.length < 1 || !proxy.customDomains[0])
|
||||||
@ -460,7 +392,7 @@ const allowCopyAccessAddress = (proxy: Proxy) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCopyAccessAddress = (proxy: Proxy) => {
|
const handleCopyAccessAddress = (proxy: FrpcProxy) => {
|
||||||
if (
|
if (
|
||||||
(proxy.type === "http" || proxy.type === "https") &&
|
(proxy.type === "http" || proxy.type === "https") &&
|
||||||
(proxy.customDomains.length < 1 || !proxy.customDomains[0])
|
(proxy.customDomains.length < 1 || !proxy.customDomains[0])
|
||||||
@ -584,26 +516,79 @@ const handleSelectFile = (type: number, ext: string[]) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
handleInitHook();
|
|
||||||
handleLoadProxys();
|
handleLoadProxys();
|
||||||
ipcRenderer.send("config.getConfig");
|
|
||||||
ipcRenderer.on("Config.getConfig.hook", (event, args) => {
|
on(ipcRouters.PROXY.getAllProxies, data => {
|
||||||
const { err, data } = args;
|
console.log("allProxies", data);
|
||||||
if (!err) {
|
loading.value.list--;
|
||||||
if (data) {
|
proxys.value = data;
|
||||||
frpcConfig.value = data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const insertOrUpdateHook = (message: string) => {
|
||||||
|
loading.value.form--;
|
||||||
|
// const { err } = args;
|
||||||
|
// if (!err) {
|
||||||
|
ElMessage({
|
||||||
|
type: "success",
|
||||||
|
message: message
|
||||||
|
});
|
||||||
|
handleResetForm();
|
||||||
|
handleLoadProxys();
|
||||||
|
edit.value.visible = false;
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
on(ipcRouters.PROXY.createProxy, data => {
|
||||||
|
console.log("data", data);
|
||||||
|
insertOrUpdateHook("新增成功");
|
||||||
|
});
|
||||||
|
|
||||||
|
on(ipcRouters.PROXY.modifyProxy, data => {
|
||||||
|
console.log("data", data);
|
||||||
|
insertOrUpdateHook("修改成功");
|
||||||
|
});
|
||||||
|
|
||||||
|
on(ipcRouters.PROXY.deleteProxy, () => {
|
||||||
|
handleLoadProxys();
|
||||||
|
ElMessage({
|
||||||
|
type: "success",
|
||||||
|
message: "删除成功"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
on(ipcRouters.PROXY.modifyProxyStatus, () => {
|
||||||
|
ElMessage({
|
||||||
|
type: "success",
|
||||||
|
message: "修改成功"
|
||||||
|
});
|
||||||
|
// handleResetForm();
|
||||||
|
handleLoadProxys();
|
||||||
|
// edit.value.visible = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
on(ipcRouters.PROXY.getLocalPorts, data => {
|
||||||
|
loading.value.localPorts--;
|
||||||
|
localPorts.value = data;
|
||||||
|
});
|
||||||
|
|
||||||
|
// ipcRenderer.send("config.getConfig");
|
||||||
|
// ipcRenderer.on("Config.getConfig.hook", (event, args) => {
|
||||||
|
// const { err, data } = args;
|
||||||
|
// if (!err) {
|
||||||
|
// if (data) {
|
||||||
|
// frpcConfig.value = data;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
ipcRenderer.removeAllListeners("Proxy.insertProxy.hook");
|
removeRouterListeners(ipcRouters.PROXY.createProxy);
|
||||||
ipcRenderer.removeAllListeners("Proxy.updateProxy.hook");
|
removeRouterListeners(ipcRouters.PROXY.modifyProxy);
|
||||||
ipcRenderer.removeAllListeners("Proxy.updateProxyStatus.hook");
|
removeRouterListeners(ipcRouters.PROXY.deleteProxy);
|
||||||
ipcRenderer.removeAllListeners("Proxy.deleteProxyById.hook");
|
removeRouterListeners(ipcRouters.PROXY.getAllProxies);
|
||||||
ipcRenderer.removeAllListeners("Proxy.getProxys.hook");
|
removeRouterListeners(ipcRouters.PROXY.modifyProxyStatus);
|
||||||
ipcRenderer.removeAllListeners("local.getLocalPorts.hook");
|
removeRouterListeners(ipcRouters.PROXY.getLocalPorts);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@ -641,7 +626,7 @@ onUnmounted(() => {
|
|||||||
<span>{{ proxy.name }}</span>
|
<span>{{ proxy.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-tag
|
<el-tag
|
||||||
v-if="!proxy.status"
|
v-if="proxy.status === 0"
|
||||||
class="mr-2"
|
class="mr-2"
|
||||||
type="danger"
|
type="danger"
|
||||||
size="small"
|
size="small"
|
||||||
@ -741,7 +726,7 @@ onUnmounted(() => {
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<p class="text-[#ADADAD] font-bold">内网地址</p>
|
<p class="text-[#ADADAD] font-bold">内网地址</p>
|
||||||
<p>{{ proxy.localIp }}</p>
|
<p>{{ proxy.localIP }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-sm text-center" v-if="proxy.type === 'tcp'">
|
<div class="text-sm text-center" v-if="proxy.type === 'tcp'">
|
||||||
@ -919,15 +904,15 @@ onUnmounted(() => {
|
|||||||
</el-col>
|
</el-col>
|
||||||
<template v-if="!(isStcp || isXtcp || isSudp) || isStcpVisited">
|
<template v-if="!(isStcp || isXtcp || isSudp) || isStcpVisited">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="内网地址:" prop="localIp">
|
<el-form-item label="内网地址:" prop="localIP">
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
v-model="editForm.localIp"
|
v-model="editForm.localIP"
|
||||||
:fetch-suggestions="handleIpFetchSuggestions"
|
:fetch-suggestions="handleIpFetchSuggestions"
|
||||||
clearable
|
clearable
|
||||||
placeholder="127.0.0.1"
|
placeholder="127.0.0.1"
|
||||||
/>
|
/>
|
||||||
<!-- <el-input-->
|
<!-- <el-input-->
|
||||||
<!-- v-model="editForm.localIp"-->
|
<!-- v-model="editForm.localIP"-->
|
||||||
<!-- placeholder="127.0.0.1"-->
|
<!-- placeholder="127.0.0.1"-->
|
||||||
<!-- clearable-->
|
<!-- clearable-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
|
2
types/core.d.ts
vendored
2
types/core.d.ts
vendored
@ -31,6 +31,8 @@ enum IpcRouterKeys {
|
|||||||
SERVER = "SERVER",
|
SERVER = "SERVER",
|
||||||
LOG = "LOG",
|
LOG = "LOG",
|
||||||
VERSION = "VERSION",
|
VERSION = "VERSION",
|
||||||
|
LAUNCH = "LAUNCH",
|
||||||
|
PROXY = "PROXY",
|
||||||
}
|
}
|
||||||
|
|
||||||
type IpcRouters = Record<
|
type IpcRouters = Record<
|
||||||
|
22
types/frp.d.ts
vendored
22
types/frp.d.ts
vendored
@ -58,6 +58,24 @@ interface FrpcProxyConfig {
|
|||||||
name: string;
|
name: string;
|
||||||
type: string;
|
type: string;
|
||||||
localIP: string;
|
localIP: string;
|
||||||
localPort: number;
|
localPort: any;
|
||||||
remotePort: number;
|
remotePort: any;
|
||||||
|
customDomains: string[];
|
||||||
|
locations: string[];
|
||||||
|
hostHeaderRewrite: string;
|
||||||
|
stcpModel: string;
|
||||||
|
serverName: string;
|
||||||
|
secretKey: string;
|
||||||
|
bindAddr: string;
|
||||||
|
bindPort: number;
|
||||||
|
subdomain: string;
|
||||||
|
basicAuth: boolean;
|
||||||
|
httpUser: string;
|
||||||
|
httpPassword: string;
|
||||||
|
fallbackTo: string;
|
||||||
|
fallbackTimeoutMs: number;
|
||||||
|
https2http: boolean;
|
||||||
|
https2httpCaFile: string;
|
||||||
|
https2httpKeyFile: string;
|
||||||
|
keepTunnelOpen: boolean;
|
||||||
}
|
}
|
||||||
|
14
types/frpc-desktop.d.ts
vendored
14
types/frpc-desktop.d.ts
vendored
@ -2,7 +2,7 @@ type FrpcDesktopProxy = FrpcProxyConfig & {};
|
|||||||
|
|
||||||
interface BaseEntity {
|
interface BaseEntity {
|
||||||
_id: string;
|
_id: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
interface FrpcSystemConfiguration {
|
interface FrpcSystemConfiguration {
|
||||||
launchAtStartup: boolean;
|
launchAtStartup: boolean;
|
||||||
@ -10,9 +10,11 @@ interface FrpcSystemConfiguration {
|
|||||||
autoConnectOnStartup: boolean;
|
autoConnectOnStartup: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type FrpcDesktopServer = FrpcCommonConfig & {
|
type FrpcDesktopServer = BaseEntity &
|
||||||
frpcVersion: number;
|
FrpcCommonConfig & {
|
||||||
};
|
frpcVersion: number;
|
||||||
|
system: any;
|
||||||
|
};
|
||||||
|
|
||||||
type FrpcVersion = BaseEntity & {
|
type FrpcVersion = BaseEntity & {
|
||||||
githubReleaseId: number;
|
githubReleaseId: number;
|
||||||
@ -30,4 +32,8 @@ type FrpcVersion = BaseEntity & {
|
|||||||
|
|
||||||
type OpenSourceFrpcDesktopServer = FrpcDesktopServer & {
|
type OpenSourceFrpcDesktopServer = FrpcDesktopServer & {
|
||||||
system: FrpcSystemConfiguration;
|
system: FrpcSystemConfiguration;
|
||||||
|
};
|
||||||
|
|
||||||
|
type FrpcProxy = BaseEntity & FrpcProxyConfig & {
|
||||||
|
status: number; // 0: disable 1: enable
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user