🔊 Improve the log
This commit is contained in:
parent
19fde43f8b
commit
aad6fd78d5
@ -5,6 +5,7 @@ import { genIniConfig, genTomlConfig, stopFrpcProcess } from "./frpc";
|
||||
import { clearProxy, insertProxy, listProxy } from "../storage/proxy";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { logDebug, logError, logInfo, LogModule, logWarn } from "../utils/log";
|
||||
|
||||
const log = require("electron-log");
|
||||
const toml = require("@iarna/toml");
|
||||
@ -12,14 +13,18 @@ const { v4: uuidv4 } = require("uuid");
|
||||
|
||||
export const initConfigApi = win => {
|
||||
ipcMain.on("config.saveConfig", async (event, args) => {
|
||||
logInfo(LogModule.APP, "Attempting to save configuration.");
|
||||
saveConfig(args, (err, numberOfUpdated, upsert) => {
|
||||
if (!err) {
|
||||
const start = args.systemSelfStart || false;
|
||||
log.info("开启自启状态", start);
|
||||
logDebug(LogModule.APP, "Startup status set to: " + start);
|
||||
app.setLoginItemSettings({
|
||||
openAtLogin: start, //win
|
||||
openAsHidden: start //macOs
|
||||
});
|
||||
logInfo(LogModule.APP, "Configuration saved successfully.");
|
||||
} else {
|
||||
logError(LogModule.APP, `Error saving configuration: ${err}`);
|
||||
}
|
||||
event.reply("Config.saveConfig.hook", {
|
||||
err: err,
|
||||
@ -30,7 +35,11 @@ export const initConfigApi = win => {
|
||||
});
|
||||
|
||||
ipcMain.on("config.getConfig", async (event, args) => {
|
||||
logInfo(LogModule.APP, "Requesting configuration.");
|
||||
getConfig((err, doc) => {
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error retrieving configuration: ${err}`);
|
||||
}
|
||||
event.reply("Config.getConfig.hook", {
|
||||
err: err,
|
||||
data: doc
|
||||
@ -39,7 +48,11 @@ export const initConfigApi = win => {
|
||||
});
|
||||
|
||||
ipcMain.on("config.versions", event => {
|
||||
logInfo(LogModule.APP, "Requesting version information.");
|
||||
listVersion((err, doc) => {
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error retrieving version information: ${err}`);
|
||||
}
|
||||
event.reply("Config.versions.hook", {
|
||||
err: err,
|
||||
data: doc
|
||||
@ -48,7 +61,11 @@ export const initConfigApi = win => {
|
||||
});
|
||||
|
||||
ipcMain.on("config.hasConfig", event => {
|
||||
logInfo(LogModule.APP, "Checking if configuration exists.");
|
||||
getConfig((err, doc) => {
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error checking configuration: ${err}`);
|
||||
}
|
||||
event.reply("Config.getConfig.hook", {
|
||||
err: err,
|
||||
data: doc
|
||||
@ -57,15 +74,18 @@ export const initConfigApi = win => {
|
||||
});
|
||||
|
||||
ipcMain.on("config.exportConfig", async (event, args) => {
|
||||
logInfo(LogModule.APP, "Attempting to export configuration.");
|
||||
const result = await dialog.showOpenDialog({
|
||||
properties: ["openDirectory"]
|
||||
});
|
||||
const outputDirectory = result.filePaths[0];
|
||||
if (!outputDirectory) {
|
||||
// 取消了
|
||||
logWarn(LogModule.APP, "Export canceled by user.");
|
||||
return;
|
||||
}
|
||||
log.info(`导出目录 ${outputDirectory} 类型:${args}`);
|
||||
log.info(
|
||||
`Exporting configuration to directory ${outputDirectory} with type: ${args}`
|
||||
);
|
||||
getConfig((err1, config) => {
|
||||
if (!err1 && config) {
|
||||
listProxy((err2, proxys) => {
|
||||
@ -85,33 +105,44 @@ export const initConfigApi = win => {
|
||||
configContent, // 配置文件内容
|
||||
{ flag: "w" },
|
||||
err => {
|
||||
if (!err) {
|
||||
// callback(filename);
|
||||
if (err) {
|
||||
logError(
|
||||
LogModule.APP,
|
||||
`Error writing configuration file: ${err}`
|
||||
);
|
||||
event.reply("config.exportConfig.hook", {
|
||||
data: "导出错误",
|
||||
err: err
|
||||
});
|
||||
} else {
|
||||
logInfo(
|
||||
LogModule.APP,
|
||||
"Configuration exported successfully."
|
||||
);
|
||||
event.reply("Config.exportConfig.hook", {
|
||||
data: {
|
||||
configPath: configPath
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
event.reply("Config.exportConfig.hook", {
|
||||
data: {
|
||||
configPath: configPath
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logError(LogModule.APP, `Error listing proxies: ${err2}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logError(LogModule.APP, `Error retrieving configuration: ${err1}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const parseTomlConfig = (tomlPath: string) => {
|
||||
logInfo(LogModule.APP, `Parsing TOML configuration from ${tomlPath}`);
|
||||
const importConfigPath = tomlPath;
|
||||
const tomlData = fs.readFileSync(importConfigPath, "utf-8");
|
||||
log.info(`读取到配置内容 ${tomlData}`);
|
||||
logInfo(LogModule.APP, "Configuration content read successfully.");
|
||||
const sourceConfig = toml.parse(tomlData);
|
||||
// log.info(`解析结果 ${sourceConfig}`);
|
||||
// console.log(sourceConfig, "frpcConfig");
|
||||
// 解析config
|
||||
const targetConfig: FrpConfig = {
|
||||
currentVersion: null,
|
||||
@ -180,6 +211,7 @@ export const initConfigApi = win => {
|
||||
return rm;
|
||||
});
|
||||
frpcProxys = [...frpcProxys, ...frpcProxys1];
|
||||
logInfo(LogModule.APP, "Parsed proxies from configuration.");
|
||||
}
|
||||
// 解析stcp的访问者
|
||||
if (sourceConfig?.visitors && sourceConfig.visitors.length > 0) {
|
||||
@ -209,17 +241,24 @@ export const initConfigApi = win => {
|
||||
return rm;
|
||||
});
|
||||
frpcProxys = [...frpcProxys, ...frpcProxys2];
|
||||
logInfo(LogModule.APP, "Parsed visitors from configuration.");
|
||||
}
|
||||
if (targetConfig) {
|
||||
clearConfig(() => {
|
||||
logInfo(LogModule.APP, "Clearing existing configuration.");
|
||||
saveConfig(targetConfig);
|
||||
logInfo(LogModule.APP, "New configuration saved.");
|
||||
});
|
||||
}
|
||||
if (frpcProxys && frpcProxys.length > 0) {
|
||||
clearProxy(() => {
|
||||
frpcProxys.forEach(f => {
|
||||
insertProxy(f, err => {
|
||||
console.log("插入", f, err);
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error inserting proxy: ${err}`);
|
||||
} else {
|
||||
logInfo(LogModule.APP, `Inserted proxy: ${JSON.stringify(f)}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -227,6 +266,7 @@ export const initConfigApi = win => {
|
||||
};
|
||||
|
||||
ipcMain.on("config.importConfig", async (event, args) => {
|
||||
logInfo(LogModule.APP, "Attempting to import configuration.");
|
||||
const result = await dialog.showOpenDialog(win, {
|
||||
properties: ["openFile"],
|
||||
filters: [
|
||||
@ -234,17 +274,22 @@ export const initConfigApi = win => {
|
||||
]
|
||||
});
|
||||
if (result.canceled) {
|
||||
logWarn(LogModule.APP, "Import canceled by user.");
|
||||
return;
|
||||
} else {
|
||||
const filePath = result.filePaths[0];
|
||||
const fileExtension = path.extname(filePath); // 获取文件后缀名
|
||||
log.info(`导入文件 ${filePath} ${fileExtension}`);
|
||||
log.info(`Importing file ${filePath} with extension ${fileExtension}`);
|
||||
if (fileExtension === ".toml") {
|
||||
parseTomlConfig(filePath);
|
||||
event.reply("Config.importConfig.hook", {
|
||||
success: true
|
||||
});
|
||||
} else {
|
||||
logError(
|
||||
LogModule.APP,
|
||||
`Import failed, unsupported file format: ${fileExtension}`
|
||||
);
|
||||
event.reply("Config.importConfig.hook", {
|
||||
success: false,
|
||||
data: `导入失败,暂不支持 ${fileExtension} 格式文件`
|
||||
@ -254,22 +299,25 @@ export const initConfigApi = win => {
|
||||
});
|
||||
|
||||
ipcMain.on("config.clearAll", async (event, args) => {
|
||||
logInfo(LogModule.APP, "Clearing all configurations.");
|
||||
stopFrpcProcess(() => {
|
||||
clearConfig();
|
||||
clearProxy();
|
||||
clearVersion();
|
||||
event.reply("Config.clearAll.hook", {});
|
||||
logInfo(LogModule.APP, "All configurations cleared.");
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.on("config.openDataFolder", async (event, args) => {
|
||||
const userDataPath = app.getPath("userData");
|
||||
logInfo(LogModule.APP, "Attempting to open data folder.");
|
||||
shell.openPath(userDataPath).then(errorMessage => {
|
||||
if (errorMessage) {
|
||||
console.error("Failed to open Logger:", errorMessage);
|
||||
logError(LogModule.APP, `Failed to open data folder: ${errorMessage}`);
|
||||
event.reply("Config.openDataFolder.hook", false);
|
||||
} else {
|
||||
console.log("Logger opened successfully");
|
||||
logInfo(LogModule.APP, "Data folder opened successfully.");
|
||||
event.reply("Config.openDataFolder.hook", true);
|
||||
}
|
||||
});
|
||||
|
@ -3,11 +3,12 @@ import { getConfig } from "../storage/config";
|
||||
import { listProxy } from "../storage/proxy";
|
||||
import { getVersionById } from "../storage/version";
|
||||
import treeKill from "tree-kill";
|
||||
import { logInfo, logError, LogModule, logDebug, logWarn } from "../utils/log";
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { exec, spawn } = require("child_process");
|
||||
const log = require("electron-log");
|
||||
|
||||
export let frpcProcess = null;
|
||||
const runningCmd = {
|
||||
commandPath: null,
|
||||
@ -15,11 +16,6 @@ const runningCmd = {
|
||||
};
|
||||
let frpcStatusListener = null;
|
||||
|
||||
/**
|
||||
* 获取选择版本的工作目录
|
||||
* @param versionId 版本ID
|
||||
* @param callback
|
||||
*/
|
||||
const getFrpcVersionWorkerPath = (
|
||||
versionId: number,
|
||||
callback: (workerPath: string) => void
|
||||
@ -56,10 +52,10 @@ export const genTomlConfig = (config: FrpConfig, proxys: Proxy[]) => {
|
||||
"\\\\"
|
||||
);
|
||||
let toml = `${
|
||||
rangePort
|
||||
? `{{- range $_, $v := parseNumberRangePair "${m.localPort}" "${m.remotePort}" }}`
|
||||
: ""
|
||||
}
|
||||
rangePort
|
||||
? `{{- range $_, $v := parseNumberRangePair "${m.localPort}" "${m.remotePort}" }}`
|
||||
: ""
|
||||
}
|
||||
[[${
|
||||
(m.type === "stcp" || m.type === "xtcp" || m.type === "sudp") &&
|
||||
m.stcpModel === "visitors"
|
||||
@ -200,9 +196,9 @@ ${
|
||||
: ""
|
||||
}
|
||||
${
|
||||
config.tlsConfigEnable && config.tlsConfigKeyFile
|
||||
? `transport.tls.keyFile = "${config.tlsConfigKeyFile}"`
|
||||
: ""
|
||||
config.tlsConfigEnable && config.tlsConfigKeyFile
|
||||
? `transport.tls.keyFile = "${config.tlsConfigKeyFile}"`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
config.tlsConfigEnable && config.tlsConfigTrustedCaFile
|
||||
@ -408,39 +404,65 @@ export const generateConfig = (
|
||||
callback: (configPath: string) => void
|
||||
) => {
|
||||
listProxy((err3, proxys) => {
|
||||
if (!err3) {
|
||||
const { currentVersion } = config;
|
||||
let filename = null;
|
||||
let configContent = "";
|
||||
const filtered = proxys
|
||||
.map(m => {
|
||||
if (m.status == null || m.status == undefined) {
|
||||
m.status = true;
|
||||
}
|
||||
return m;
|
||||
})
|
||||
.filter(f => f.status);
|
||||
if (currentVersion < 124395282) {
|
||||
// 版本小于v0.52.0
|
||||
filename = "frp.ini";
|
||||
configContent = genIniConfig(config, filtered);
|
||||
} else {
|
||||
filename = "frp.toml";
|
||||
configContent = genTomlConfig(config, filtered);
|
||||
}
|
||||
const configPath = path.join(app.getPath("userData"), filename);
|
||||
log.info(`生成配置成功 配置路径:${configPath}`);
|
||||
fs.writeFile(
|
||||
configPath, // 配置文件目录
|
||||
configContent, // 配置文件内容
|
||||
{ flag: "w" },
|
||||
err => {
|
||||
if (!err) {
|
||||
callback(filename);
|
||||
}
|
||||
if (err3) {
|
||||
logError(LogModule.FRP_CLIENT, `Failed to list proxies: ${err3.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const { currentVersion } = config;
|
||||
let filename = null;
|
||||
let configContent = "";
|
||||
const filtered = proxys
|
||||
.map(m => {
|
||||
if (m.status == null || m.status == undefined) {
|
||||
m.status = true;
|
||||
}
|
||||
return m;
|
||||
})
|
||||
.filter(f => f.status);
|
||||
|
||||
if (currentVersion < 124395282) {
|
||||
// 版本小于v0.52.0
|
||||
filename = "frp.ini";
|
||||
configContent = genIniConfig(config, filtered);
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Using INI format for configuration: ${filename}`
|
||||
);
|
||||
} else {
|
||||
filename = "frp.toml";
|
||||
configContent = genTomlConfig(config, filtered);
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Using TOML format for configuration: ${filename}`
|
||||
);
|
||||
}
|
||||
|
||||
const configPath = path.join(app.getPath("userData"), filename);
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Writing configuration to file: ${configPath}`
|
||||
);
|
||||
|
||||
fs.writeFile(
|
||||
configPath, // 配置文件目录
|
||||
configContent, // 配置文件内容
|
||||
{ flag: "w" },
|
||||
err => {
|
||||
if (err) {
|
||||
logError(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Failed to write configuration file: ${err.message}`
|
||||
);
|
||||
} else {
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Configuration file written successfully: ${filename}`
|
||||
);
|
||||
callback(filename);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
@ -451,7 +473,13 @@ export const generateConfig = (
|
||||
* @param configPath
|
||||
*/
|
||||
const startFrpcProcess = (commandPath: string, configPath: string) => {
|
||||
log.info(`启动frpc 目录:${app.getPath("userData")} 命令:${commandPath}`);
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Starting frpc process. Directory: ${app.getPath(
|
||||
"userData"
|
||||
)}, Command: ${commandPath}`
|
||||
);
|
||||
|
||||
const command = `${commandPath} -c ${configPath}`;
|
||||
frpcProcess = spawn(command, {
|
||||
cwd: app.getPath("userData"),
|
||||
@ -459,21 +487,31 @@ const startFrpcProcess = (commandPath: string, configPath: string) => {
|
||||
});
|
||||
runningCmd.commandPath = commandPath;
|
||||
runningCmd.configPath = configPath;
|
||||
|
||||
frpcProcess.stdout.on("data", data => {
|
||||
log.debug(`启动输出:${data}`);
|
||||
logDebug(LogModule.FRP_CLIENT, `Frpc process output: ${data}`);
|
||||
});
|
||||
|
||||
frpcProcess.stdout.on("error", data => {
|
||||
log.error(`启动错误:${data}`);
|
||||
logError(LogModule.FRP_CLIENT, `Frpc process error: ${data}`);
|
||||
stopFrpcProcess(() => {});
|
||||
});
|
||||
|
||||
frpcStatusListener = setInterval(() => {
|
||||
const status = frpcProcessStatus();
|
||||
log.debug(`监听frpc子进程状态:${status} ${frpcStatusListener}`);
|
||||
logDebug(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Monitoring frpc process status: ${status}, Listener ID: ${frpcStatusListener}`
|
||||
);
|
||||
if (!status) {
|
||||
new Notification({
|
||||
title: "Frpc Desktop",
|
||||
body: "连接已断开,请前往日志查看原因"
|
||||
body: "Connection lost, please check the logs for details."
|
||||
}).show();
|
||||
logError(
|
||||
LogModule.FRP_CLIENT,
|
||||
"Frpc process status check failed. Connection lost."
|
||||
);
|
||||
clearInterval(frpcStatusListener);
|
||||
}
|
||||
}, 3000);
|
||||
@ -484,20 +522,58 @@ const startFrpcProcess = (commandPath: string, configPath: string) => {
|
||||
*/
|
||||
export const reloadFrpcProcess = () => {
|
||||
if (frpcProcess && !frpcProcess.killed) {
|
||||
logDebug(
|
||||
LogModule.FRP_CLIENT,
|
||||
"Attempting to reload frpc process configuration."
|
||||
);
|
||||
getConfig((err1, config) => {
|
||||
if (!err1) {
|
||||
if (config) {
|
||||
generateConfig(config, configPath => {
|
||||
const command = `${runningCmd.commandPath} reload -c ${configPath}`;
|
||||
log.info(`重载配置:${command}`);
|
||||
exec(command, {
|
||||
cwd: app.getPath("userData"),
|
||||
shell: true
|
||||
});
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Reloading configuration: ${command}`
|
||||
);
|
||||
exec(
|
||||
command,
|
||||
{
|
||||
cwd: app.getPath("userData"),
|
||||
shell: true
|
||||
},
|
||||
(error, stdout, stderr) => {
|
||||
if (error) {
|
||||
logError(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Error reloading configuration: ${error.message}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
logDebug(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Configuration reload output: ${stdout}`
|
||||
);
|
||||
if (stderr) {
|
||||
logWarn(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Configuration reload warnings: ${stderr}`
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
} else {
|
||||
logWarn(LogModule.FRP_CLIENT, "No configuration found to reload.");
|
||||
}
|
||||
} else {
|
||||
logError(LogModule.FRP_CLIENT, `Error getting configuration: ${err1}`);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logWarn(
|
||||
LogModule.FRP_CLIENT,
|
||||
"frpc process is not running or has been killed."
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -508,16 +584,27 @@ export const stopFrpcProcess = (callback?: () => void) => {
|
||||
if (frpcProcess) {
|
||||
treeKill(frpcProcess.pid, (error: Error) => {
|
||||
if (error) {
|
||||
log.error(`关闭frpc子进程失败 pid:${frpcProcess.pid} error:${error}`);
|
||||
logError(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Failed to stop frpc process with pid: ${frpcProcess.pid}. Error: ${error.message}`
|
||||
);
|
||||
callback();
|
||||
} else {
|
||||
log.info(`关闭frpc子进程成功`);
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Successfully stopped frpc process with pid: ${frpcProcess.pid}.`
|
||||
);
|
||||
frpcProcess = null;
|
||||
clearInterval(frpcStatusListener);
|
||||
callback();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logWarn(
|
||||
LogModule.FRP_CLIENT,
|
||||
"Attempted to stop frpc process, but no process is running."
|
||||
);
|
||||
logWarn(LogModule.FRP_CLIENT, "No frpc process to stop.");
|
||||
callback();
|
||||
}
|
||||
};
|
||||
@ -527,14 +614,23 @@ export const stopFrpcProcess = (callback?: () => void) => {
|
||||
*/
|
||||
export const frpcProcessStatus = () => {
|
||||
if (!frpcProcess) {
|
||||
logWarn(LogModule.FRP_CLIENT, "frpc process is not running.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// 发送信号给进程,如果进程存在,会正常返回
|
||||
process.kill(frpcProcess.pid, 0);
|
||||
logDebug(
|
||||
LogModule.FRP_CLIENT,
|
||||
`frpc process is running with pid: ${frpcProcess.pid}`
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
// 进程不存在,抛出异常
|
||||
logError(
|
||||
LogModule.FRP_CLIENT,
|
||||
`frpc process not found. Error: ${error.message}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@ -544,29 +640,47 @@ export const frpcProcessStatus = () => {
|
||||
* @param config
|
||||
*/
|
||||
export const startFrpWorkerProcess = async (config: FrpConfig) => {
|
||||
logInfo(LogModule.FRP_CLIENT, "Starting frpc worker process...");
|
||||
getFrpcVersionWorkerPath(config.currentVersion, (frpcVersionPath: string) => {
|
||||
if (frpcVersionPath) {
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
`Found frpc version path: ${frpcVersionPath}`
|
||||
);
|
||||
generateConfig(config, configPath => {
|
||||
const platform = process.platform;
|
||||
if (platform === "win32") {
|
||||
logInfo(LogModule.FRP_CLIENT, "Starting frpc on Windows.");
|
||||
startFrpcProcess(path.join(frpcVersionPath, "frpc.exe"), configPath);
|
||||
} else {
|
||||
logInfo(
|
||||
LogModule.FRP_CLIENT,
|
||||
"Starting frpc on non-Windows platform."
|
||||
);
|
||||
startFrpcProcess(path.join(frpcVersionPath, "frpc"), configPath);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logError(LogModule.FRP_CLIENT, "frpc version path not found.");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const initFrpcApi = () => {
|
||||
ipcMain.handle("frpc.running", async (event, args) => {
|
||||
logDebug(LogModule.FRP_CLIENT, "Checking if frpc process is running...");
|
||||
return frpcProcessStatus();
|
||||
});
|
||||
|
||||
ipcMain.on("frpc.start", async (event, args) => {
|
||||
logInfo(LogModule.FRP_CLIENT, "Received request to start frpc process.");
|
||||
getConfig((err1, config) => {
|
||||
if (!err1) {
|
||||
if (!config) {
|
||||
logWarn(
|
||||
LogModule.FRP_CLIENT,
|
||||
"Configuration not found. Prompting user to set configuration."
|
||||
);
|
||||
event.reply(
|
||||
"Home.frpc.start.error.hook",
|
||||
"请先前往设置页面,修改配置后再启动"
|
||||
@ -574,6 +688,10 @@ export const initFrpcApi = () => {
|
||||
return;
|
||||
}
|
||||
if (!config.currentVersion) {
|
||||
logWarn(
|
||||
LogModule.FRP_CLIENT,
|
||||
"Current version not set in configuration. Prompting user."
|
||||
);
|
||||
event.reply(
|
||||
"Home.frpc.start.error.hook",
|
||||
"请先前往设置页面,修改配置后再启动"
|
||||
@ -581,13 +699,18 @@ export const initFrpcApi = () => {
|
||||
return;
|
||||
}
|
||||
startFrpWorkerProcess(config);
|
||||
} else {
|
||||
logError(LogModule.FRP_CLIENT, `Error getting configuration: ${err1}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.on("frpc.stop", () => {
|
||||
logInfo(LogModule.FRP_CLIENT, "Received request to stop frpc process.");
|
||||
if (frpcProcess && !frpcProcess.killed) {
|
||||
stopFrpcProcess(() => {});
|
||||
} else {
|
||||
logWarn(LogModule.FRP_CLIENT, "No frpc process to stop.");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ const { download } = require("electron-dl");
|
||||
const AdmZip = require("adm-zip");
|
||||
const log = require("electron-log");
|
||||
import frpReleasesJson from "../json/frp-releases.json";
|
||||
import { logInfo, logError, LogModule, logDebug, logWarn } from "../utils/log";
|
||||
|
||||
const versionRelation = {
|
||||
win32_x64: ["window", "amd64"],
|
||||
@ -31,23 +32,45 @@ const frpArch = versionRelation[currArch];
|
||||
const unTarGZ = (tarGzPath: string, targetPath: string) => {
|
||||
const tar = require("tar");
|
||||
const unzip = zlib.createGunzip();
|
||||
log.debug(`开始解压tar.gz:${tarGzPath} 目标目录:${targetPath}`);
|
||||
logInfo(
|
||||
LogModule.APP,
|
||||
`Starting to extract tar.gz: ${tarGzPath} to ${targetPath}`
|
||||
);
|
||||
|
||||
const readStream = fs.createReadStream(tarGzPath);
|
||||
if (!fs.existsSync(unzip)) {
|
||||
fs.mkdirSync(targetPath, { recursive: true });
|
||||
logInfo(LogModule.APP, `Created target directory: ${targetPath}`);
|
||||
}
|
||||
readStream.pipe(unzip).pipe(
|
||||
tar.extract({
|
||||
cwd: targetPath,
|
||||
filter: filePath => path.basename(filePath) === "frpc"
|
||||
|
||||
readStream.on("error", err => {
|
||||
logError(LogModule.APP, `Error reading tar.gz file: ${err.message}`);
|
||||
});
|
||||
|
||||
readStream
|
||||
.pipe(unzip)
|
||||
.on("error", err => {
|
||||
logError(LogModule.APP, `Error during gunzip: ${err.message}`);
|
||||
})
|
||||
);
|
||||
const frpcPath = path.join("frp", path.basename(tarGzPath, ".tar.gz"));
|
||||
log.debug(`解压完成 解压后目录:${frpcPath}`);
|
||||
return frpcPath;
|
||||
// .on("finish", () => {
|
||||
// console.log("解压完成!");
|
||||
// });
|
||||
.pipe(
|
||||
tar
|
||||
.extract({
|
||||
cwd: targetPath,
|
||||
filter: filePath => path.basename(filePath) === "frpc"
|
||||
})
|
||||
.on("error", err => {
|
||||
logError(LogModule.APP, `Error extracting tar file: ${err.message}`);
|
||||
})
|
||||
)
|
||||
.on("finish", () => {
|
||||
const frpcPath = path.join("frp", path.basename(tarGzPath, ".tar.gz"));
|
||||
logInfo(
|
||||
LogModule.APP,
|
||||
`Extraction completed. Extracted directory: ${frpcPath}`
|
||||
);
|
||||
});
|
||||
|
||||
return path.join("frp", path.basename(tarGzPath, ".tar.gz"));
|
||||
};
|
||||
|
||||
const unZip = (zipPath: string, targetPath: string) => {
|
||||
@ -55,28 +78,37 @@ const unZip = (zipPath: string, targetPath: string) => {
|
||||
fs.mkdirSync(path.join(targetPath, path.basename(zipPath, ".zip")), {
|
||||
recursive: true
|
||||
});
|
||||
logInfo(LogModule.APP, `Created target directory: ${targetPath}`);
|
||||
logInfo(
|
||||
LogModule.APP,
|
||||
`Created directory for zip extraction: ${path.basename(zipPath, ".zip")}`
|
||||
);
|
||||
}
|
||||
log.debug(`开始解压zip:${zipPath} 目标目录:${targetPath}`);
|
||||
/**
|
||||
* unzipper解压
|
||||
*/
|
||||
// fs.createReadStream(zipPath)
|
||||
// .pipe(unzipper.Extract({ path: targetPath }))
|
||||
// // 只解压frpc.exe
|
||||
// // .pipe(unzipper.ParseOne('frpc'))
|
||||
// // .pipe(fs.createWriteStream(path.join(targetPath, path.basename(zipPath, ".zip"), "frpc.exe")))
|
||||
// .on('finish', () => {
|
||||
// console.log('File extracted successfully.');
|
||||
// })
|
||||
// .on('error', (err) => {
|
||||
// console.error('Error extracting file:', err);
|
||||
// });
|
||||
|
||||
logDebug(
|
||||
LogModule.APP,
|
||||
`Starting to unzip: ${zipPath} to target directory: ${targetPath}`
|
||||
);
|
||||
logInfo(LogModule.APP, `Starting to extract zip file: ${zipPath}`);
|
||||
|
||||
const zip = new AdmZip(zipPath);
|
||||
zip.extractAllTo(targetPath, true); // 第二个参数为 true,表示覆盖已存在的文件
|
||||
const frpcPath = path.join("frp", path.basename(zipPath, ".zip"));
|
||||
log.debug(`解压完成 解压后目录:${frpcPath}`);
|
||||
return frpcPath;
|
||||
try {
|
||||
zip.extractAllTo(targetPath, true); // 第二个参数为 true,表示覆盖已存在的文件
|
||||
const frpcPath = path.join("frp", path.basename(zipPath, ".zip"));
|
||||
logInfo(
|
||||
LogModule.APP,
|
||||
`Extraction completed. Extracted directory: ${frpcPath}`
|
||||
);
|
||||
logDebug(
|
||||
LogModule.APP,
|
||||
`Unzip completed. Extracted directory: ${frpcPath}`
|
||||
);
|
||||
return frpcPath;
|
||||
} catch (error) {
|
||||
logError(LogModule.APP, `Error extracting zip file: ${error.message}`);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const initGitHubApi = () => {
|
||||
@ -84,40 +116,68 @@ export const initGitHubApi = () => {
|
||||
let versions: FrpVersion[] = [];
|
||||
|
||||
const getVersion = versionId => {
|
||||
return versions.find(f => f.id === versionId);
|
||||
logDebug(
|
||||
LogModule.GITHUB,
|
||||
`Attempting to get version with ID: ${versionId}`
|
||||
);
|
||||
const version = versions.find(f => f.id === versionId);
|
||||
if (version) {
|
||||
logInfo(LogModule.GITHUB, `Version found: ${JSON.stringify(version)}`);
|
||||
} else {
|
||||
logWarn(LogModule.GITHUB, `No version found for ID: ${versionId}`);
|
||||
}
|
||||
return version;
|
||||
};
|
||||
|
||||
const getAdaptiveAsset = versionId => {
|
||||
const { assets } = getVersion(versionId);
|
||||
if (!assets || assets.length === 0) {
|
||||
logWarn(LogModule.GITHUB, `No assets found for version ID: ${versionId}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const asset = assets.find(f => {
|
||||
// const a = versionRelation[currArch]
|
||||
const a = frpArch;
|
||||
if (a) {
|
||||
const flag = a.every(item => f.name.includes(item));
|
||||
if (flag) {
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Found matching asset: ${f.name} for version ID: ${versionId}`
|
||||
);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
logWarn(
|
||||
LogModule.GITHUB,
|
||||
`No architecture match found for asset: ${f.name}`
|
||||
);
|
||||
return false;
|
||||
});
|
||||
// if (asset) {
|
||||
// log.info(`找到对应版本 ${asset.name}`);
|
||||
// }
|
||||
|
||||
if (!asset) {
|
||||
logError(
|
||||
LogModule.GITHUB,
|
||||
`No adaptive asset found for version ID: ${versionId}`
|
||||
);
|
||||
}
|
||||
return asset;
|
||||
};
|
||||
|
||||
/**
|
||||
* 格式化字节信息
|
||||
* @param bytes 字节
|
||||
* @param decimals 小数位
|
||||
* Format byte information
|
||||
* @param bytes Bytes
|
||||
* @param decimals Decimal places
|
||||
* @returns
|
||||
*/
|
||||
const formatBytes = (bytes: number, decimals: number = 2): string => {
|
||||
if (bytes === 0) return "0 Bytes";
|
||||
const k = 1024; // 1 KB = 1024 Bytes
|
||||
const dm = decimals < 0 ? 0 : decimals; // 确保小数位数不小于 0
|
||||
const dm = decimals < 0 ? 0 : decimals; // Ensure decimal places are not less than 0
|
||||
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k)); // 计算单位索引
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; // 返回格式化的字符串
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k)); // Calculate unit index
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; // Return formatted string
|
||||
};
|
||||
|
||||
/**
|
||||
@ -127,8 +187,15 @@ export const initGitHubApi = () => {
|
||||
*/
|
||||
const handleApiResponse = (githubReleaseJsonStr: string) => {
|
||||
const downloadPath = path.join(app.getPath("userData"), "download");
|
||||
logInfo(LogModule.GITHUB, "Parsing GitHub release JSON response.");
|
||||
|
||||
versions = JSON.parse(githubReleaseJsonStr);
|
||||
if (versions) {
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
"Successfully parsed versions from GitHub response."
|
||||
);
|
||||
|
||||
const returnVersionsData = versions
|
||||
.filter(f => getAdaptiveAsset(f.id))
|
||||
.map(m => {
|
||||
@ -143,12 +210,25 @@ export const initGitHubApi = () => {
|
||||
m.download_completed = fs.existsSync(absPath);
|
||||
m.download_count = download_count;
|
||||
m.size = formatBytes(asset.size);
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Asset found: ${asset.name}, download count: ${download_count}`
|
||||
);
|
||||
} else {
|
||||
logWarn(LogModule.GITHUB, `No asset found for version ID: ${m.id}`);
|
||||
}
|
||||
return m;
|
||||
});
|
||||
// log.debug(`获取到frp版本:${JSON.stringify(returnVersionsData)}`)
|
||||
logDebug(
|
||||
LogModule.GITHUB,
|
||||
`Retrieved FRP versions: ${JSON.stringify(returnVersionsData)}`
|
||||
);
|
||||
return returnVersionsData;
|
||||
} else {
|
||||
logError(
|
||||
LogModule.GITHUB,
|
||||
"Failed to parse versions: No versions found in response."
|
||||
);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@ -172,7 +252,7 @@ export const initGitHubApi = () => {
|
||||
*/
|
||||
ipcMain.on("github.getFrpVersions", async (event, mirror: string) => {
|
||||
const mirrorUrl = conventMirrorUrl(mirror);
|
||||
log.info("request mirror Url", mirrorUrl);
|
||||
log.info("Requesting mirror URL: ", mirrorUrl);
|
||||
const request = net.request({
|
||||
method: "get",
|
||||
url: `${mirrorUrl}/repos/fatedier/frp/releases?page=1&per_page=1000`
|
||||
@ -180,7 +260,7 @@ export const initGitHubApi = () => {
|
||||
|
||||
let githubReleaseJsonStr = null;
|
||||
request.on("response", response => {
|
||||
log.info("request mirror Status Code", response.statusCode);
|
||||
log.info("Received response with status code: ", response.statusCode);
|
||||
let responseData: Buffer = Buffer.alloc(0);
|
||||
response.on("data", (data: Buffer) => {
|
||||
responseData = Buffer.concat([responseData, data]);
|
||||
@ -188,8 +268,16 @@ export const initGitHubApi = () => {
|
||||
response.on("end", () => {
|
||||
if (response.statusCode === 200) {
|
||||
githubReleaseJsonStr = responseData.toString();
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
"Successfully retrieved GitHub release data."
|
||||
);
|
||||
} else {
|
||||
log.info("use local json", response.statusCode);
|
||||
logWarn(
|
||||
LogModule.GITHUB,
|
||||
"Failed to retrieve data, using local JSON instead. Status code: " +
|
||||
response.statusCode
|
||||
);
|
||||
githubReleaseJsonStr = JSON.stringify(frpReleasesJson);
|
||||
}
|
||||
const versions = handleApiResponse(githubReleaseJsonStr);
|
||||
@ -198,7 +286,10 @@ export const initGitHubApi = () => {
|
||||
});
|
||||
|
||||
request.on("error", error => {
|
||||
log.info("error use local json", error);
|
||||
logError(
|
||||
LogModule.GITHUB,
|
||||
"Error occurred while requesting GitHub releases: " + error
|
||||
);
|
||||
githubReleaseJsonStr = JSON.stringify(frpReleasesJson);
|
||||
const versions = handleApiResponse(githubReleaseJsonStr);
|
||||
event.reply("Download.frpVersionHook", versions);
|
||||
@ -221,7 +312,11 @@ export const initGitHubApi = () => {
|
||||
url = "https://mirror.ghproxy.com/" + url;
|
||||
}
|
||||
|
||||
log.info(`开始下载frp url:${url} asset:${asset.name}`);
|
||||
logDebug(
|
||||
LogModule.GITHUB,
|
||||
`Starting download for versionId: ${versionId}, mirror: ${mirror}, download URL: ${url}`
|
||||
);
|
||||
|
||||
// 数据目录
|
||||
await download(BrowserWindow.getFocusedWindow(), url, {
|
||||
filename: `${asset.name}`,
|
||||
@ -231,29 +326,54 @@ export const initGitHubApi = () => {
|
||||
id: versionId,
|
||||
progress: progress
|
||||
});
|
||||
logDebug(
|
||||
LogModule.GITHUB,
|
||||
`Download progress for versionId: ${versionId} is ${progress}%`
|
||||
);
|
||||
},
|
||||
onCompleted: () => {
|
||||
log.info(`frp下载完成 url:${url} asset:${asset.name}`);
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Download completed for versionId: ${versionId}, asset: ${asset.name}`
|
||||
);
|
||||
|
||||
const targetPath = path.resolve(
|
||||
path.join(app.getPath("userData"), "frp")
|
||||
);
|
||||
const ext = path.extname(asset.name);
|
||||
let frpcVersionPath = "";
|
||||
if (ext === ".zip") {
|
||||
frpcVersionPath = unZip(
|
||||
path.join(
|
||||
path.join(app.getPath("userData"), "download"),
|
||||
`${asset.name}`
|
||||
),
|
||||
targetPath
|
||||
);
|
||||
} else if (ext === ".gz" && asset.name.includes(".tar.gz")) {
|
||||
frpcVersionPath = unTarGZ(
|
||||
path.join(
|
||||
path.join(app.getPath("userData"), "download"),
|
||||
`${asset.name}`
|
||||
),
|
||||
targetPath
|
||||
|
||||
try {
|
||||
if (ext === ".zip") {
|
||||
frpcVersionPath = unZip(
|
||||
path.join(
|
||||
path.join(app.getPath("userData"), "download"),
|
||||
`${asset.name}`
|
||||
),
|
||||
targetPath
|
||||
);
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Unzipped file to path: ${frpcVersionPath}`
|
||||
);
|
||||
} else if (ext === ".gz" && asset.name.includes(".tar.gz")) {
|
||||
frpcVersionPath = unTarGZ(
|
||||
path.join(
|
||||
path.join(app.getPath("userData"), "download"),
|
||||
`${asset.name}`
|
||||
),
|
||||
targetPath
|
||||
);
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Untarred file to path: ${frpcVersionPath}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
logError(
|
||||
LogModule.GITHUB,
|
||||
`Error during extraction: ${error.message}`
|
||||
);
|
||||
}
|
||||
|
||||
@ -264,7 +384,13 @@ export const initGitHubApi = () => {
|
||||
event.reply("Config.versions.hook", { err, data: doc });
|
||||
event.reply("Download.frpVersionDownloadOnCompleted", versionId);
|
||||
version.download_completed = true;
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Version ${versionId} has been inserted successfully.`
|
||||
);
|
||||
});
|
||||
} else {
|
||||
logError(LogModule.GITHUB, `Error inserting version: ${err}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -276,17 +402,34 @@ export const initGitHubApi = () => {
|
||||
*/
|
||||
ipcMain.on("github.deleteVersion", async (event, args) => {
|
||||
const { absPath, id } = args;
|
||||
logDebug(
|
||||
LogModule.GITHUB,
|
||||
`Attempting to delete version with ID: ${id} and path: ${absPath}`
|
||||
);
|
||||
if (fs.existsSync(absPath)) {
|
||||
deleteVersionById(id, () => {
|
||||
fs.unlinkSync(absPath);
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
`Successfully deleted version with ID: ${id}`
|
||||
);
|
||||
});
|
||||
} else {
|
||||
logWarn(
|
||||
LogModule.GITHUB,
|
||||
`Version with ID: ${id} not found at path: ${absPath}`
|
||||
);
|
||||
}
|
||||
listVersion((err, doc) => {
|
||||
event.reply("Config.versions.hook", { err, data: doc });
|
||||
event.reply("Download.deleteVersion.hook", {
|
||||
err: null,
|
||||
data: "删除成功"
|
||||
});
|
||||
if (err) {
|
||||
logError(LogModule.GITHUB, `Error listing versions: ${err}`);
|
||||
} else {
|
||||
event.reply("Config.versions.hook", { err, data: doc });
|
||||
event.reply("Download.deleteVersion.hook", {
|
||||
err: null,
|
||||
data: "删除成功"
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -294,6 +437,7 @@ export const initGitHubApi = () => {
|
||||
* 获取最后版本
|
||||
*/
|
||||
ipcMain.on("github.getFrpcDesktopLastVersions", async event => {
|
||||
logInfo(LogModule.GITHUB, "Requesting the latest version from GitHub.");
|
||||
const request = net.request({
|
||||
method: "get",
|
||||
url: "https://api.github.com/repos/luckjiawei/frpc-desktop/releases/latest"
|
||||
@ -304,26 +448,24 @@ export const initGitHubApi = () => {
|
||||
responseData = Buffer.concat([responseData, data]);
|
||||
});
|
||||
response.on("end", () => {
|
||||
versions = JSON.parse(responseData.toString());
|
||||
// const borderContent: Electron.WebContents =
|
||||
// BrowserWindow.getFocusedWindow().webContents;
|
||||
// const downloadPath = path.join(app.getPath("userData"), "download");
|
||||
// log.info(`开始获取frp版本 当前架构:${currArch} 对应frp架构:${frpArch}`)
|
||||
// const returnVersionsData = versions
|
||||
// .filter(f => getAdaptiveAsset(f.id))
|
||||
// .map(m => {
|
||||
// const asset = getAdaptiveAsset(m.id);
|
||||
// if (asset) {
|
||||
// const absPath = `${downloadPath}/${asset.name}`;
|
||||
// m.absPath = absPath;
|
||||
// m.download_completed = fs.existsSync(absPath);
|
||||
// }
|
||||
// return m;
|
||||
// });
|
||||
// log.debug(`获取到frp版本:${JSON.stringify(returnVersionsData)}`)
|
||||
event.reply("github.getFrpcDesktopLastVersionsHook", versions);
|
||||
try {
|
||||
versions = JSON.parse(responseData.toString());
|
||||
logInfo(
|
||||
LogModule.GITHUB,
|
||||
"Successfully retrieved the latest version."
|
||||
);
|
||||
event.reply("github.getFrpcDesktopLastVersionsHook", versions);
|
||||
} catch (error) {
|
||||
logError(
|
||||
LogModule.GITHUB,
|
||||
`Error parsing response data: ${error.message}`
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
request.on("error", error => {
|
||||
logError(LogModule.GITHUB, `Request error: ${error.message}`);
|
||||
});
|
||||
request.end();
|
||||
});
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {ipcMain} from "electron";
|
||||
import log from "electron-log";
|
||||
import { logDebug, logError, logInfo, LogModule, logWarn } from "electron/utils/log";
|
||||
|
||||
const {exec, spawn} = require("child_process");
|
||||
|
||||
@ -15,19 +15,19 @@ export const initLocalApi = () => {
|
||||
: 'netstat -an | grep LISTEN';
|
||||
|
||||
ipcMain.on("local.getLocalPorts", async (event, args) => {
|
||||
log.info("开始获取本地端口")
|
||||
logInfo(LogModule.APP, "Starting to retrieve local ports");
|
||||
// 执行命令
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
log.error(`getLocalPorts - error ${error.message}`)
|
||||
logError(LogModule.APP, `getLocalPorts - error: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
log.error(`getLocalPorts - stderr ${stderr}`)
|
||||
logWarn(LogModule.APP, `getLocalPorts - stderr: ${stderr}`);
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug(`sc ${stdout}`)
|
||||
logDebug(LogModule.APP, `Command output: ${stdout}`);
|
||||
let ports = [];
|
||||
if (stdout) {
|
||||
if (process.platform === 'win32') {
|
||||
@ -72,7 +72,6 @@ export const initLocalApi = () => {
|
||||
}
|
||||
return singe;
|
||||
})
|
||||
// .filter(f => f.indexOf('TCP') > 0 || f.indexOf('UDP') > 0)
|
||||
|
||||
} else if (process.platform === 'linux') {
|
||||
ports = stdout.split('\n')
|
||||
|
@ -8,10 +8,16 @@ import {
|
||||
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
|
||||
@ -21,8 +27,12 @@ export const initProxyApi = () => {
|
||||
|
||||
ipcMain.on("proxy.insertProxy", async (event, args) => {
|
||||
delete args["_id"];
|
||||
logInfo(LogModule.APP, "Inserting a new proxy.");
|
||||
insertProxy(args, (err, documents) => {
|
||||
if (!err) {
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error inserting proxy: ${err.message}`);
|
||||
} else {
|
||||
logInfo(LogModule.APP, "Proxy inserted successfully.");
|
||||
reloadFrpcProcess();
|
||||
}
|
||||
event.reply("Proxy.insertProxy.hook", {
|
||||
@ -33,8 +43,12 @@ export const initProxyApi = () => {
|
||||
});
|
||||
|
||||
ipcMain.on("proxy.deleteProxyById", async (event, args) => {
|
||||
logInfo(LogModule.APP, `Deleting proxy with ID: ${args._id}`);
|
||||
deleteProxyById(args, (err, documents) => {
|
||||
if (!err) {
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error deleting proxy: ${err.message}`);
|
||||
} else {
|
||||
logInfo(LogModule.APP, "Proxy deleted successfully.");
|
||||
reloadFrpcProcess();
|
||||
}
|
||||
event.reply("Proxy.deleteProxyById.hook", {
|
||||
@ -45,7 +59,13 @@ export const initProxyApi = () => {
|
||||
});
|
||||
|
||||
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
|
||||
@ -54,9 +74,16 @@ export const initProxyApi = () => {
|
||||
});
|
||||
|
||||
ipcMain.on("proxy.updateProxy", async (event, args) => {
|
||||
if (!args._id) return;
|
||||
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) {
|
||||
if (err) {
|
||||
logError(LogModule.APP, `Error updating proxy: ${err.message}`);
|
||||
} else {
|
||||
logInfo(LogModule.APP, "Proxy updated successfully.");
|
||||
reloadFrpcProcess();
|
||||
}
|
||||
event.reply("Proxy.updateProxy.hook", {
|
||||
@ -67,10 +94,16 @@ export const initProxyApi = () => {
|
||||
});
|
||||
|
||||
ipcMain.on("proxy.updateProxyStatus", async (event, args) => {
|
||||
console.log("更新状态", args);
|
||||
if (!args._id) return;
|
||||
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) {
|
||||
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", {
|
||||
|
@ -2,7 +2,6 @@ import {app, dialog, autoUpdater, BrowserWindow} from "electron";
|
||||
|
||||
const log = require('electron-log');
|
||||
|
||||
|
||||
export const initUpdaterApi = (win: BrowserWindow) => {
|
||||
//更新测试打开
|
||||
Object.defineProperty(app, 'isPackaged', {
|
||||
@ -56,10 +55,7 @@ export const initUpdaterApi = (win: BrowserWindow) => {
|
||||
|
||||
})
|
||||
|
||||
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
console.log('update-downloaded')
|
||||
|
||||
dialog.showMessageBox({
|
||||
type: 'info',
|
||||
title: '应用更新',
|
||||
|
@ -2,9 +2,7 @@ export const maskSensitiveData = (
|
||||
obj: Record<string, any>,
|
||||
keysToMask: string[]
|
||||
) => {
|
||||
console.log("obj", obj);
|
||||
const maskedObj = JSON.parse(JSON.stringify(obj));
|
||||
console.log("masked", maskedObj);
|
||||
keysToMask.forEach(key => {
|
||||
if (maskedObj.hasOwnProperty(key)) {
|
||||
maskedObj[key] = "***";
|
||||
|
@ -3,10 +3,9 @@ import log from "electron-log";
|
||||
export enum LogModule {
|
||||
APP = "app",
|
||||
FRP_CLIENT = "frpc client",
|
||||
PROXY = "proxy",
|
||||
DOWNLOAD = "download",
|
||||
SETTING = "setting",
|
||||
LOGGER = "logger"
|
||||
LOGGER = "logger",
|
||||
GITHUB = "github",
|
||||
STORAGE = "",
|
||||
}
|
||||
|
||||
// 设置日志级别
|
||||
|
Loading…
Reference in New Issue
Block a user