diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/jsconfig.json b/jsconfig.json new file mode 100755 index 0000000..7f3328e --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "target": "ES2015", + "allowImportingTsExtensions": false, + "strictNullChecks": true, + "strictFunctionTypes": true + } +} \ No newline at end of file diff --git a/scripts/cd.bat b/scripts/cd.bat old mode 100644 new mode 100755 diff --git a/scripts/kad.bat b/scripts/kad.bat old mode 100644 new mode 100755 diff --git a/scripts/kar.bat b/scripts/kar.bat old mode 100644 new mode 100755 diff --git a/src/aura/init/main/ipcHandler.js b/src/aura/init/main/ipcHandler.js old mode 100644 new mode 100755 index bc4b181..5d4f69b --- a/src/aura/init/main/ipcHandler.js +++ b/src/aura/init/main/ipcHandler.js @@ -1,10 +1,64 @@ +// @ts-check + +const __SCOPE = "main"; + +/** + * + * @param {import("electron")} electron + */ const buildIpcMain = (electron) => { - const { app, ipcMain } = electron; + const { app } = electron; + /** + * @type {import("../../types/main/electron").AuraIPCMain} + */ + // @ts-ignore + const ipcMain = electron.ipcMain; + + /** + * + * @param {string} windowKey + * @param {string} channel + * @param {any} data + * @param {import("electron").WebContents?} grep + */ + ipcMain.send = (windowKey, channel, data, grep = null) => { + /** + * + * @param {string} key + * @param {string} chan + * @param {any} targetData + */ + const sendDataToWebContents = (key, chan, targetData) => { + const webContents = + global.__HUGO_AURA__.hookedWindows.get(key).webContents; + + if (grep !== webContents) webContents.send(chan, targetData); + }; + + if (windowKey === "*") { + for (const perWindow of global.__HUGO_AURA__.hookedWindows.keys()) { + sendDataToWebContents(perWindow, channel, data); + } + } else { + const isWindowValid = global.__HUGO_AURA__.hookedWindows.has(windowKey); + if (!isWindowValid) { + throw new Error( + `[HugoAura / Main / IPC / ERROR] Unknown windowKey: ${windowKey}` + ); + } + + sendDataToWebContents(windowKey, channel, data); + } + }; + + const { applyPlsIpcHandler } = require("./ipcModules/plsIpcHandler"); ipcMain.handle("$aura.base.restartApplication", async () => { app.relaunch(); app.exit(0); }); + + applyPlsIpcHandler(ipcMain); }; module.exports = { buildIpcMain }; diff --git a/src/aura/init/main/ipcModules/plsIpcHandler.js b/src/aura/init/main/ipcModules/plsIpcHandler.js new file mode 100755 index 0000000..cb27fff --- /dev/null +++ b/src/aura/init/main/ipcModules/plsIpcHandler.js @@ -0,0 +1,190 @@ +// @ts-check + +const __SCOPE = "main"; + +const fs = require("fs"); +const path = require("path"); + +/** + * + * @param {import("../../../types/main/electron").AuraIPCMain} ipcMain + */ +const applyPlsIpcHandler = (ipcMain) => { + const methodBase = "$aura.pls"; + + const isPlsDetached = process.argv.includes("--pls-detach"); + + global.__HUGO_AURA__.plsStats = { + installed: false, + launched: false, + detached: isPlsDetached, + connected: false, + version: "未知", + status: "dead", + authToken: global.__HUGO_AURA_CONFIG__.plsToken, + }; + + ipcMain.handle( + `${methodBase}.getPlsFolderExists`, + /** + * + * @returns {{ success: boolean; data: { isExists: boolean }; error?: Error }} + */ + (_event, _arg) => { + const plsFolderPath = path.join(__dirname, "../../../proxy"); + try { + const result = fs.existsSync(plsFolderPath); + return { + success: true, + data: { isExists: result }, + }; + } catch (e) { + return { + success: false, + data: { isExists: false }, + error: e, + }; + } + } + ); + + ipcMain.handle( + `${methodBase}.getPlsStats`, + /** + * + * @returns {{ success: boolean; data: PLSStatus; }} + */ + (_event, _arg) => { + return { + success: true, + data: global.__HUGO_AURA__.plsStats, + }; + } + ); + + ipcMain.handle( + `${methodBase}.updatePlsStats`, + /** + * + * @param {import("electron").IpcMainInvokeEvent} _event + * @param {PLSStatus} arg + * @returns + */ + (_event, arg) => { + global.__HUGO_AURA__.plsStats = arg; + ipcMain.send("assistant", `${methodBase}.post.onPlsStatsUpdate`, arg); + return { + success: true, + }; + } + ); + + ipcMain.handle( + `${methodBase}.getPlsSettings`, + /** + * + * @returns {{ success: boolean; data: Record }} + */ + (_event, _arg) => { + return { + success: true, + data: global.__HUGO_AURA__.plsSettings, + }; + } + ); + + ipcMain.handle( + `${methodBase}.updatePlsSettings`, + /** + * + * @param {import("electron").IpcMainInvokeEvent} _event + * @param {Record} arg + * @returns + */ + (_event, arg) => { + global.__HUGO_AURA__.plsSettings = arg; + return { + success: true, + }; + } + ); + + ipcMain.handle( + `${methodBase}.getPlsRules`, + /** + * + * @returns {{ success: boolean; data: Record }} + */ + (_event, _arg) => { + return { + success: true, + data: global.__HUGO_AURA__.plsRules, + }; + } + ); + + ipcMain.handle( + `${methodBase}.updatePlsRules`, + /** + * + * @param {import("electron").IpcMainInvokeEvent} _event + * @param {Record} arg + * @returns + */ + (_event, arg) => { + global.__HUGO_AURA__.plsRules = arg; + return { + success: true, + }; + } + ); + + ipcMain.on( + `${methodBase}.ws.broadcastMessageRecv`, + /** + * + * @param {import("electron").IpcMainEvent} _event + * @param {PLSResponse} arg + */ + (_event, arg) => { + ipcMain.send("assistant", `${methodBase}.ws.post.onNewMsgRecv`, arg); + } + ); + + ipcMain.handle( + `${methodBase}.ws.sendWsMessage`, + /** + * + * @param {import("electron").IpcMainInvokeEvent} _event + * @param {ClientPLSRequest} arg + */ + (_event, arg) => { + ipcMain.send( + "desktopAssistant", + `${methodBase}.ws.post.onReqSendMsg`, + arg + ); + } + ); + + ipcMain.handle( + `${methodBase}.syncPlsConfig`, + /** + * + * @param {import("electron").IpcMainInvokeEvent} event + * @param {{ basic: Record, rules: Record }} arg + */ + (event, arg) => { + global.__HUGO_AURA__.plsRules = arg.rules; + global.__HUGO_AURA__.plsSettings = arg.basic; + + ipcMain.send("*", `${methodBase}.syncPlsConfig`, arg, event.sender); + + return { + success: true, + }; + } + ); +}; + +module.exports = { applyPlsIpcHandler }; diff --git a/src/aura/init/preload/webpackHook.js b/src/aura/init/preload/webpackHook.js old mode 100644 new mode 100755 diff --git a/src/aura/init/rendererHook/hooksManager.js b/src/aura/init/rendererHook/hooksManager.js old mode 100644 new mode 100755 index ad68e83..bf9a766 --- a/src/aura/init/rendererHook/hooksManager.js +++ b/src/aura/init/rendererHook/hooksManager.js @@ -1,13 +1,20 @@ +// @ts-check + const fs = require("fs"); const path = require("path"); class HooksManager { loadHooks() { - if (global.__HUGO_AURA__.hooks) { + if ( + global.__HUGO_AURA__.hooks && + Object.keys(global.__HUGO_AURA__.hooks).length !== 0 + ) { return global.__HUGO_AURA__.hooks; } - const hooksPath = path.join(__dirname, "../../../aura/ui/hooks"); + const hooksPath = path.join(__dirname, "../../../aura/ui/hookDefinitions"); + + /** @type {import("../../types/main/core").HooksMap} */ const hooks = new Map(); try { @@ -17,6 +24,7 @@ class HooksManager { try { const hook = require(path.join(hooksPath, file)); + /** @type {import("../../types/main/core").WindowName} */ const targetWindow = hook.windowName || path.basename(file, ".js"); hooks.set(targetWindow, hook); console.log( @@ -40,13 +48,19 @@ class HooksManager { return hooks; } - cleanupWindow(windowKey, listeners) { + /** + * + * @param {import("../../types/main/core").WindowName} windowKey + * @param {import("../../types/main/core").HookedWindow} hookedWindowProps + */ + cleanupWindow(windowKey, hookedWindowProps) { console.log( `[HugoAura / Cleanup / ${windowKey}] Window destroyed, cleaning up...` ); - if (listeners) { - const { webContents, domReadyListener, destroyedListener } = listeners; + if (hookedWindowProps) { + const { webContents, domReadyListener, destroyedListener } = + hookedWindowProps; webContents.removeListener("dom-ready", domReadyListener); webContents.removeListener("destroyed", destroyedListener); } @@ -54,9 +68,17 @@ class HooksManager { global.__HUGO_AURA__.hookedWindows.delete(windowKey); } + /** + * + * @param {import("electron").WebContents} webContents + * @param {import("../../types/render/uiHook").UIHookConfigFin} hookConfig + * @param {import("../../types/main/core").WindowName} windowName + * @returns + */ handleWindowHook(webContents, hookConfig, windowName) { if (!hookConfig) return; + /** @type {import("../../types/main/core").WindowName} */ const windowKey = `${hookConfig.windowName || windowName}`; if (global.__HUGO_AURA__.hookedWindows.has(windowKey)) { console.log( diff --git a/src/aura/init/rendererHook/injection.js b/src/aura/init/rendererHook/injection.js old mode 100644 new mode 100755 diff --git a/src/aura/init/rendererHook/networkHook.js b/src/aura/init/rendererHook/networkHook.js old mode 100644 new mode 100755 diff --git a/src/aura/init/shared/configManager.js b/src/aura/init/shared/configManager.js old mode 100644 new mode 100755 diff --git a/src/aura/init/shared/default.json b/src/aura/init/shared/default.json old mode 100644 new mode 100755 index e27f0fd..e5fa983 --- a/src/aura/init/shared/default.json +++ b/src/aura/init/shared/default.json @@ -18,5 +18,6 @@ "enabled": true } }, + "plsToken": "66ccff0d000721114514191981023333", "devTools": false } diff --git a/src/aura/init/zeron/hookWS.js b/src/aura/init/zeron/hookWS.js old mode 100644 new mode 100755 diff --git a/src/aura/jsRewrite/network/disableBehaviorAudit.js b/src/aura/jsRewrite/network/disableBehaviorAudit.js old mode 100644 new mode 100755 diff --git a/src/aura/jsRewrite/network/disableFriday.js b/src/aura/jsRewrite/network/disableFriday.js old mode 100644 new mode 100755 diff --git a/src/aura/jsRewrite/vendor/passwordValidation.js b/src/aura/jsRewrite/vendor/passwordValidation.js old mode 100644 new mode 100755 diff --git a/src/aura/types/main/core.d.ts b/src/aura/types/main/core.d.ts new file mode 100755 index 0000000..6940586 --- /dev/null +++ b/src/aura/types/main/core.d.ts @@ -0,0 +1,33 @@ +import { WebContents } from "electron"; + +type SeewoHugoCentralLambda = any; +type SeewoHugoGlobalConfig = Record; + +type WindowName = string; + +interface LauncherArgs { + central: SeewoHugoCentralLambda; + windowName: WindowName; + config: SeewoHugoGlobalConfig; +} + +interface HookedWindow { + webContents: WebContents; + domReadyListener: any; + destroyedListener: any; +} + +type HookedWindowsMap = Map; + +type HookRequire = any; + +type HooksMap = Map; + +interface MainProcessGlobal { + hookedWindows: HookedWindowsMap; + hooks: HooksMap; + configInit: boolean; + plsStats: PLSStatus | null; + plsSettings: Record | null; + plsRules: Record | null; +} diff --git a/src/aura/types/main/electron.d.ts b/src/aura/types/main/electron.d.ts new file mode 100755 index 0000000..0ffe4e0 --- /dev/null +++ b/src/aura/types/main/electron.d.ts @@ -0,0 +1,10 @@ +import { IpcMain, WebContents } from "electron"; + +interface AuraIPCMain extends IpcMain { + send: ( + windowKey: string, + channel: string, + data: any, + grep?: WebContents + ) => void; +} diff --git a/src/aura/types/render/global.d.ts b/src/aura/types/render/global.d.ts new file mode 100755 index 0000000..14d9161 --- /dev/null +++ b/src/aura/types/render/global.d.ts @@ -0,0 +1,14 @@ +interface HugoAuraGlobal { + utils: Record; +} + +interface AssistantHugoAuraGlobal extends HugoAuraGlobal { + plsStatus: PLSStatus; + plsRules: Record; + plsSettings: Record; +} + +interface DesktopAssistantHugoAuraGlobal extends HugoAuraGlobal { + plsWs: WebSocket | null; + plsStats: PLSStatus; +} diff --git a/src/aura/types/render/uiHook.d.ts b/src/aura/types/render/uiHook.d.ts new file mode 100755 index 0000000..198b026 --- /dev/null +++ b/src/aura/types/render/uiHook.d.ts @@ -0,0 +1,25 @@ +import { WindowName } from "../main/core"; + +interface UIHookTarget { + active: boolean; + pageURI: string; + pageScript: string; + pageSelector: string; + selectorMode: "insertAfter" | "insertBefore" | "appendChild"; + pageCSS: string; + revive?: boolean; +} + +type AuraElementUID = string; +type OnLoadedEvalJS = string; + +interface UIHookConfig { + targets: Record; + globalStyles: string[]; + globalJS: string[]; + onLoaded: OnLoadedEvalJS; +} + +interface UIHookConfigFin extends UIHookConfig { + windowName: WindowName; +} diff --git a/src/aura/types/shared/pls/status.d.ts b/src/aura/types/shared/pls/status.d.ts new file mode 100755 index 0000000..a1bae3f --- /dev/null +++ b/src/aura/types/shared/pls/status.d.ts @@ -0,0 +1,9 @@ +interface PLSStatus { + installed: boolean; + detached: boolean; + connected: boolean; + launched: boolean; + status: string; + version: string; + authToken: string; +} diff --git a/src/aura/types/shared/pls/websocket.d.ts b/src/aura/types/shared/pls/websocket.d.ts new file mode 100755 index 0000000..9533b70 --- /dev/null +++ b/src/aura/types/shared/pls/websocket.d.ts @@ -0,0 +1,18 @@ +interface ClientPLSRequest { + method: string; + data: Record; + eventId: string; +} + +interface PLSResponse { + success: boolean; + code: number; + data: Record; + eventId: string; +} + +interface PLSPush { + success: boolean; + type: string; + data: Record; +} diff --git a/src/aura/ui/bootstrap/bootstrap.bundle.min.js b/src/aura/ui/bootstrap/bootstrap.bundle.min.js old mode 100644 new mode 100755 diff --git a/src/aura/ui/bootstrap/bootstrap.min.css b/src/aura/ui/bootstrap/bootstrap.min.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/composables/plsConfigManager.js b/src/aura/ui/composables/plsConfigManager.js new file mode 100755 index 0000000..18aa464 --- /dev/null +++ b/src/aura/ui/composables/plsConfigManager.js @@ -0,0 +1,93 @@ +// @ts-check + +const __SCOPE = "assistant / rendererCommon"; + +const IPC_METHOD_BASE = "$aura.pls"; + +const updatePlsStatusFromLocal = async () => { + const plsStatus = ( + await global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.getPlsStats`) + ).data; + global.__HUGO_AURA_GLOBAL__.plsStatus = plsStatus; + return plsStatus; +}; + +const updatePlsSettingsFromLocal = async () => { + const plsSettings = ( + await global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.getPlsSettings`) + ).data; + global.__HUGO_AURA_GLOBAL__.plsSettings = plsSettings; + return plsSettings; +}; + +const updatePlsRulesFromLocal = async () => { + const plsRules = ( + await global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.getPlsRules`) + ).data; + global.__HUGO_AURA_GLOBAL__.plsRules = plsRules; + return plsRules; +}; + +/** + * + * @returns {string} + */ +const genRandomHex = () => { + let result = ""; + for (let i = 0; i < 8; i++) { + const randomNum = Math.floor(Math.random() * 0x10000); + result += randomNum.toString(16).padStart(4, "0"); + } + return result; +}; + +/** + * + * @param {string} configKey + * @param {any} configValue + */ +const updatePlsConfigToRemote = async (configKey, configValue) => { + const configLevels = configKey.split("."); + /** @type {Record} */ + let localUpdateTarget = + configLevels[0] === "ruleSettings" + ? global.__HUGO_AURA_GLOBAL__.plsRules + : global.__HUGO_AURA_GLOBAL__.plsSettings; + for (const level of configLevels.slice(0, -1)) { + localUpdateTarget = localUpdateTarget[level]; + } + localUpdateTarget[configLevels.slice(-1)[0]] = configValue; + + const plsConfigUpdateEvent = new CustomEvent("onPLSConfigUpdate", { + detail: { + path: configKey, + value: configValue, + }, + }); + document.dispatchEvent(plsConfigUpdateEvent); + + /** + * @type {ClientPLSRequest} + */ + const data = { + method: "config.action.updateConfig", + data: { + key: configKey, + value: configValue, + }, + eventId: genRandomHex(), // 不用 crypto, 因为会带来不必要的性能开销 + }; + + global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.ws.sendWsMessage`, data); + global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.syncPlsConfig`, { + basic: global.__HUGO_AURA_GLOBAL__.plsSettings, + rules: global.__HUGO_AURA_GLOBAL__.plsRules, + }); +}; + +module.exports = { + updatePlsRulesFromLocal, + updatePlsStatusFromLocal, + updatePlsSettingsFromLocal, + updatePlsConfigToRemote, +}; diff --git a/src/aura/ui/composables/settingsRenderer.js b/src/aura/ui/composables/settingsRenderer.js old mode 100644 new mode 100755 index d8c90d0..a9a783e --- a/src/aura/ui/composables/settingsRenderer.js +++ b/src/aura/ui/composables/settingsRenderer.js @@ -18,15 +18,30 @@ const showRelaunchToast = () => { if (!toastBs.isShown()) toastBs.show(); }; +const showRelaunchPLSToast = () => { + const toast = document.getElementById("relaunchPlsNotifyToast"); + const toastBs = bootstrap.Toast.getOrCreateInstance(toast); + + if (global.__HUGO_AURA_GLOBAL__.plsStatus.detached) { + const relaunchBtn = document.getElementById("plsRelaunchBtn"); + relaunchBtn.disabled = true; + relaunchBtn.textContent = "分离模式下无法执行" + } + + if (!toastBs.isShown()) toastBs.show(); +}; + const showToast = (entry) => { if (entry.reload) { showReloadToast(); } else if (entry.restart) { showRelaunchToast(); + } else if (entry.restartPLS) { + showRelaunchPLSToast(); } }; -const settingsRenderer = (pendingEl, settingsObj) => { +const settingsRenderer = (pendingEl, settingsObj, isPls = false) => { const formEl = document.createElement("form"); formEl.classList.add("aura-settings-form"); for (const category of settingsObj) { @@ -56,6 +71,18 @@ const settingsRenderer = (pendingEl, settingsObj) => { powerIcon.setAttribute("data-bs-title", "需要重启 Electron 进程"); entryTitle.appendChild(powerIcon); } + if (entry.restartPLS) { + const plsIcon = document.createElement("i"); + plsIcon.classList.add( + "layui-icon", + "layui-icon-logout", + "aura-settings-entry-property-icon" + ); + plsIcon.setAttribute("data-bs-toggle", "tooltip"); + plsIcon.setAttribute("data-bs-placement", "top"); + plsIcon.setAttribute("data-bs-title", "需要重启 PLS 进程"); + entryTitle.appendChild(plsIcon); + } if (entry.reload) { const reloadIcon = document.createElement("i"); reloadIcon.classList.add( @@ -182,14 +209,18 @@ const settingsRenderer = (pendingEl, settingsObj) => { if (!isShow) entryContainerEl.classList.add("aura-settings-entry-hidden"); if (entry.associateVal) { - document.addEventListener("onHugoAuraConfigUpdate", (event) => { - if (!entry.associateVal.includes(event.detail.path.join("."))) return; - const cls = entryContainerEl.classList; - const isShow = entry.auraIf(); - isShow - ? cls.remove("aura-settings-entry-hidden") - : cls.add("aura-settings-entry-hidden"); - }); + document.addEventListener( + isPls ? "onPLSConfigUpdate" : "onHugoAuraConfigUpdate", + (event) => { + if (!entry.associateVal.includes(event.detail.path.join("."))) + return; + const cls = entryContainerEl.classList; + const isShow = entry.auraIf(); + isShow + ? cls.remove("aura-settings-entry-hidden") + : cls.add("aura-settings-entry-hidden"); + } + ); } formEl.appendChild(entryContainerEl); diff --git a/src/aura/ui/css/assistant.css b/src/aura/ui/css/assistant.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/css/form.css b/src/aura/ui/css/form.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/css/global.css b/src/aura/ui/css/global.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/hooks/assistant.js b/src/aura/ui/hookDefinitions/assistant.js old mode 100644 new mode 100755 similarity index 61% rename from src/aura/ui/hooks/assistant.js rename to src/aura/ui/hookDefinitions/assistant.js index 933e7a8..fd3aff8 --- a/src/aura/ui/hooks/assistant.js +++ b/src/aura/ui/hookDefinitions/assistant.js @@ -1,4 +1,9 @@ -module.exports = { +// @ts-check + +/** + * @type {import("../../types/render/uiHook").UIHookConfig} + */ +const def = { targets: { "Aura.UI.Assistant.HeaderEntry": { active: true, @@ -28,6 +33,22 @@ module.exports = { pageCSS: "ui/pages/configSubPages/disableLimitations/disableLimitations.css", }, + "Aura.UI.Assistant.Config.BehaviourCtrl": { + active: false, + pageURI: "ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.html", + pageScript: "ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js", + pageSelector: ".aura-config-page-subpage-container", + selectorMode: "appendChild", + pageCSS: "ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.css", + }, + "Aura.UI.Assistant.Config.BehaviourCtrl.PlsStatus": { + active: false, + pageURI: "ui/pages/configSubPages/behaviourCtrl/plsStatus.html", + pageScript: "ui/pages/configSubPages/behaviourCtrl/plsStatus.js", + pageSelector: "#status-subpage", + selectorMode: "appendChild", + pageCSS: "ui/pages/configSubPages/behaviourCtrl/plsStatus.css", + }, }, globalStyles: [ "ui/css/global.css", @@ -41,3 +62,5 @@ module.exports = { console.log('[HugoAura / UI / Hooks / Assistant] Page loaded.'); `, }; + +module.exports = def; diff --git a/src/aura/ui/hookDefinitions/desktopAssistant.js b/src/aura/ui/hookDefinitions/desktopAssistant.js new file mode 100755 index 0000000..40fa0de --- /dev/null +++ b/src/aura/ui/hookDefinitions/desktopAssistant.js @@ -0,0 +1,15 @@ +// @ts-check + +/** + * @type {import("../../types/render/uiHook").UIHookConfig} + */ +const def = { + targets: {}, + globalStyles: ["ui/css/global.css"], + globalJS: ["ui/js/global.js", "ui/js/plsConnectionManager.js"], + onLoaded: ` + console.log('[HugoAura / UI / Hooks / Desktop Assistant] Page loaded.'); + `, +}; + +module.exports = def; diff --git a/src/aura/ui/js/global.js b/src/aura/ui/js/global.js old mode 100644 new mode 100755 diff --git a/src/aura/ui/js/plsConnectionManager.js b/src/aura/ui/js/plsConnectionManager.js new file mode 100755 index 0000000..6229dc4 --- /dev/null +++ b/src/aura/ui/js/plsConnectionManager.js @@ -0,0 +1,192 @@ +// @ts-check + +const IPC_METHOD_BASE = "$aura.pls"; +const REQUIRE_BASE = "../../aura/ui"; +const __SCOPE = "desktopAssistant"; + +const { pushMsgHandler } = require(`${REQUIRE_BASE}/pls/pushHandler`); + +/** @type {number} */ +let failedCounter = 0; +/** @type {boolean} */ +let isErrorOccurred = false; + +/** + * + * @param {string} authToken + * @param {any} callback + * @returns + */ +const createPlsConnection = (authToken, callback) => { + if (failedCounter >= 3) { + console.error( + `[HugoAura / UI / PLS Manager / ERROR] Failed connecting to PLS WebSocket server, please check the status of PLS process.` + ); + return; + } + + /** @type {WebSocket} */ + const plsWs = new WebSocket( + `wss://pls.hugoaura.local:22077/?auth=${authToken}` + ); + + plsWs.onopen = () => { + callback(true, plsWs); + }; + + plsWs.onerror = () => { + isErrorOccurred = true; + failedCounter += 1; + callback(false, plsWs); + }; + + plsWs.onclose = () => { + console.error( + "[HugoAura / UI / PLS Manager / ERROR] WebSocket connection closed." + ); + if (isErrorOccurred) return; + failedCounter += 1; + callback(false, plsWs); + }; +}; + +/** + * + * @param {WebSocket} wsObj + */ +const registerSendReqListener = (wsObj) => { + global.ipcRenderer.on( + `${IPC_METHOD_BASE}.ws.post.onReqSendMsg`, + /** + * + * @param {Event} _evt + * @param {any} arg + */ + (_evt, arg) => { + wsObj.send(JSON.stringify(arg)); + } + ); +}; + +/** + * + * @param {boolean} result + * @param {WebSocket} wsObj + * @returns + */ +const connectionResultCallback = (result, wsObj) => { + global.__HUGO_AURA_GLOBAL__.plsStats.launched = result; + global.__HUGO_AURA_GLOBAL__.plsStats.connected = result; + global.ipcRenderer.invoke( + `${IPC_METHOD_BASE}.updatePlsStats`, + global.__HUGO_AURA_GLOBAL__.plsStats + ); + if (!result) { + console.error( + `[HugoAura / UI / PLS Manager / ERROR] Failed connecting to PLS WebSocket server, retrying ...` + ); + createPlsConnection( + global.__HUGO_AURA_GLOBAL__.plsStats.authToken, + connectionResultCallback + ); + return; + } + global.__HUGO_AURA_GLOBAL__.plsWs = wsObj; + registerSendReqListener(wsObj); + wsObj.onmessage = plsPushHandler; +}; + +/** + * + * @param {MessageEvent} event + */ +const plsPushHandler = (event) => { + try { + /** @type {Record} */ + const parsedEvent = JSON.parse(event.data); + console.debug( + "[HugoAura / UI / PLS Manager / DEBUG] Received new server message: " + ); + if (!parsedEvent.eventId) { + // Push + pushMsgHandler(parsedEvent); + } else { + // Not push + global.ipcRenderer.send( + `${IPC_METHOD_BASE}.ws.broadcastMessageRecv`, + parsedEvent + ); + } + } catch { + console.error( + "[HugoAura / UI / PLS Manager / ERROR] Failed to resolve server message: ", + event.data + ); + } +}; + +const initPlsConnection = async () => { + failedCounter = 0; + isErrorOccurred = false; + + const curPlsStats = await global.ipcRenderer.invoke( + `${IPC_METHOD_BASE}.getPlsStats` + ); + let updatedPlsStats = {}; + if (curPlsStats === null || !curPlsStats.success) { + updatedPlsStats = { + installed: false, + launched: false, + detached: false, + connected: false, + version: "未知", + status: "dead", + authToken: "66ccff0d000721114514191981023333", + }; + } else { + updatedPlsStats = curPlsStats.data; + } + + const isPlsFolderExists = ( + await global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.getPlsFolderExists`) + ).data.isExists; + updatedPlsStats.installed = isPlsFolderExists; + + global.__HUGO_AURA_GLOBAL__.plsStats = updatedPlsStats; + console.debug( + "[HugoAura / UI / PLS Manager / DEBUG] Updated plsStats:", + global.__HUGO_AURA_GLOBAL__.plsStats + ); + + global.ipcRenderer.invoke( + `${IPC_METHOD_BASE}.updatePlsStats`, + updatedPlsStats + ); + + const startConnPls = () => { + createPlsConnection(updatedPlsStats.authToken, connectionResultCallback); + }; + + if (updatedPlsStats.detached && updatedPlsStats.installed) { + startConnPls(); + } + + global.ipcRenderer.on(`${IPC_METHOD_BASE}.post.onPlsLaunched`, (_event) => { + setTimeout(() => { + startConnPls(); + }, 5000); + }); +}; + +const onSetup = () => { + if (!global.global.ipcRenderer) { + // @ts-ignore + global.global.ipcRenderer = require("electron").global.ipcRenderer; + } + + initPlsConnection(); +}; + +(() => { + onSetup(); +})(); diff --git a/src/aura/ui/layui/css/layui.css b/src/aura/ui/layui/css/layui.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/layui/font/iconfont.eot b/src/aura/ui/layui/font/iconfont.eot old mode 100644 new mode 100755 diff --git a/src/aura/ui/layui/font/iconfont.svg b/src/aura/ui/layui/font/iconfont.svg old mode 100644 new mode 100755 diff --git a/src/aura/ui/layui/font/iconfont.ttf b/src/aura/ui/layui/font/iconfont.ttf old mode 100644 new mode 100755 diff --git a/src/aura/ui/layui/font/iconfont.woff b/src/aura/ui/layui/font/iconfont.woff old mode 100644 new mode 100755 diff --git a/src/aura/ui/layui/font/iconfont.woff2 b/src/aura/ui/layui/font/iconfont.woff2 old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/config/config.css b/src/aura/ui/pages/config/config.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/config/config.html b/src/aura/ui/pages/config/config.html old mode 100644 new mode 100755 index 1ad336d..42d7c99 --- a/src/aura/ui/pages/config/config.html +++ b/src/aura/ui/pages/config/config.html @@ -80,7 +80,7 @@
@@ -162,5 +162,30 @@
+ +
+
+
+ + 重启 PLS 进程以应用设置 +
+
+

