[🛠️ Fix] Invalid log dir path (#24) & Remove PLS trust token

1. [-] 删除了 PLS 的 Trust token 认证机制
2. [+] 现在可以在 `偏好设置` - `调试选项` 中直接打开日志文件夹了
3. [/] 日志目录不再使用 `%USERPROFILE%\Documents\HugoAura\logs` 为基准, 而是从注册表获取值
4. [/] 配置文件目录同理, 旧版配置文件将会自动迁移到新位置
This commit is contained in:
Minoricew
2025-06-16 21:24:10 +08:00
parent dae0f033a5
commit a638a29cc6
13 changed files with 274 additions and 88 deletions

View File

@@ -77,6 +77,7 @@ const buildIpcMain = (electron) => {
};
const { applyBaseIpcHandler } = require("./ipcModules/baseIpcHandler");
const { applyDebugIpcHandler } = require("./ipcModules/debugIpcHandler");
const { applyConfigIpcHandler } = require("./ipcModules/configIpcHandler");
const { applyFsIpcHandler } = require("./ipcModules/fsIpcHandler");
const { applyPlsIpcHandler } = require("./ipcModules/plsIpcHandler");
@@ -87,6 +88,7 @@ const buildIpcMain = (electron) => {
});
applyBaseIpcHandler(ipcMain);
applyDebugIpcHandler(ipcMain);
applyConfigIpcHandler(ipcMain);
applyFsIpcHandler(ipcMain);
applyPlsIpcHandler(ipcMain);

View File

@@ -0,0 +1,20 @@
// @ts-check
const __SCOPE = "main";
/**
*
* @param {import("electron").IpcMain} ipcMain
*/
const applyDebugIpcHandler = (ipcMain) => {
const methodBase = "$aura.debug";
ipcMain.handle(`${methodBase}.getLogDirAsync`, (_evt, _arg) => {
return {
success: true,
data: global.__HUGO_AURA__.logDir,
};
});
};
module.exports = { applyDebugIpcHandler };

View File

