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