请重启 PLS 进程以应用修改的设置

+ +
+
+
diff --git a/src/aura/ui/pages/config/config.js b/src/aura/ui/pages/config/config.js old mode 100644 new mode 100755 index 9c66509..3953a2b --- a/src/aura/ui/pages/config/config.js +++ b/src/aura/ui/pages/config/config.js @@ -49,17 +49,33 @@ global.__HUGO_AURA_UI_FUNCTIONS__.config = { "aura-config-page-operation-el" ); let pendingSubPageId = ""; + let preserveOperationIdx = 0; switch (subPage) { case "disableLimitations": - side - ? operationElArr[0].classList.add("preserve-operation") - : operationElArr[0].classList.remove("preserve-operation"); + preserveOperationIdx = 0; pendingSubPageId = "Aura.UI.Assistant.Config.DisableLimitations"; break; + case "behaviourCtrl": + preserveOperationIdx = 1; + pendingSubPageId = "Aura.UI.Assistant.Config.BehaviourCtrl"; + if (!side) { + setTimeout(() => { + global.__HUGO_AURA_LOADER__[ + "Aura.UI.Assistant.Config.BehaviourCtrl.PlsStatus" + ].active = false; + }, 500); + } + break; default: break; } + side + ? operationElArr[preserveOperationIdx].classList.add("preserve-operation") + : operationElArr[preserveOperationIdx].classList.remove( + "preserve-operation" + ); + const operationAreaEl = document.getElementsByClassName( "aura-config-page-operation-area" )[0]; diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.css b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.css new file mode 100755 index 0000000..373b100 --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.css @@ -0,0 +1,8 @@ +.aura-config-subpage-behaviour-control { + opacity: 1; + transition: opacity 0.5s; +} + +.aura-config-subpage-behaviour-control.acs-behaviour-control-hidden { + opacity: 0; +} diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.html b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.html new file mode 100755 index 0000000..69ce598 --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.html @@ -0,0 +1,69 @@ +
+ +
+
+
+
+
+
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js new file mode 100755 index 0000000..5eee61a --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js @@ -0,0 +1,44 @@ +(() => { + const REQUIRE_BASE = + "../../aura/ui/pages/configSubPages/behaviourCtrl/settings"; + + const { + settingsRenderer, + } = require(`${REQUIRE_BASE}/../../../../composables/settingsRenderer`); + + const { basicSettings } = require(`${REQUIRE_BASE}/basic`); + + const { + updatePlsSettingsFromLocal, + updatePlsRulesFromLocal, + } = require(`${REQUIRE_BASE}/../../../../composables/plsConfigManager`); + + const initStatusPage = () => { + global.__HUGO_AURA_LOADER__[ + "Aura.UI.Assistant.Config.BehaviourCtrl.PlsStatus" + ].active = true; + }; + + const initBasicSettingsPage = () => { + const basicSubPageEl = document.getElementById("basic-config-subpage"); + settingsRenderer(basicSubPageEl, basicSettings); + }; + + const renderSubPages = async () => { + await updatePlsSettingsFromLocal(); + await updatePlsRulesFromLocal(); + + initBasicSettingsPage(); + }; + + const onMounted = () => { + const rootEl = document.getElementById("acs-behaviour-control-el"); + initStatusPage(); + renderSubPages(); + setTimeout(() => { + rootEl.classList.remove("acs-behaviour-control-hidden"); + }, 500); + }; + + onMounted(); +})(); diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.css b/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.css new file mode 100755 index 0000000..bfda3c5 --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.css @@ -0,0 +1,78 @@ +.acs-behaviour-control-pls-status-page { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.acs-behaviour-control-pls-status-page p { + font-family: sans-serif; +} + +.acs-bc-pls-status-page-pls-description { + margin-top: 0.5rem; + max-width: 80%; + opacity: 0.35; + font-size: small; + text-align: center; +} + +.acs-bc-pls-status-page-main-logo { + max-width: 13.5%; + opacity: 0.45; + margin-top: 1.5rem; + margin-bottom: 1.5rem; +} + +.acs-bc-pls-status-page-status-el { + display: flex; + align-items: center; + width: 40%; + padding: 0.625rem 0.25rem; + border-bottom: 1px solid rgba(0, 0, 0, 0.25); +} + +.acs-bc-pls-status-page-status-el div { + display: flex; + align-items: center; +} + +.acs-bc-pls-status-page-status-area { + flex-grow: 1; + justify-content: flex-end; +} + +.acs-bc-pls-status-page-status-area-circle { + height: 10px; + width: 10px; + border-radius: 100%; + margin-right: 8px; + margin-top: 2px; +} + +.acs-bc-pls-status-page-status-area.pending + .acs-bc-pls-status-page-status-area-circle { + background-color: rgba(0, 0, 0, 0.375); +} + +.acs-bc-pls-status-page-status-area.pending p { + opacity: 0.5; +} + +.acs-bc-pls-status-page-status-area.success + .acs-bc-pls-status-page-status-area-circle { + background-color: rgb(0, 175, 38); +} + +.acs-bc-pls-status-page-status-area.success p { + color: rgb(0, 150, 33); +} + +.acs-bc-pls-status-page-status-area.failed + .acs-bc-pls-status-page-status-area-circle { + background-color: rgb(175, 0, 0); +} + +.acs-bc-pls-status-page-status-area.failed p { + color: rgb(175, 0, 0); +} diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.html b/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.html new file mode 100755 index 0000000..7038397 --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.html @@ -0,0 +1,51 @@ +
+

+ HugoAura ProxyLayerServices (Aura-PLS) 是基于 Python + MITMProxy 实现的代理服务, + 用于解密并修改希沃基础服务 (SeewoCore) 的 MQTT 数据包, + 实现行为监控、伪造上报等功能 +

+ + +
+

安装状态

+
+ +

未安装

+
+
+ +
+

启动状态

+
+ +

未启动

+
+
+ +
+

连接状态

+
+ +

已断开

+
+
+ +
+

版本

+
+

不可用

+
+
+
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.js new file mode 100755 index 0000000..14fdae0 --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/plsStatus.js @@ -0,0 +1,86 @@ +(() => { + const REQUIRE_BASE = "../../aura/ui/pages/configSubPages/behaviourCtrl"; + const IPC_METHOD_BASE = "$aura.pls"; + + const { + updatePlsStatusFromLocal, + } = require(`${REQUIRE_BASE}/../../../composables/plsConfigManager`); + + const updateStatusEl = ( + areaContainerId, + areaTextId, + target, + text = false + ) => { + const areaContainerEl = document.getElementById(areaContainerId); + const areaContainerText = document.getElementById(areaTextId); + switch (target) { + case "PENDING": + areaContainerEl.className = + "acs-bc-pls-status-page-status-area pending"; + break; + case "SUCCESS": + areaContainerEl.className = + "acs-bc-pls-status-page-status-area success"; + break; + case "FAILED": + areaContainerEl.className = "acs-bc-pls-status-page-status-area failed"; + break; + case "WARNING": + areaContainerEl.className = + "acs-bc-pls-status-page-status-area warning"; + break; + default: + return false; + } + areaContainerText.textContent = text ? text : ""; + return true; + }; + + const updateStatus = async () => { + const curPlsStats = await updatePlsStatusFromLocal(); + + const acIdInst = "acs-bc-psp-installStatus-container"; + const atIdInst = "acs-bc-psp-installStatus-text"; + switch (curPlsStats.installed) { + case true: + updateStatusEl(acIdInst, atIdInst, "SUCCESS", "已安装"); + break; + case false: + updateStatusEl(acIdInst, atIdInst, "PENDING", "未安装"); + } + + const acIdLaunch = "acs-bc-psp-launchStatus-container"; + const atIdLaunch = "acs-bc-psp-launchStatus-text"; + switch (curPlsStats.launched) { + case true: + updateStatusEl(acIdLaunch, atIdLaunch, "SUCCESS", "已启动"); + break; + case false: + updateStatusEl(acIdLaunch, atIdLaunch, "PENDING", "未启动"); + break; + } + + const acIdConn = "acs-bc-psp-connStatus-container"; + const atIdConn = "acs-bc-psp-connStatus-text"; + switch (curPlsStats.connected) { + case true: + updateStatusEl(acIdConn, atIdConn, "SUCCESS", "已连接"); + break; + case false: + updateStatusEl(acIdConn, atIdConn, "FAILED", "连接失败"); + break; + } + + if (curPlsStats.version && curPlsStats.version !== "未知") { + const versionTextEl = document.getElementById("acs-bc-psp-version-text"); + versionTextEl.textContent = "v" + curPlsStats.version; + } + }; + + const onMounted = () => { + updateStatus(); + }; + + onMounted(); +})(); diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js new file mode 100755 index 0000000..d1baa92 --- /dev/null +++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js @@ -0,0 +1,45 @@ +const REQUIRE_BASE = "."; + +const { + updatePlsConfigToRemote, +} = require(`${REQUIRE_BASE}/../../../../composables/plsConfigManager`); + +const basicSettings = [ + { + id: 0, + categoryName: "可访问性", + child: [ + { + index: 0, + id: "authToken", + type: "input", + subType: "text", + name: "WebSocket 认证密钥", + description: "选择一个安全的密钥, 用于 PLS 侧验证 Aura 前端身份", + restart: true, + reload: false, + restartPLS: false, + associateVal: null, + auraIf: () => true, + defaultValue: "", + placeHolder: "输入一个密钥", + valueGetter: () => { + return global.__HUGO_AURA_CONFIG__.plsToken; + }, + callbackFn: (newVal) => { + if (newVal === "" || !newVal) + return { valid: false, hint: "请输入认证密钥" }; + + if (newVal.length < 8) { + return { valid: false, hint: "至少输入 8 位字符" }; + } + + global.__HUGO_AURA_CONFIG__.plsToken = newVal; + return { valid: true }; + }, + }, + ], + }, +]; + +module.exports = { basicSettings }; diff --git a/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.css b/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.css old mode 100644 new mode 100755 index 709f5e1..f90de5c --- a/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.css +++ b/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.css @@ -1,6 +1,5 @@ .aura-config-subpage-disable-limit-root { opacity: 1; - transition: opacity 0.5s; } diff --git a/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.html b/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.html old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.js b/src/aura/ui/pages/configSubPages/disableLimitations/disableLimitations.js old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/configSubPages/disableLimitations/settings/audit.js b/src/aura/ui/pages/configSubPages/disableLimitations/settings/audit.js old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/configSubPages/disableLimitations/settings/auth.js b/src/aura/ui/pages/configSubPages/disableLimitations/settings/auth.js old mode 100644 new mode 100755 index 21b92ea..b10f9e4 --- a/src/aura/ui/pages/configSubPages/disableLimitations/settings/auth.js +++ b/src/aura/ui/pages/configSubPages/disableLimitations/settings/auth.js @@ -114,8 +114,8 @@ const authSettings = [ ].enabled; }, defaultValue: "hybrid", - templates: ["hybrid", "remoteOnly", "passwordOnly"], - templateLabels: ["混合", "仅二维码", "仅密码"], + templates: ["default", "hybrid", "remoteOnly", "passwordOnly"], + templateLabels: ["默认", "混合", "仅二维码", "仅密码"], valueGetter: () => { return global.__HUGO_AURA_CONFIG__.rewrite[ "vendor/passwordValidation" diff --git a/src/aura/ui/pages/headerIcon/headerIcon.css b/src/aura/ui/pages/headerIcon/headerIcon.css old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/headerIcon/headerIcon.html b/src/aura/ui/pages/headerIcon/headerIcon.html old mode 100644 new mode 100755 diff --git a/src/aura/ui/pages/headerIcon/headerIcon.js b/src/aura/ui/pages/headerIcon/headerIcon.js old mode 100644 new mode 100755 diff --git a/src/aura/ui/pls/pushHandler.js b/src/aura/ui/pls/pushHandler.js new file mode 100755 index 0000000..bf33426 --- /dev/null +++ b/src/aura/ui/pls/pushHandler.js @@ -0,0 +1,30 @@ +// @ts-check + +const REQUIRE_BASE = "."; + +const { basicRouteHandler } = require(`${REQUIRE_BASE}/routes/basic`); +const { configRouteHandler } = require(`${REQUIRE_BASE}/routes/config`); + +/** + * + * @param {PLSPush} parsedWsMsg + * @returns + */ +const pushMsgHandler = (parsedWsMsg) => { + if (!parsedWsMsg.type) return false; + + const msgCategory = parsedWsMsg.type.split(".")[0]; + + switch (msgCategory) { + case "basic": + basicRouteHandler(parsedWsMsg); + break; + case "config": + configRouteHandler(parsedWsMsg); + break; + default: + break; + } +}; + +module.exports = { pushMsgHandler }; diff --git a/src/aura/ui/pls/routes/basic.js b/src/aura/ui/pls/routes/basic.js new file mode 100755 index 0000000..ffdf4be --- /dev/null +++ b/src/aura/ui/pls/routes/basic.js @@ -0,0 +1,33 @@ +// @ts-check + +const IPC_METHOD_BASE = "$aura.pls"; + +/** + * + * @param {PLSPush} parsedWsMsg + * @returns + */ +const basicRouteHandler = (parsedWsMsg) => { + const target = parsedWsMsg.type.split(".").slice(-1)[0]; + switch (target) { + case "pushPlsInfo": + global.__HUGO_AURA_GLOBAL__.plsStats.status = parsedWsMsg.data.status; + global.__HUGO_AURA_GLOBAL__.plsStats.version = parsedWsMsg.data.version; + + global.ipcRenderer.invoke( + `${IPC_METHOD_BASE}.updatePlsStats`, + global.__HUGO_AURA_GLOBAL__.plsStats + ); + + console.debug( + "[HugoAura / UI / PLS Routes / DEBUG] Updated plsStats basic info:", + global.__HUGO_AURA_GLOBAL__.plsStats + ); + break; + default: + return false; + } + return true; +}; + +module.exports = { basicRouteHandler }; diff --git a/src/aura/ui/pls/routes/config.js b/src/aura/ui/pls/routes/config.js new file mode 100755 index 0000000..2d8bdae --- /dev/null +++ b/src/aura/ui/pls/routes/config.js @@ -0,0 +1,32 @@ +// @ts-check + +const IPC_METHOD_BASE = "$aura.pls"; + +/** + * + * @param {PLSPush} parsedWsMsg + * @returns + */ +const configRouteHandler = (parsedWsMsg) => { + const target = parsedWsMsg.type.split(".").slice(-1)[0]; + switch (target) { + case "pushBasicConfig": + global.ipcRenderer.invoke( + `${IPC_METHOD_BASE}.updatePlsSettings`, + parsedWsMsg.data + ); + break; + case "pushRuleSettings": + global.ipcRenderer.invoke( + `${IPC_METHOD_BASE}.updatePlsRules`, + parsedWsMsg.data + ); + break; + default: + return false; + } + + return true; +}; + +module.exports = { configRouteHandler }; diff --git a/src/aura/ui/static/aura.svg b/src/aura/ui/static/aura.svg old mode 100644 new mode 100755 diff --git a/src/aura/ui/static/aura_pls.png b/src/aura/ui/static/aura_pls.png new file mode 100755 index 0000000..d2bb2bf Binary files /dev/null and b/src/aura/ui/static/aura_pls.png differ diff --git a/src/aura/ui/static/config/about.svg b/src/aura/ui/static/config/about.svg old mode 100644 new mode 100755 diff --git a/src/aura/ui/static/config/behaviour_mon.svg b/src/aura/ui/static/config/behaviour_mon.svg old mode 100644 new mode 100755 diff --git a/src/aura/ui/static/config/no_limitations.svg b/src/aura/ui/static/config/no_limitations.svg old mode 100644 new mode 100755 diff --git a/src/aura/ui/static/config/plugin.svg b/src/aura/ui/static/config/plugin.svg old mode 100644 new mode 100755 diff --git a/src/core/hook.js b/src/core/hook.js old mode 100644 new mode 100755 index 7777931..68a1668 --- a/src/core/hook.js +++ b/src/core/hook.js @@ -1,139 +1,161 @@ -if (!global.__HUGO_AURA__) { - global.__HUGO_AURA__ = { - hookedWindows: new Map(), - hooks: null, - configInit: false, - }; -} - -const fs = require("fs"); -const util = require("util"); -const path = require("path"); -const os = require("os"); - -const HooksManager = require("../aura/init/rendererHook/hooksManager"); -const NetworkHook = require("../aura/init/rendererHook/networkHook"); -const configManager = require("../aura/init/shared/configManager"); -const { buildIpcMain } = require("../aura/init/main/ipcHandler"); - -const initLogger = () => { - const logDir = path.join(os.homedir(), "Documents", "HugoAura", "logs"); - if (!fs.existsSync(logDir)) { - fs.mkdirSync(logDir, { recursive: true }); - } - - const logFile = path.join( - logDir, - `main-process-${new Date().toISOString().replace(/:/g, "-")}.log` - ); - const logStream = fs.createWriteStream(logFile, { flags: "a" }); - - const originalConsole = { - log: console.log, - error: console.error, - warn: console.warn, - info: console.info, - debug: console.debug, - }; - - console.log = function (...args) { - const msg = util.format("[LOG] ", ...args) + "\n"; - logStream.write(msg); - originalConsole.log.apply(console, args); - }; - - console.error = function (...args) { - const msg = util.format("[ERROR] ", ...args) + "\n"; - logStream.write(msg); - originalConsole.error.apply(console, args); - }; - - console.warn = function (...args) { - const msg = util.format("[WARN] ", ...args) + "\n"; - logStream.write(msg); - originalConsole.warn.apply(console, args); - }; - - console.info = function (...args) { - const msg = util.format("[INFO] ", ...args) + "\n"; - logStream.write(msg); - originalConsole.info.apply(console, args); - }; - - console.debug = function (...args) { - if (!process.argv.includes("--aura-debug")) return; - const msg = util.format("[DEBUG] ", ...args) + "\n"; - logStream.write(msg); - originalConsole.debug.apply(console, args); - }; - - process.on("uncaughtException", (err) => { - console.error("UNCAUGHT EXCEPTION:", err); - }); - - console.log("Logger initialized. Log file:", logFile); -}; - -module.exports = function ({ central, windowName, config }) { - process.stdout.isTTY = true; - process.stderr.isTTY = true; - - const electron = central(1); - const app = electron.app; - if (!global.__HUGO_AURA__.central) global.__HUGO_AURA__.central = central; - - global.reloadApp = () => { - app.relaunch({ args: process.argv.slice(1).concat(["--inspect 5858"]) }); - app.exit(0); - }; - - initLogger(); - - console.log("[HugoAura / Loaded] Aura is loaded!"); - - if (!global.__HUGO_AURA__.ipcInit) { - buildIpcMain(electron); - global.__HUGO_AURA__.ipcInit = true; - } - - const hooksManager = new HooksManager(); - - configManager.ensureConfigExists(); - const loadedConfig = configManager.loadConfig(); - if (!global.__HUGO_AURA__.configInit) global.__HUGO_AURA__.configInit = true; - - const hooks = hooksManager.loadHooks(); - - if (loadedConfig.devTools && !config.canOpenDevTool) { - config.canOpenDevTool = true; - } - - const webContentsCreatedListener = (_event, webContents) => { - const hookConfig = hooks.get(windowName); - - const initNetworkHook = () => { - const networkHook = new NetworkHook(); - networkHook.installHook(webContents.session, loadedConfig); - - console.debug( - `[HugoAura / Init / Done / NetworkHook] Network Hook for ${windowName} installed.` - ); - }; - - initNetworkHook(); - - if (hookConfig) { - hooksManager.handleWindowHook(webContents, hookConfig, windowName); - } else { - console.debug( - `[HugoAura / Init] Window ${windowName} has no corresponding hook, ignoring...` - ); - } - }; - - app.once("web-contents-created", webContentsCreatedListener); - - return () => { - app.removeListener("web-contents-created", webContentsCreatedListener); - }; -}; +// @ts-check + +if (!global.__HUGO_AURA__) { + /** + * @type {import("../aura/types/main/core").MainProcessGlobal} + */ + const __HUGO_AURA__ = { + hookedWindows: new Map(), + hooks: new Map(), + configInit: false, + plsStats: null, + plsSettings: null, + plsRules: null, + }; + global.__HUGO_AURA__ = __HUGO_AURA__; +} + +if (!global.__HUGO_AURA_CONFIG__) { + global.__HUGO_AURA_CONFIG__ = {}; +} + +const fs = require("fs"); +const util = require("util"); +const path = require("path"); +const os = require("os"); + +const HooksManager = require("../aura/init/rendererHook/hooksManager"); +const NetworkHook = require("../aura/init/rendererHook/networkHook"); +const configManager = require("../aura/init/shared/configManager"); +const { buildIpcMain } = require("../aura/init/main/ipcHandler"); + +const initLogger = () => { + const logDir = path.join(os.homedir(), "Documents", "HugoAura", "logs"); + if (!fs.existsSync(logDir)) { + fs.mkdirSync(logDir, { recursive: true }); + } + + const logFile = path.join( + logDir, + `main-process-${new Date().toISOString().replace(/:/g, "-")}.log` + ); + const logStream = fs.createWriteStream(logFile, { flags: "a" }); + + const originalConsole = { + log: console.log, + error: console.error, + warn: console.warn, + info: console.info, + debug: console.debug, + }; + + console.log = function (...args) { + const msg = util.format("[LOG] ", ...args) + "\n"; + logStream.write(msg); + originalConsole.log.apply(console, args); + }; + + console.error = function (...args) { + const msg = util.format("[ERROR] ", ...args) + "\n"; + logStream.write(msg); + originalConsole.error.apply(console, args); + }; + + console.warn = function (...args) { + const msg = util.format("[WARN] ", ...args) + "\n"; + logStream.write(msg); + originalConsole.warn.apply(console, args); + }; + + console.info = function (...args) { + const msg = util.format("[INFO] ", ...args) + "\n"; + logStream.write(msg); + originalConsole.info.apply(console, args); + }; + + console.debug = function (...args) { + if (!process.argv.includes("--aura-debug")) return; + const msg = util.format("[DEBUG] ", ...args) + "\n"; + logStream.write(msg); + originalConsole.debug.apply(console, args); + }; + + process.on("uncaughtException", (err) => { + console.error("UNCAUGHT EXCEPTION:", err); + }); + + console.log("Logger initialized. Log file:", logFile); +}; + +/** + * + * @param {import("../aura/types/main/core").LauncherArgs} param0 + * @returns + */ +const launcher = ({ central, windowName, config }) => { + process.stdout.isTTY = true; + process.stderr.isTTY = true; + + const electron = central(1); + const app = electron.app; + if (!global.__HUGO_AURA__.central) global.__HUGO_AURA__.central = central; + + global.reloadApp = () => { + app.relaunch({ args: process.argv.slice(1).concat(["--inspect 5858"]) }); + app.exit(0); + }; + + initLogger(); + + console.log("[HugoAura / Loaded] Aura is loaded!"); + + configManager.ensureConfigExists(); + const loadedConfig = configManager.loadConfig(); + if (!global.__HUGO_AURA__.configInit) global.__HUGO_AURA__.configInit = true; + + global.__HUGO_AURA_CONFIG__ = loadedConfig; + + if (!global.__HUGO_AURA__.ipcInit) { + buildIpcMain(electron); + global.__HUGO_AURA__.ipcInit = true; + } + + const hooksManager = new HooksManager(); + + const hooks = hooksManager.loadHooks(); + + if (loadedConfig.devTools && !config.canOpenDevTool) { + config.canOpenDevTool = true; + } + + const webContentsCreatedListener = (_event, webContents) => { + const hookConfig = hooks.get(windowName); + + const initNetworkHook = () => { + const networkHook = new NetworkHook(); + networkHook.installHook(webContents.session, loadedConfig); + + console.debug( + `[HugoAura / Init / Done / NetworkHook] Network Hook for ${windowName} installed.` + ); + }; + + initNetworkHook(); + + if (hookConfig) { + hooksManager.handleWindowHook(webContents, hookConfig, windowName); + } else { + console.debug( + `[HugoAura / Init] Window ${windowName} has no corresponding hook, ignoring...` + ); + } + }; + + app.once("web-contents-created", webContentsCreatedListener); + + return () => { + app.removeListener("web-contents-created", webContentsCreatedListener); + }; +}; + +module.exports = launcher; diff --git a/src/core/preload.js b/src/core/preload.js old mode 100644 new mode 100755 diff --git a/src/core/zeron.js b/src/core/zeron.js old mode 100644 new mode 100755 index aaa5512..082f372 --- a/src/core/zeron.js +++ b/src/core/zeron.js @@ -1,23 +1,31 @@ -// Ex-Early Load Pro Plus Max ++ - -console.debug("[HugoAura / Zeron] Early load script loaded."); - -module.exports = function (central) { - const originalCentral = { ...central }; - const genHookedWS = require("../aura/init/zeron/hookWS"); - - console.debug( - "[HugoAura / Zeron / WebSocket Hook] WebSocket hooked class generated." - ); - - return new Proxy(central, { - apply(target, thisArg, args) { - switch (args[0]) { - case 18: - return genHookedWS(central); - default: - return Reflect.apply(target, thisArg, args); - } - }, - }); -}; +// Ex-Early Load Pro Plus Max ++ + +console.debug("[HugoAura / Zeron] Early load script loaded."); + +const appendSwitch = () => { + const { app } = require("electron"); + app.commandLine.appendSwitch("host-rules", "MAP *.hugoaura.local 127.0.0.1"); +}; + +module.exports = function (central) { + const originalCentral = { ...central }; + + appendSwitch(); + + const genHookedWS = require("../aura/init/zeron/hookWS"); + + console.debug( + "[HugoAura / Zeron / WebSocket Hook] WebSocket hooked class generated." + ); + + return new Proxy(central, { + apply(target, thisArg, args) { + switch (args[0]) { + case 18: + return genHookedWS(central); + default: + return Reflect.apply(target, thisArg, args); + } + }, + }); +};