@@ -2,13 +2,43 @@ const path = require("path");
const fs = require("fs");
const os = require("os");
const util = require("util");
const RegistryManager = require("../shared/registryManager");
const getUserDocumentsDirPath = () => {
const registryManager = new RegistryManager();
const pathInfo = registryManager.readRegKeySync(
'"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"',
"Personal",
false,
true,
/REG_EXPAND_SZ\s+(.+)/
);
if (pathInfo.success) {
const resolvedPath = pathInfo.data.replace(
/%([^%]+)%/g,
(match, varName) => {
return process.env[varName] || match;
}
);
return resolvedPath;
} else {
console.error(
"[HugoAura / Init / Logger] Failed to get the path of documents dir, using default val."
);
return path.join(os.homedir(), "Documents");
}
};
/**
*
* @param {import("../aura/types/main/core").WindowName} windowName
*/
const initLogger = (windowName) => {
const logDir = path.join(os.homedir(), "Documents", "HugoAura", "logs");
const logDir = path.join(getUserDocumentsDirPath(), "HugoAura", "logs");
global.__HUGO_AURA__.logDir = logDir;
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
@@ -64,25 +94,22 @@ const initLogger = (windowName) => {
console.error("[CRITICAL] UNCAUGHT EXCEPTION:", err);
});
console.log(
"[HugoAura / Logger] Logger initialized. Log file:",
logFile
);
console.log("[HugoAura / Logger] Logger initialized. Log file:", logFile);
};
const cleanupOldLogs = (logDir) => {
try {
const files = fs.readdirSync(logDir);
const now = new Date();
const sevenDaysAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
const daysAgo = new Date(now.getTime() - 15 * 24 * 60 * 60 * 1000);
files.forEach((file) => {
if (file.endsWith(".log")) {
const filePath = path.join(logDir, file);
const stats = fs.statSync(filePath);
// 如果文件创建时间超过 30 天, 则删除
if (stats.birthtime < sevenDaysAgo) {
// 如果文件创建时间超过两周, 则删除
if (stats.birthtime < daysAgo) {
fs.unlinkSync(filePath);
console.log(
`[HugoAura / Logger / Cleanup] Cleaned log file: ${file}`
@@ -91,7 +118,10 @@ const cleanupOldLogs = (logDir) => {
}
});
} catch (error) {
console.error("[HugoAura / Logger / Cleanup] Unexpected error occurred cleaning log file:", error);
console.error(
"[HugoAura / Logger / Cleanup] Unexpected error occurred cleaning log file:",
error
);
}
};

View File

@@ -69,7 +69,7 @@ const deepMerge = (target, source) => {
class ConfigManager {
constructor() {
this.configDir = path.join(os.homedir(), "Documents", "HugoAura");
this.configDir = path.join(global.__HUGO_AURA__.logDir, "..");
this.configPath = path.join(this.configDir, "config.json");
this.encConfigPath = path.join(this.configDir, ".cache_2eafc8d0.dat"); // (雾
/* ↑ 不使用 .tmp 扩展名, 不然容易真被清理了 */
@@ -95,6 +95,33 @@ class ConfigManager {
}
}
migrateOldConfigFile() {
const oldConfigPath = path.join(
os.homedir(),
"Documents",
"HugoAura",
"config.json"
);
const oldEncConfigPath = path.join(
os.homedir(),
"Documents",
"HugoAura",
".cache_2eafc8d0.dat"
);
if (fs.existsSync(oldConfigPath)) {
fs.copyFileSync(oldConfigPath, this.configPath);
fs.unlinkSync(oldConfigPath);
} else if (fs.existsSync(oldEncConfigPath)) {
fs.copyFileSync(oldEncConfigPath, this.encConfigPath);
fs.unlinkSync(oldEncConfigPath);
this.useEncConfig = true;
}
console.log(
`[HugoAura / Config] Moved old config file to ${this.configDir}`
);
}
getHugoAuraConfigPath() {
return path.dirname(
this.useEncConfig ? this.encConfigPath : this.configPath

View File

@@ -6,7 +6,12 @@ const { exec, execSync } = require("child_process");
const LOG_PREFIX = "[HugoAura / Init / Reg";
const LOG_PREFIX_FUNC = "[HugoAura / Reg";
const AURA_REGISTRY_PATH = ["HKEY_USERS", ".DEFAULT", "SOFTWARE", "HugoAura"].join("\\");
const AURA_REGISTRY_PATH = [
"HKEY_USERS",
".DEFAULT",
"SOFTWARE",
"HugoAura",
].join("\\");
class RegistryManager {
/**
@@ -341,19 +346,27 @@ class RegistryManager {
}
/**
* @param {string} relativePath
* @param {string} keyPath
* @param {string} keyName
* @param {boolean | undefined} silent
* @param {boolean} absolute
* @param {any} regex
* @returns {Promise<{ success: boolean, data: string | null, error: Error | null }>}
*/
async readRegKey(relativePath, keyName, silent = false) {
async readRegKey(
keyPath,
keyName,
silent = false,
absolute = false,
regex = null
) {
try {
const { stdout } = await new Promise((resolve, reject) => {
exec(
[
"reg",
"query",
[AURA_REGISTRY_PATH, relativePath].join("\\"),
absolute ? keyPath : [AURA_REGISTRY_PATH, keyPath].join("\\"),
"/v",
`\"${keyName}\"`,
].join(" "),
@@ -367,12 +380,12 @@ class RegistryManager {
if (!silent) {
console.debug(
`${LOG_PREFIX_FUNC} / SUCCESS] Successfully read reg key ${relativePath}/${keyName}, stdout:`,
`${LOG_PREFIX_FUNC} / SUCCESS] Successfully read reg key ${keyPath}/${keyName}, stdout:`,
stdout
);
}
const match = stdout.match(/REG_SZ\s+(.+)/);
const match = regex ? stdout.match(regex) : stdout.match(/REG_SZ\s+(.+)/);
if (!match) {
console.warn(`${LOG_PREFIX} / WARN] Data not found in stdout`);
@@ -390,10 +403,7 @@ class RegistryManager {
error: null,
};
} catch (e) {
console.error(
`${LOG_PREFIX} / ERROR] Failed to read reg key, error:`,
e
);
console.error(`${LOG_PREFIX} / ERROR] Failed to read reg key, error:`, e);
return {
success: false,
data: null,
@@ -403,18 +413,26 @@ class RegistryManager {
}
/**
* @param {string} relativePath
* @param {string} keyPath
* @param {string} keyName
* @param {boolean | undefined} silent
* @param {boolean} absolute
* @param {any} regex
* @returns {{ success: boolean, data: string | null, error: Error | null }}
*/
readRegKeySync(relativePath, keyName, silent = false) {
readRegKeySync(
keyPath,
keyName,
silent = false,
absolute = false,
regex = null
) {
try {
const readResult = execSync(
[
"reg",
"query",
[AURA_REGISTRY_PATH, relativePath].join("\\"),
absolute ? keyPath : [AURA_REGISTRY_PATH, keyPath].join("\\"),
"/v",
`\"${keyName}\"`,
].join(" "),
@@ -424,11 +442,13 @@ class RegistryManager {
if (readResult) {
if (!silent) {
console.debug(
`${LOG_PREFIX_FUNC} / SUCCESS] Successfully read reg key ${relativePath}/${keyName}, stdout:`,
`${LOG_PREFIX_FUNC} / SUCCESS] Successfully read reg key ${keyPath}/${keyName}, stdout:`,
readResult
);
}
const match = readResult.match(/REG_SZ\s+(.+)/);
const match = regex
? readResult.match(regex)
: readResult.match(/REG_SZ\s+(.+)/);
if (!match) {
console.warn(`${LOG_PREFIX} / WARN] Data not found in stdout`);

View File

@@ -14,6 +14,7 @@ interface GlobalHugoAuraInfo {
fsTasks?: MainProcessOnlyVal<FSTasks>;
hookedWindows?: MainProcessOnlyVal<HookedWindowsMap>;
ipcInit?: MainProcessOnlyVal<boolean>;
logDir: MainProcessOnlyVal<string>;
plsRules?: Record<any, any> | null;
plsSettings?: Record<any, any> | null;
plsStats?: PLSStatus | null;

View File

@@ -170,6 +170,23 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
operationArea.classList.add("ase-operation-area-expanded");
return inputEl;
}
case "button": {
const btnEl = document.createElement("button");
btnEl.type = "button";
btnEl.classList.add("btn");
switch (entry.style) {
case "outline":
default:
btnEl.classList.add("btn-outline-primary");
break;
}
btnEl.innerHTML = entry.buttonContent;
btnEl.onclick = entry.callbackFn;
(async () => {
descriptionArea.innerHTML = await entry.valueGetter();
})();
return btnEl;
}
default:
break;
}

View File

@@ -45,8 +45,7 @@
};
const calcFullAuthToken = (/** @type {string} */ authToken) => {
const trustToken = window._ACCEPT_DATA.getData("deviceId");
const conjToken = authToken + "AuraXAuth" + trustToken + "NeverEnds";
const conjToken = authToken + "AuraXAuth 0xFFFFFF NeverEnds";
const crypto = require("crypto");
return crypto.createHash("sha512").update(conjToken).digest("hex");
};

View File

@@ -17,6 +17,20 @@
Aura 设置
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
id="debug-subpage-tab"
data-bs-toggle="pill"
data-bs-target="#debug-subpage"
type="button"
role="tab"
aria-controls="debug-subpage"
aria-selected="false"
>
调试选项
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
@@ -26,7 +40,7 @@
type="button"
role="tab"
aria-controls="about-subpage"
aria-selected="true"
aria-selected="false"
>
关于项目
</button>
@@ -39,6 +53,12 @@
role="tabpanel"
aria-labelledby="aura-subpage-tab"
></div>
<div
class="tab-pane fade"
id="debug-subpage"
role="tabpanel"
aria-labelledby="debug-subpage-tab"
></div>
<div
class="tab-pane fade"
id="about-subpage"

View File

@@ -5,13 +5,21 @@
settingsRenderer,
} = require("../../aura/ui/composables/settingsRenderer");
const { auraSettings } = require(`${pathBase}/aura`);
const { debugSettings } = require(`${pathBase}/debug`);
const initAuraSubPage = () => {
const auraSettingsSubPageEl = document.getElementById("aura-subpage");
settingsRenderer(auraSettingsSubPageEl, auraSettings);
};
const initDebugSubPage = () => {
const debugSubPageEl = document.getElementById("debug-subpage");
settingsRenderer(debugSubPageEl, debugSettings);
};
const onMounted = () => {
initAuraSubPage();
initDebugSubPage();
const rootEl = document.getElementById("acs-preferences-root-el");
setTimeout(() => {

View File

@@ -0,0 +1,40 @@
const IPC_METHOD_BASE = "$aura.debug";
const debugSettings = [
{
id: 0,
categoryName: "日志与输出",
child: [
{
index: 0,
id: "openHugoAuraLogDir",
type: "button",
style: "outline",
name: "HugoAura 日志目录",
description: "",
restart: false,
reload: false,
associateVal: null,
auraIf: () => true,
buttonContent: "打开",
valueGetter: async () => {
const ipcRendererRet = await ipcRenderer.invoke(
`${IPC_METHOD_BASE}.getLogDirAsync`
);
if (ipcRendererRet.success && ipcRendererRet.data !== "") {
global.__HUGO_AURA__.logDir = ipcRendererRet.data;
return "目录位置: " + ipcRendererRet.data;
} else {
return "未能获取日志目录位置";
}
},
callbackFn: async (event) => {
const childProc = require("child_process");
childProc.spawn(`explorer.exe`, [`${global.__HUGO_AURA__.logDir}`]);
},
},
],
},
];
module.exports = { debugSettings };

View File

@@ -6,6 +6,7 @@ if (!global.__HUGO_AURA__) {
configInit: false,
central: () => {},
ipcInit: false,
logDir: "",
plsStats: null,
plsSettings: null,
plsRules: null,
@@ -24,7 +25,7 @@ if (!global.__HUGO_AURA_API__) {
"https://api-aura.asaka.site",
"https://api.hugoaura.dpdns.org",
"https://api-aura-projekts.minorice.moe",
"https://api.aura.vim.moe"
"https://api.aura.vim.moe",
],
plsUpdate: "/api/getPLSLatestVersion",
auraUpdate: "/api/getAuraLatestVersion",
@@ -79,6 +80,7 @@ const launcher = ({ central, windowName, config }) => {
// >>> Init Config <<< //
const configManager = new ConfigManager();
configManager.side = "main";
configManager.migrateOldConfigFile();
configManager.ensureConfigExists();
const loadedConfig = configManager.loadConfig();
if (!global.__HUGO_AURA__.configInit) global.__HUGO_AURA__.configInit = true;