[Feat] Early support for PLS & Use JSDoc (Partially)

This commit is contained in:
Minoricew
2025-05-25 22:40:12 +08:00
parent 502da5ba9a
commit 12f1040884
71 changed files with 1470 additions and 185 deletions

0
src/aura/ui/bootstrap/bootstrap.bundle.min.js vendored Normal file → Executable file
View File

0
src/aura/ui/bootstrap/bootstrap.min.css vendored Normal file → Executable file
View File

View File

@@ -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<any, any>} */
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,
};

49
src/aura/ui/composables/settingsRenderer.js Normal file → Executable file
View File

@@ -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);

0
src/aura/ui/css/assistant.css Normal file → Executable file
View File

0
src/aura/ui/css/form.css Normal file → Executable file
View File

0
src/aura/ui/css/global.css Normal file → Executable file
View File

View File

@@ -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;

View File

@@ -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;

0
src/aura/ui/js/global.js Normal file → Executable file
View File

View File

@@ -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<any, any>} */
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();
})();

0
src/aura/ui/layui/css/layui.css Normal file → Executable file
View File

0
src/aura/ui/layui/font/iconfont.eot Normal file → Executable file
View File

0
src/aura/ui/layui/font/iconfont.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 322 KiB

After

Width:  |  Height:  |  Size: 322 KiB

0
src/aura/ui/layui/font/iconfont.ttf Normal file → Executable file
View File

0
src/aura/ui/layui/font/iconfont.woff Normal file → Executable file
View File

0
src/aura/ui/layui/font/iconfont.woff2 Normal file → Executable file
View File

0
src/aura/ui/pages/config/config.css Normal file → Executable file
View File

27
src/aura/ui/pages/config/config.html Normal file → Executable file
View File

@@ -80,7 +80,7 @@
</div>
<div
class="operation-el-hidden aura-config-page-operation-el"
aura-disabled="true"
onclick="window.__HUGO_AURA_UI_FUNCTIONS__.config.toggleSubConfig('behaviourCtrl', true)"
>
<div class="aura-config-page-operation-body">
<img src="../../aura/ui/static/config/behaviour_mon.svg" />
@@ -162,5 +162,30 @@
</div>
</div>
</div>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div
id="relaunchPlsNotifyToast"
class="toast acp-toast-emerg"
aria-atomic="true"
data-bs-autohide="false"
>
<div class="toast-header">
<i class="layui-icon layui-icon-tips"></i>
<strong class="me-auto">重启 PLS 进程以应用设置</strong>
</div>
<div class="toast-body">
<p>请重启 PLS 进程以应用修改的设置</p>
<button
type="button"
class="btn btn-primary btn-sm"
id="plsRelaunchBtn"
onclick="ipcRenderer.invoke('$aura.pls.relaunchPls')"
>
重启进程
</button>
</div>
</div>
</div>
</div>
</div>

22
src/aura/ui/pages/config/config.js Normal file → Executable file
View File

@@ -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];

View File

@@ -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;
}

View File

@@ -0,0 +1,69 @@
<div
id="acs-behaviour-control-el"
class="aura-config-subpage-behaviour-control acs-behaviour-control-hidden"
>
<ul class="nav nav-underline mb-3" role="tablist">
<li class="nav-item" role="presentation">
<button
class="nav-link active"
id="status-subpage-tab"
data-bs-toggle="pill"
data-bs-target="#status-subpage"
type="button"
role="tab"
aria-controls="status-subpage"
aria-selected="true"
>
状态
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
id="basic-config-tab"
data-bs-toggle="pill"
data-bs-target="#basic-config-subpage"
type="button"
role="tab"
aria-controls="basic-config-subpage"
aria-selected="false"
>
基本设置
</button>
</li>
<li class="nav-item" role="presentation">
<button
class="nav-link"
id="security-config-tab"
data-bs-toggle="pill"
data-bs-target="#security-config-subpage"
type="button"
role="tab"
aria-controls="security-config-subpage"
aria-selected="false"
>
设备安全
</button>
</li>
</ul>
<div class="tab-content">
<div
class="tab-pane fade show active"
id="status-subpage"
role="tabpanel"
aria-labelledby="status-subpage-tab"
></div>
<div
class="tab-pane fade"
id="basic-config-subpage"
role="tabpanel"
aria-labelledby="basic-config-tab"
></div>
<div
class="tab-pane fade"
id="security-config-subpage"
role="tabpanel"
aria-labelledby="security-config-tab"
></div>
</div>
</div>

View File

@@ -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();
})();

View File

@@ -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);
}

View File

@@ -0,0 +1,51 @@
<div class="acs-behaviour-control-pls-status-page">
<p class="acs-bc-pls-status-page-pls-description">
HugoAura ProxyLayerServices (Aura-PLS) 是基于 Python + MITMProxy 实现的代理服务,
用于解密并修改希沃基础服务 (SeewoCore) 的 MQTT 数据包,
实现行为监控、伪造上报等功能
</p>
<img
src="../../aura/ui/static/aura_pls.png"
class="acs-bc-pls-status-page-main-logo"
/>
<div class="acs-bc-pls-status-page-status-el">
<p>安装状态</p>
<div
class="acs-bc-pls-status-page-status-area pending"
id="acs-bc-psp-installStatus-container"
>
<span class="acs-bc-pls-status-page-status-area-circle"></span>
<p id="acs-bc-psp-installStatus-text">未安装</p>
</div>
</div>
<div class="acs-bc-pls-status-page-status-el">
<p>启动状态</p>
<div
class="acs-bc-pls-status-page-status-area pending"
id="acs-bc-psp-launchStatus-container"
>
<span class="acs-bc-pls-status-page-status-area-circle"></span>
<p id="acs-bc-psp-launchStatus-text">未启动</p>
</div>
</div>
<div class="acs-bc-pls-status-page-status-el">
<p>连接状态</p>
<div
class="acs-bc-pls-status-page-status-area pending"
id="acs-bc-psp-connStatus-container"
>
<span class="acs-bc-pls-status-page-status-area-circle"></span>
<p id="acs-bc-psp-connStatus-text">已断开</p>
</div>
</div>
<div class="acs-bc-pls-status-page-status-el" style="border-bottom: none">
<p>版本</p>
<div class="acs-bc-pls-status-page-status-area">
<p id="acs-bc-psp-version-text">不可用</p>
</div>
</div>
</div>

View File

@@ -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();
})();

View File

@@ -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 };

View File

@@ -1,6 +1,5 @@
.aura-config-subpage-disable-limit-root {
opacity: 1;
transition: opacity 0.5s;
}

View File

View File

@@ -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"

0
src/aura/ui/pages/headerIcon/headerIcon.css Normal file → Executable file
View File

0
src/aura/ui/pages/headerIcon/headerIcon.html Normal file → Executable file
View File

0
src/aura/ui/pages/headerIcon/headerIcon.js Normal file → Executable file
View File

30
src/aura/ui/pls/pushHandler.js Executable file
View File

@@ -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 };

33
src/aura/ui/pls/routes/basic.js Executable file
View File

@@ -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 };

View File

@@ -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 };

0
src/aura/ui/static/aura.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 673 B

BIN
src/aura/ui/static/aura_pls.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

0
src/aura/ui/static/config/about.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

0
src/aura/ui/static/config/behaviour_mon.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

0
src/aura/ui/static/config/no_limitations.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

0
src/aura/ui/static/config/plugin.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB