[🔄 Chore] Prepare for Aikari (2/2)

This commit is contained in:
Minoricew
2025-11-16 18:35:53 +08:00
committed by Minorice
parent 08290301a3
commit b277a61923
14 changed files with 586 additions and 333 deletions

View File

@@ -218,12 +218,17 @@ const applyAikariIpcHandler = (ipcMain) => {
const AIKARI_DEFAULT_INSTALL_DIR = path.join( const AIKARI_DEFAULT_INSTALL_DIR = path.join(
"C:\\Program Files", "C:\\Program Files",
"HugoAura Aikari" "HugoAura",
"Aikari"
); );
const AIKARI_LAUNCHER_PATH = path.join( const AIKARI_LAUNCHER_PATH = path.join(
AIKARI_DEFAULT_INSTALL_DIR, AIKARI_DEFAULT_INSTALL_DIR,
"Aikari-Launcher.exe" "Aikari-Launcher.exe"
); );
const AIKARI_UNINSTALLER_PATH = path.join(
AIKARI_DEFAULT_INSTALL_DIR,
"unins000.exe"
);
const AIKARI_SVC_NAME = "HugoAuraAikari"; const AIKARI_SVC_NAME = "HugoAuraAikari";
const isAikariDetached = process.argv.includes("--aikari-detach"); const isAikariDetached = process.argv.includes("--aikari-detach");
@@ -502,27 +507,27 @@ const applyAikariIpcHandler = (ipcMain) => {
return await functions.execCommand( return await functions.execCommand(
logHeader, logHeader,
AIKARI_LAUNCHER_PATH, AIKARI_LAUNCHER_PATH,
"--startup auto install" "--service install"
); );
case "uninstSvc": { case "uninstSvc": {
const result = await functions.execCommand( const result = await functions.execCommand(
logHeader, logHeader,
AIKARI_LAUNCHER_PATH, AIKARI_LAUNCHER_PATH,
"remove" "--service uninstall"
); );
return result; return result;
} }
case "startSvc": case "startSvc":
return await functions.execCommand( return await functions.execCommand(
logHeader, logHeader,
AIKARI_LAUNCHER_PATH, "sc.exe",
"start" `start ${AIKARI_SVC_NAME}`
); );
case "stopSvc": { case "stopSvc": {
const result = await functions.execCommand( const result = await functions.execCommand(
logHeader, logHeader,
AIKARI_LAUNCHER_PATH, "sc.exe",
"stop" `stop ${AIKARI_SVC_NAME}`
); );
if (result.success && global.__HUGO_AURA__.aikariStats) { if (result.success && global.__HUGO_AURA__.aikariStats) {
global.__HUGO_AURA__.aikariStats.connected = false; global.__HUGO_AURA__.aikariStats.connected = false;
@@ -547,7 +552,11 @@ const applyAikariIpcHandler = (ipcMain) => {
case "inst": case "inst":
// TODO: Impl Aikari INST // TODO: Impl Aikari INST
case "uninst": case "uninst":
// same return await functions.execCommand(
logHeader,
AIKARI_UNINSTALLER_PATH,
""
);
default: default:
return { success: false, errorObj: new Error("Method not found") }; return { success: false, errorObj: new Error("Method not found") };
} }

View File

@@ -54,6 +54,29 @@ const actions = {
return null; return null;
} }
}, },
getAikariPLSRules: async (wsObj) => {
const eventId = genRandomHex();
wsObj.send(
JSON.stringify({
module: "pls",
eventId,
method: "config.rules.getConfig",
})
);
const promise = new Promise((resolve) => {
wsGetCallbacks.set(eventId, resolve);
});
const data = await promise;
if (data.success) {
console.debug(
"[HugoAura / UI / Aikari OCMS] Received Aikari PLS rules: ",
data
);
return data.data;
} else {
return null;
}
},
}; };
const onAikariConnectedMsgSeq = async ({ curAikariStates, wsObj }) => { const onAikariConnectedMsgSeq = async ({ curAikariStates, wsObj }) => {
@@ -66,6 +89,7 @@ const onAikariConnectedMsgSeq = async ({ curAikariStates, wsObj }) => {
document.addEventListener("onAikariMessageRecv", onMsgRecvListener); document.addEventListener("onAikariMessageRecv", onMsgRecvListener);
// Get Aikari Version // Get Aikari Version
await actions.getAikariVersion(updatedAikariStates, wsObj); await actions.getAikariVersion(updatedAikariStates, wsObj);
// Get Aikari Launcher Config
const aikariLauncherConfig = await actions.getAikariLauncherConfig(wsObj); const aikariLauncherConfig = await actions.getAikariLauncherConfig(wsObj);
if (aikariLauncherConfig) { if (aikariLauncherConfig) {
global.ipcRenderer.invoke( global.ipcRenderer.invoke(
@@ -73,6 +97,14 @@ const onAikariConnectedMsgSeq = async ({ curAikariStates, wsObj }) => {
aikariLauncherConfig aikariLauncherConfig
); );
} }
// Get Aikari PLS Rules
const aikariPLSRules = await actions.getAikariPLSRules(wsObj);
if (aikariPLSRules) {
global.ipcRenderer.invoke(
`${IPC_METHOD_BASE}.updateAikariRules`,
aikariPLSRules
);
}
return updatedAikariStates; return updatedAikariStates;
}; };

View File

@@ -35,7 +35,12 @@ const { genRandomHex } = require("../../utils/crypto");
* @param {string} configKey * @param {string} configKey
* @param {any} configValue * @param {any} configValue
*/ */
const updateAikariConfigToRemote = async (configKey, configValue) => { const updateAikariConfigToRemote = async (
configKey,
configValue,
module = "launcher",
writeToDisk = true
) => {
const configLevels = configKey.split("."); const configLevels = configKey.split(".");
const aikariConfigUpdateEvent = new CustomEvent("onAikariConfigUpdate", { const aikariConfigUpdateEvent = new CustomEvent("onAikariConfigUpdate", {
@@ -57,18 +62,65 @@ const updateAikariConfigToRemote = async (configKey, configValue) => {
/** /**
* @type {ClientAikariRequest} * @type {ClientAikariRequest}
*/ */
/*
const data = { const data = {
method: "config.action.updateConfig", method: "config.actions.updateConfig",
data: { data: {
key: configKey, key: configKey,
value: configValue, value: configValue,
write: writeToDisk,
}, },
eventId: genRandomHex(), // 不用 crypto, 因为会带来不必要的性能开销 eventId: genRandomHex(), // 不用 crypto, 因为会带来不必要的性能开销
};*/ module: module,
// TODO: Impl this ↑ };
// global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.ws.sendWsMessage`, data); global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.ws.sendWsMessage`, data);
global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.syncAikariConfig`, {
basic: global.__HUGO_AURA__.aikariSettings,
rules: global.__HUGO_AURA__.aikariRules,
});
};
// [!] Will be deprecated
const updateAikariPLSRulesToRemote = async (
configKey,
configValue,
affiliated,
writeToDisk = true
) => {
const configLevels = configKey.split(".");
const aikariRuleConfigUpdateEvent = new CustomEvent("onAikariConfigUpdate", {
detail: {
path: configLevels,
value: configValue,
},
});
document.dispatchEvent(aikariRuleConfigUpdateEvent);
const settingsEntries = document.getElementsByClassName(
"aura-settings-entry"
);
if (settingsEntries.length > 0) {
Array.from(settingsEntries).forEach((entry) => {
entry.dispatchEvent(aikariRuleConfigUpdateEvent);
});
}
/**
* @type {ClientAikariRequest}
*/
const data = {
method: "config.rules.updateConfig",
data: {
key: configKey,
value: configValue,
write: writeToDisk,
affiliated,
},
eventId: genRandomHex(),
module: "pls",
};
global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.ws.sendWsMessage`, data);
global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.syncAikariConfig`, { global.ipcRenderer.invoke(`${IPC_METHOD_BASE}.syncAikariConfig`, {
basic: global.__HUGO_AURA__.aikariSettings, basic: global.__HUGO_AURA__.aikariSettings,
rules: global.__HUGO_AURA__.aikariRules, rules: global.__HUGO_AURA__.aikariRules,
@@ -80,4 +132,5 @@ module.exports = {
updateAikariStatusFromLocal, updateAikariStatusFromLocal,
updateAikariSettingsFromLocal, updateAikariSettingsFromLocal,
updateAikariConfigToRemote, updateAikariConfigToRemote,
updateAikariPLSRulesToRemote,
}; };

View File

@@ -0,0 +1,28 @@
const childProc = require("child_process");
const fileSystemRawCmds = {
getDiskCaptions: async () => {
const waitForCmd = new Promise((resolve) => {
childProc.exec(
"wmic logicaldisk get caption",
(error, stdout, stderr) => {
if (error) {
console.error(
`[HugoAura / UI / Composables / Raw CMD / FS] Failed to exec wmic getCaption: ${error}`
);
resolve([]);
}
const drives = stdout
.trim()
.split("\r\n")
.slice(1)
.map((line) => line.trim());
resolve(drives);
}
);
});
return waitForCmd;
},
};
module.exports = fileSystemRawCmds;

View File

@@ -50,9 +50,9 @@ const setDisableStatus = (el, isDisable, hint = null) => {
tooltipIns.enable(); tooltipIns.enable();
} }
} else { } else {
el.setAttribute("data-bs-toggle", "tooltip"); el.removeAttribute("data-bs-toggle");
el.setAttribute("data-bs-placement", "top"); el.removeAttribute("data-bs-placement");
el.setAttribute("data-bs-title", "None"); el.removeAttribute("data-bs-title");
el.classList.remove("ase-operation-area-disabled"); el.classList.remove("ase-operation-area-disabled");
const tooltipIns = bootstrap.Tooltip.getInstance(el); const tooltipIns = bootstrap.Tooltip.getInstance(el);
if (tooltipIns) { if (tooltipIns) {
@@ -100,7 +100,18 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
case "radio": { case "radio": {
const elValue = entry.valueGetter(); const elValue = entry.valueGetter();
const elArr = []; const elArr = [];
for (const template of entry.templates) { let targetTemplatesArr = [];
let targetTemplateLablesArr = [];
targetTemplatesArr =
typeof entry.templates === "function"
? entry.templates()
: entry.templates;
targetTemplateLablesArr =
typeof entry.templateLabels === "function"
? entry.templateLabels()
: entry.templateLabels;
for (const template of targetTemplatesArr) {
const inlineContainerEl = document.createElement("div"); const inlineContainerEl = document.createElement("div");
inlineContainerEl.classList.add("form-check", "form-check-inline"); inlineContainerEl.classList.add("form-check", "form-check-inline");
const radioEl = document.createElement("input"); const radioEl = document.createElement("input");
@@ -108,7 +119,7 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
radioEl.classList.add("form-check-input"); radioEl.classList.add("form-check-input");
radioEl.type = "radio"; radioEl.type = "radio";
radioEl.name = `${entry.id}Radios`; radioEl.name = `${entry.id}Radios`;
radioEl.id = `${entry.id}Radio${entry.templates.indexOf(template)}`; radioEl.id = `${entry.id}Radio${targetTemplatesArr.indexOf(template)}`;
radioEl.checked = template === elValue ? true : false; radioEl.checked = template === elValue ? true : false;
radioEl.addEventListener("change", async (event) => { radioEl.addEventListener("change", async (event) => {
if (event.target.checked) { if (event.target.checked) {
@@ -126,7 +137,53 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
labelEl.classList.add("form-check-label"); labelEl.classList.add("form-check-label");
labelEl.setAttribute("for", radioEl.id); labelEl.setAttribute("for", radioEl.id);
labelEl.textContent = labelEl.textContent =
entry.templateLabels[entry.templates.indexOf(template)]; targetTemplateLablesArr[targetTemplatesArr.indexOf(template)];
inlineContainerEl.appendChild(labelEl);
elArr.push(inlineContainerEl);
}
return elArr;
}
case "checkbox": {
const elValue = entry.valueGetter();
const elArr = [];
let targetTemplatesArr = [];
let targetTemplateLablesArr = [];
targetTemplatesArr =
typeof entry.templates === "function"
? entry.templates()
: entry.templates;
targetTemplateLablesArr =
typeof entry.templateLabels === "function"
? entry.templateLabels()
: entry.templateLabels;
for (const templateName of targetTemplatesArr) {
const inlineContainerEl = document.createElement("div");
inlineContainerEl.classList.add("form-check", "form-check-inline");
const chkBoxEl = document.createElement("input");
chkBoxEl.value = templateName;
chkBoxEl.classList.add("form-check-input");
chkBoxEl.type = "checkbox";
chkBoxEl.name = `${entry.id}Checkbox`;
chkBoxEl.id = `${entry.id}Checkbox${targetTemplatesArr.indexOf(
templateName
)}`;
chkBoxEl.checked = elValue.includes(templateName) ? true : false;
chkBoxEl.addEventListener("change", async (event) => {
showToast(entry);
await entry.callbackFn(
event.target.value,
chkBoxEl,
operationArea,
descriptionArea
);
});
inlineContainerEl.appendChild(chkBoxEl);
const labelEl = document.createElement("label");
labelEl.classList.add("form-check-label");
labelEl.setAttribute("for", chkBoxEl.id);
labelEl.textContent =
targetTemplateLablesArr[targetTemplatesArr.indexOf(templateName)];
inlineContainerEl.appendChild(labelEl); inlineContainerEl.appendChild(labelEl);
elArr.push(inlineContainerEl); elArr.push(inlineContainerEl);
} }
@@ -219,7 +276,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
powerIcon.setAttribute("data-bs-title", "需要重启 Electron 进程"); powerIcon.setAttribute("data-bs-title", "需要重启 Electron 进程");
entryTitle.appendChild(powerIcon); entryTitle.appendChild(powerIcon);
} }
if (entry.AikariRequired) { if (entry.aikariRequired) {
const aikariIcon = document.createElement("i"); const aikariIcon = document.createElement("i");
aikariIcon.classList.add( aikariIcon.classList.add(
"layui-icon", "layui-icon",
@@ -302,14 +359,14 @@ const renderNormalSettingsItem = (entry, formEl) => {
insertOrRemoveEl(entryOperationArea, targetEl, true); insertOrRemoveEl(entryOperationArea, targetEl, true);
} }
}; };
const channel = entry.AikariRequired const channel = entry.aikariRequired
? "onAikariConfigUpdate" ? "onAikariConfigUpdate"
: "onHugoAuraConfigUpdate"; : "onHugoAuraConfigUpdate";
entryContainerEl.addEventListener(channel, evtListener); entryContainerEl.addEventListener(channel, evtListener);
// createOnLeaveEvtListener(channel, evtListener); // createOnLeaveEvtListener(channel, evtListener);
} }
if (entry.AikariRequired) { if (entry.aikariRequired) {
if (!global.__HUGO_AURA__.aikariStats.connected) { if (!global.__HUGO_AURA__.aikariStats.connected) {
setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续"); setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续");
} }
@@ -332,7 +389,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
const isDisabledRet = entry.auraDisable(); const isDisabledRet = entry.auraDisable();
setDisableStatus( setDisableStatus(
entryOperationArea, entryOperationArea,
isDisabledRet.value, global.__HUGO_AURA__.aikariStats.connected ? isDisabledRet.value : true,
isDisabledRet.tooltip isDisabledRet.tooltip
); );
}; };
@@ -354,7 +411,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
updateDisableStatus(); updateDisableStatus();
} }
}; };
const channel = entry.AikariRequired const channel = entry.aikariRequired
? "onAikariConfigUpdate" ? "onAikariConfigUpdate"
: "onHugoAuraConfigUpdate"; : "onHugoAuraConfigUpdate";
entryContainerEl.addEventListener(channel, evtListener); entryContainerEl.addEventListener(channel, evtListener);
@@ -397,7 +454,9 @@ const renderPreviewItem = (entry, formEl) => {
}; };
document.addEventListener( document.addEventListener(
eventChannel === "pls" ? "onAikariConfigUpdate" : "onHugoAuraConfigUpdate", eventChannel === "aikari"
? "onAikariConfigUpdate"
: "onHugoAuraConfigUpdate",
eventListener eventListener
); );
createOnLeaveEvtListener(eventListener); // Clean up createOnLeaveEvtListener(eventListener); // Clean up

View File

@@ -6,9 +6,11 @@
let tooltipTriggerCache = null; let tooltipTriggerCache = null;
const refreshBsTooltip = (selector = '[data-bs-toggle="tooltip"]') => { const refreshBsTooltip = (selector = '[data-bs-toggle="tooltip"]') => {
if (tooltipTriggerCache) { if (tooltipTriggerCache) {
[...tooltipTriggerCache].map((el) => [...tooltipTriggerCache].map((el) => {
bootstrap.Tooltip.getInstance(el).disable() if (bootstrap.Tooltip.getInstance(el)) {
); bootstrap.Tooltip.getInstance(el).disable();
}
});
} }
const tooltipTriggerList = document.querySelectorAll(selector); const tooltipTriggerList = document.querySelectorAll(selector);

View File

@@ -27,7 +27,7 @@
<div <div
class="acs-bc-psp-operation-btn" class="acs-bc-psp-operation-btn"
aura-disabled="true" aura-disabled="true"
id="acsBcPsp-operBtn-Download" id="acsBcPsp-operBtn-Install"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@@ -44,10 +44,10 @@
d="M17 26.17V14h-2v12.17l-2.59-2.58L11 25l5 5l5-5l-1.41-1.41z" d="M17 26.17V14h-2v12.17l-2.59-2.58L11 25l5 5l5-5l-1.41-1.41z"
/> />
</svg> </svg>
<p>下载内核</p> <p>下载应用</p>
</div> </div>
<div class="acs-bc-psp-operation-btn" id="acsBcPsp-operBtn-Install"> <div class="acs-bc-psp-operation-btn" id="acsBcPsp-operBtn-InstallSvc">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
width="32" width="32"
@@ -72,7 +72,7 @@
<div <div
class="acs-bc-psp-operation-btn acs-bc-psp-o-btn-dangerous" class="acs-bc-psp-operation-btn acs-bc-psp-o-btn-dangerous"
id="acsBcPsp-operBtn-Uninstall" id="acsBcPsp-operBtn-UninstallSvc"
> >
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"

View File

@@ -33,7 +33,9 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
const toastHeaderEl = document.getElementById( const toastHeaderEl = document.getElementById(
"aikariStatusNotifyToastTitle" "aikariStatusNotifyToastTitle"
); );
const toastBodyEl = document.getElementById("aikariStatusNotifyToastBody"); const toastBodyEl = document.getElementById(
"aikariStatusNotifyToastBody"
);
const bsToastIns = bootstrap.Toast.getOrCreateInstance(toastRootEl); const bsToastIns = bootstrap.Toast.getOrCreateInstance(toastRootEl);
if (bsToastIns.isShown) { if (bsToastIns.isShown) {
@@ -96,7 +98,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.refreshAikariStatus(); global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.refreshAikariStatus();
}; };
break; break;
case "Download": case "Install":
btnEl.onclick = async () => { btnEl.onclick = async () => {
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.downloadAndInstallAikariBin(); global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.downloadAndInstallAikariBin();
}; };
@@ -104,10 +106,10 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
// ↓ 这边的确可以把这些全都合并到一个可复用 fn 里去, 但没必要 // ↓ 这边的确可以把这些全都合并到一个可复用 fn 里去, 但没必要
// 如果后续要引入错误视觉反馈, 合并到单个 fn 反而会增加实现复杂度 // 如果后续要引入错误视觉反馈, 合并到单个 fn 反而会增加实现复杂度
case "Install": case "InstallSvc":
btnEl.onclick = async () => { btnEl.onclick = async () => {
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateOperationBtnStatus( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateOperationBtnStatus(
"Install", "InstallSvc",
true true
); );
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
@@ -145,24 +147,26 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent(); global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent();
}; };
break; break;
case "Uninstall": case "UninstallSvc":
if (btnContent === "删除内核") { if (btnContent === "卸载应用") {
btnEl.onclick = async () => { btnEl.onclick = async () => {
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateOperationBtnStatus( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateOperationBtnStatus(
"Uninstall", "UninstallSvc",
true true
); );
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
"warning", "warning",
"正在删除内核", "正在卸载 Aikari",
null, `<p>
请在弹出窗口中完成操作
</p>`,
false, false,
false, false,
null null
); );
const ret = await ipcRenderer.invoke( const ret = await ipcRenderer.invoke(
`${IPC_METHOD_BASE}.aikariLifecycleControl`, `${IPC_METHOD_BASE}.aikariLifecycleControl`,
{ target: "rmBin" } { target: "uninst" }
); );
if (ret.success) { if (ret.success) {
lifecycleStatus.installed = false; lifecycleStatus.installed = false;
@@ -176,7 +180,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
); );
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
"success", "success",
"内核已删除", "Aikari 已完成卸载",
null, null,
true, true,
true, true,
@@ -185,7 +189,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
} else { } else {
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
"error", "error",
"内核删除失败", "Aikari 卸载失败",
`<p> `<p>
${ret.errorObj ? ret.errorObj : "检查日志以获取详细信息"} ${ret.errorObj ? ret.errorObj : "检查日志以获取详细信息"}
</p>`, </p>`,
@@ -199,7 +203,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
} else { } else {
btnEl.onclick = async () => { btnEl.onclick = async () => {
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateOperationBtnStatus( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateOperationBtnStatus(
"Uninstall", "UninstallSvc",
true true
); );
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast( global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateToast(
@@ -239,7 +243,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
} }
const ret = await ipcRenderer.invoke( const ret = await ipcRenderer.invoke(
`${IPC_METHOD_BASE}.aikariLifecycleControl`, `${IPC_METHOD_BASE}.aikariLifecycleControl`,
{ target: "rmSvc" } { target: "uninstSvc" }
); );
if (ret.success) { if (ret.success) {
lifecycleStatus.svcInstalled = false; lifecycleStatus.svcInstalled = false;
@@ -296,7 +300,9 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
2000 2000
); );
await global.__HUGO_AURA_GLOBAL__.utils.sleep(100); await global.__HUGO_AURA_GLOBAL__.utils.sleep(100);
await ipcRenderer.invoke(`${IPC_METHOD_BASE}.retryAikariConnect`); await ipcRenderer.invoke(
`${IPC_METHOD_BASE}.retryAikariConnect`
);
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent(); global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent();
} else { } else {
global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent(); global.__HUGO_AURA_UI_FUNCTIONS__.subConfig.aikariStatus.updateStatusContent();
@@ -375,20 +381,25 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
switch (lifecycleStatus.installed) { switch (lifecycleStatus.installed) {
case true: case true:
if (!lifecycleStatus.svcInstalled) { if (!lifecycleStatus.svcInstalled) {
updateStatusEl(acIdInst, atIdInst, "WARNING", "已下载, 服务未安装"); updateStatusEl(
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", false); acIdInst,
atIdInst,
"WARNING",
"应用已安装, 服务未安装"
);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("InstallSvc", false);
GLOBAL_FUNCTIONS.updateOperationBtnStatus( GLOBAL_FUNCTIONS.updateOperationBtnStatus(
"Uninstall", "UninstallSvc",
false, false,
"删除内核" "卸载应用"
); );
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Start", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Start", true);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Stop", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Stop", true);
} else { } else {
updateStatusEl(acIdInst, atIdInst, "SUCCESS", "已安装"); updateStatusEl(acIdInst, atIdInst, "SUCCESS", "已安装");
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("InstallSvc", true);
GLOBAL_FUNCTIONS.updateOperationBtnStatus( GLOBAL_FUNCTIONS.updateOperationBtnStatus(
"Uninstall", "UninstallSvc",
false, false,
"卸载服务" "卸载服务"
); );
@@ -396,9 +407,9 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
break; break;
case false: case false:
updateStatusEl(acIdInst, atIdInst, "PENDING", "未下载"); updateStatusEl(acIdInst, atIdInst, "PENDING", "未下载");
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Download", false); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", false);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("InstallSvc", true);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Uninstall", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("UninstallSvc", true);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Start", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Start", true);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Stop", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Stop", true);
} }
@@ -450,7 +461,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
if (curAikariStats.version && curAikariStats.version !== "unknown") { if (curAikariStats.version && curAikariStats.version !== "unknown") {
versionTextEl.textContent = curAikariStats.version; versionTextEl.textContent = curAikariStats.version;
} else { } else {
versionTextEl.textContent = "不可用" versionTextEl.textContent = "不可用";
} }
}, },
@@ -468,7 +479,10 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
const binExistsRet = await ipcRenderer.invoke( const binExistsRet = await ipcRenderer.invoke(
`${IPC_METHOD_BASE}.getIfAikariBinExists` `${IPC_METHOD_BASE}.getIfAikariBinExists`
); );
if ((binExistsRet.success && binExistsRet.data.isExists) || lifecycleStatus.detached) { if (
(binExistsRet.success && binExistsRet.data.isExists) ||
lifecycleStatus.detached
) {
lifecycleStatus.installed = true; lifecycleStatus.installed = true;
global.__HUGO_AURA__.aikariStats.installed = true; global.__HUGO_AURA__.aikariStats.installed = true;
ipcRenderer.invoke( ipcRenderer.invoke(
@@ -628,7 +642,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
const CUR_CHANNEL = `${IPC_METHOD_BASE}.post.reportAikariInstallStep`; const CUR_CHANNEL = `${IPC_METHOD_BASE}.post.reportAikariInstallStep`;
if (!retrieveMode) { if (!retrieveMode) {
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Download", true, "正在检查"); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true, "正在检查");
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", true);
await ipcRenderer.invoke(`${IPC_METHOD_BASE}.ensureAikariInstallDir`); await ipcRenderer.invoke(`${IPC_METHOD_BASE}.ensureAikariInstallDir`);
GLOBAL_FUNCTIONS.updateToast( GLOBAL_FUNCTIONS.updateToast(
@@ -639,7 +653,7 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
true, true,
2000 2000
); );
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Download", true); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Install", true);
} else { } else {
GLOBAL_FUNCTIONS.updateToast( GLOBAL_FUNCTIONS.updateToast(
"info", "info",
@@ -683,9 +697,9 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
ipcRenderer.off(CUR_CHANNEL, callbackFn); ipcRenderer.off(CUR_CHANNEL, callbackFn);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false);
GLOBAL_FUNCTIONS.updateOperationBtnStatus( GLOBAL_FUNCTIONS.updateOperationBtnStatus(
"Download", "Install",
false, false,
"下载内核" "下载应用"
); );
break; break;
case "done": case "done":
@@ -711,9 +725,9 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
ipcRenderer.off(CUR_CHANNEL, callbackFn); ipcRenderer.off(CUR_CHANNEL, callbackFn);
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false);
GLOBAL_FUNCTIONS.updateOperationBtnStatus( GLOBAL_FUNCTIONS.updateOperationBtnStatus(
"Download", "Install",
true, true,
"下载内核" "下载应用"
); );
lifecycleStatus.installed = true; lifecycleStatus.installed = true;
global.__HUGO_AURA__.aikariStats.installed = true; global.__HUGO_AURA__.aikariStats.installed = true;
@@ -756,9 +770,9 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
case "cancelled": case "cancelled":
GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false); GLOBAL_FUNCTIONS.updateOperationBtnStatus("Refresh", false);
GLOBAL_FUNCTIONS.updateOperationBtnStatus( GLOBAL_FUNCTIONS.updateOperationBtnStatus(
"Download", "Install",
false, false,
"下载内核" "下载应用"
); );
break; break;
} }
@@ -852,14 +866,16 @@ if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
"acs-bc-aikari-status-page-status-area success"; "acs-bc-aikari-status-page-status-area success";
break; break;
case "FAILED": case "FAILED":
areaContainerEl.className = "acs-bc-aikari-status-page-status-area failed"; areaContainerEl.className =
"acs-bc-aikari-status-page-status-area failed";
break; break;
case "WARNING": case "WARNING":
areaContainerEl.className = areaContainerEl.className =
"acs-bc-aikari-status-page-status-area warning"; "acs-bc-aikari-status-page-status-area warning";
break; break;
case "INFO": case "INFO":
areaContainerEl.className = "acs-bc-aikari-status-page-status-area info"; areaContainerEl.className =
"acs-bc-aikari-status-page-status-area info";
break; break;
default: default:
return false; return false;

View File

@@ -36,13 +36,13 @@
class="nav-link" class="nav-link"
id="security-config-tab" id="security-config-tab"
data-bs-toggle="pill" data-bs-toggle="pill"
data-bs-target="#security-config-subpage" data-bs-target="#device-info-post-config-subpage"
type="button" type="button"
role="tab" role="tab"
aria-controls="security-config-subpage" aria-controls="device-info-post-config-subpage"
aria-selected="false" aria-selected="false"
> >
设备安全 信息上报
</button> </button>
</li> </li>
</ul> </ul>
@@ -61,7 +61,7 @@
></div> ></div>
<div <div
class="tab-pane fade" class="tab-pane fade"
id="security-config-subpage" id="device-info-post-config-subpage"
role="tabpanel" role="tabpanel"
aria-labelledby="security-config-tab" aria-labelledby="security-config-tab"
></div> ></div>

View File

@@ -7,29 +7,41 @@
} = require(`${REQUIRE_BASE}/../../../../composables/settingsRenderer`); } = require(`${REQUIRE_BASE}/../../../../composables/settingsRenderer`);
const { basicSettings } = require(`${REQUIRE_BASE}/basic`); const { basicSettings } = require(`${REQUIRE_BASE}/basic`);
const { deviceSecuritySettings } = require(`${REQUIRE_BASE}/deviceSecurity`); const { deviceInfoPostSettings } = require(`${REQUIRE_BASE}/deviceInfoPost`);
const { const {
updateAikariSettingsFromLocal, updateAikariSettingsFromLocal,
updateAikariRulesFromLocal, updateAikariRulesFromLocal,
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`); } = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
const fileSystemRawCmds = require(`${REQUIRE_BASE}/../../../../composables/rawCmdExec/fs`);
const initStatusPage = () => { const initStatusPage = () => {
global.__HUGO_AURA_LOADER__[ global.__HUGO_AURA_LOADER__[
"Aura.UI.Assistant.Config.BehaviourCtrl.AikariStatus" "Aura.UI.Assistant.Config.BehaviourCtrl.AikariStatus"
].active = true; ].active = true;
}; };
const preInitUIReactives = async () => {
if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig)
global.__HUGO_AURA_UI_REACTIVES__.subConfig = {};
if (!global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared)
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared = {};
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared.diskCaptions =
await fileSystemRawCmds.getDiskCaptions();
};
const initBasicSettingsPage = () => { const initBasicSettingsPage = () => {
const basicSubPageEl = document.getElementById("basic-config-subpage"); const basicSubPageEl = document.getElementById("basic-config-subpage");
settingsRenderer(basicSubPageEl, basicSettings); settingsRenderer(basicSubPageEl, basicSettings);
}; };
const initDeviceSecuritySettingsPage = () => { const initDeviceInfoPostSettingsPage = () => {
const deviceSecuritySubPageEl = document.getElementById( const deviceInfoPostSubPageEl = document.getElementById(
"security-config-subpage" "device-info-post-config-subpage"
); );
settingsRenderer(deviceSecuritySubPageEl, deviceSecuritySettings); settingsRenderer(deviceInfoPostSubPageEl, deviceInfoPostSettings);
}; };
const renderSubPages = async () => { const renderSubPages = async () => {
@@ -37,15 +49,16 @@
await updateAikariRulesFromLocal(); await updateAikariRulesFromLocal();
initBasicSettingsPage(); initBasicSettingsPage();
initDeviceSecuritySettingsPage(); initDeviceInfoPostSettingsPage();
}; };
const onMounted = () => { const onMounted = () => {
const rootEl = document.getElementById("acs-behaviour-control-el"); const rootEl = document.getElementById("acs-behaviour-control-el");
preInitUIReactives();
initStatusPage(); initStatusPage();
setTimeout(() => { setTimeout(() => {
rootEl.classList.remove("acs-behaviour-control-hidden"); rootEl.classList.remove("acs-behaviour-control-hidden");
renderSubPages(); // 如果立即渲染子页面, 此时 plsRules 还未初始化, 会导致子页面 auraIf 失效 renderSubPages();
}, 500); }, 500);
}; };

View File

@@ -4,28 +4,6 @@ const {
updateAikariConfigToRemote, updateAikariConfigToRemote,
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`); } = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
const reusableChkFn = {
checkRelativePath: () => {
if (newVal === "" || !newVal)
return { valid: false, hint: "请输入证书路径" };
if (newVal.includes(":/") || newVal.includes(":\\")) {
return { valid: false, hint: "请输入相对路径, 而非绝对路径" };
}
if (newVal.includes("\\")) {
return {
valid: false,
hint: '请输入正确的路径, 使用 "/" 作为路径符',
};
}
return {
valid: true,
};
},
};
const basicSettings = [ const basicSettings = [
{ {
id: 0, id: 0,
@@ -33,137 +11,70 @@ const basicSettings = [
child: [ child: [
{ {
index: 0, index: 0,
id: "plsListenPort", id: "aikarWsPreferPort",
type: "input", type: "input",
subType: "number", subType: "number",
name: "PLS WS 默认监听端口", name: "Aikari WS 默认监听端口",
description: "PLS 的 WebSocket 服务器默认监听指定的端口", description: "Aikari WebSocket 服务器默认监听的端口",
reactive: true, reactive: true,
reactiveVal: ["root.settings"], reactiveVal: ["root.settings"],
restart: false, restart: false,
reload: false, reload: false,
AikariRequired: true, aikariRequired: true,
restartAikari: false, restartAikari: false,
warning: true, warning: true,
warningContent: "PLS 仍会在默认端口被占用时, 自动随机端口重试", warningContent: "Aikari 仍会在默认端口被占用时, 自动随机端口重试",
associateVal: null, associateVal: null,
auraIf: () => true, auraIf: () => true,
defaultValue: "", defaultValue: "",
placeHolder: "输入端口号 (10000 ~ 65535)", placeHolder: "输入端口号 (10000 ~ 65535)",
valueGetter: () => { valueGetter: () => {
if (!global.__HUGO_AURA__.aikariSettings) return ""; if (!global.__HUGO_AURA__.aikariSettings) return "";
return global.__HUGO_AURA__.aikariSettings.wsPort; return global.__HUGO_AURA__.aikariSettings.wsPreferPort;
}, },
callbackFn: (newVal) => { callbackFn: (newVal) => {
if (newVal === "" || !newVal) if (newVal === "" || !newVal)
return { valid: false, hint: "请输入端口号" }; return { valid: false, hint: "请输入端口号" };
const numberNewVal = Number(newVal); const numberNewVal = Number(newVal);
if (numberNewVal === NaN || !(10000 <= numberNewVal) || !(newVal <= 65535)) { if (
numberNewVal === NaN ||
!(10000 <= numberNewVal) ||
!(newVal <= 65535)
) {
return { valid: false, hint: "请输入合法的端口号 (10000 ~ 65535)" }; return { valid: false, hint: "请输入合法的端口号 (10000 ~ 65535)" };
} }
global.__HUGO_AURA__.aikariSettings.wsPort = numberNewVal; global.__HUGO_AURA__.aikariSettings.wsPreferPort = numberNewVal;
updateAikariConfigToRemote("wsPort", numberNewVal); updateAikariConfigToRemote("wsPreferPort", numberNewVal);
return { valid: true }; return { valid: true };
}, },
}, },
{ {
index: 1, index: 1,
id: "plsCertPath", id: "aikariForceRegenWsTlsCert",
type: "input",
subType: "text",
name: "WSS TLS 证书相对路径",
description: "PLS 将使用指定路径下的证书启动 WSS 服务器",
reactive: true,
reactiveVal: ["root.settings"],
restart: false,
reload: false,
AikariRequired: true,
restartAikari: true,
tip: true,
tipTitle:
'路径相对于 "%PROGRAMDATA%\\HugoAura\\Aura-PLS\\", 使用 "/" 作为路径符',
associateVal: null,
auraIf: () => true,
defaultValue: "",
placeHolder: "输入相对路径, 例如: config/vme50/cert.crt",
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariSettings) return "";
return global.__HUGO_AURA__.aikariSettings.certPath;
},
callbackFn: (newVal) => {
const validate = reusableChkFn.checkRelativePath();
if (!validate.valid) {
return validate;
}
global.__HUGO_AURA__.aikariSettings.certPath = newVal;
updateAikariConfigToRemote("certPath", newVal);
return { valid: true };
},
},
{
index: 2,
id: "plsCertPath",
type: "input",
subType: "text",
name: "WSS TLS 证书私钥相对路径",
description: "PLS 将使用指定路径下的私钥启动 WSS 服务器",
reactive: true,
reactiveVal: ["root.settings"],
restart: false,
reload: false,
AikariRequired: true,
restartAikari: true,
tip: true,
tipTitle:
'路径相对于 "%PROGRAMDATA%\\HugoAura\\Aura-PLS\\", 使用 "/" 作为路径符',
warning: true,
warningContent: "请使用 PEM 格式的密钥",
associateVal: null,
auraIf: () => true,
defaultValue: "",
placeHolder: "输入相对路径, 例如: config/vme50/cert.key",
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariSettings) return "";
return global.__HUGO_AURA__.aikariSettings.keyPath;
},
callbackFn: (newVal) => {
const validate = reusableChkFn.checkRelativePath();
if (!validate.valid) {
return validate;
}
global.__HUGO_AURA__.aikariSettings.keyPath = newVal;
updateAikariConfigToRemote("keyPath", newVal);
return { valid: true };
},
},
{
index: 3,
id: "plsRegenCertAftRelaunch",
type: "switch", type: "switch",
name: "重新生成 TLS 证书", name: "重新生成 WS TLS 证书",
description: "PLS 将在下次启动时重新生成 TLS 证书", description: "Aikari 将在下次启动时重新生成用于 WebSocket 的 TLS 证书",
reactive: true, reactive: true,
reactiveVal: ["root.settings"], reactiveVal: ["root.settings"],
restart: false, restart: false,
reload: false, reload: false,
AikariRequired: true, aikariRequired: true,
restartAikari: true, restartAikari: true,
associateVal: null, associateVal: null,
auraIf: () => true, auraIf: () => true,
defaultValue: false, defaultValue: false,
valueGetter: () => { valueGetter: () => {
if (!global.__HUGO_AURA__.aikariSettings) return ""; if (!global.__HUGO_AURA__.aikariSettings) return "";
return global.__HUGO_AURA__.aikariSettings.regenCert; return global.__HUGO_AURA__.aikariSettings.tls.regenWsCertNextLaunch;
}, },
callbackFn: (newVal) => { callbackFn: (newVal) => {
if (typeof newVal !== "boolean") return false; if (typeof newVal !== "boolean") return false;
global.__HUGO_AURA__.aikariSettings.regenCert = newVal; global.__HUGO_AURA__.aikariSettings.tls.regenWsCertNextLaunch =
updateAikariConfigToRemote("regenCert", newVal); newVal;
updateAikariConfigToRemote("tls.regenWsCertNextLaunch", newVal);
return true; return true;
}, },
}, },

View File

@@ -0,0 +1,257 @@
// [!] Will be deprecated
const REQUIRE_BASE = ".";
const {
updateAikariPLSRulesToRemote,
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
const composables = {};
const deviceInfoPostSettings = [
{
id: 0,
categoryName: "冰点管理",
child: [
{
index: 0,
id: "enableFreezeInfoReportOverride",
type: "switch",
name: "启用冰冻状态篡改",
description: "篡改上报的冰冻数据, 可自定义集控端显示的状态",
reactive: true,
reactiveVal: ["root.ruleSettings"],
restart: false,
reload: false,
aikariRequired: true,
restartAikari: false,
associateVal: null,
auraIf: () => true,
defaultValue: false,
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariRules) return "";
return global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies
.freezeManagement.freezeDiskInfoPost.enabled;
},
callbackFn: (newVal) => {
if (typeof newVal !== "boolean") return;
if (!global.__HUGO_AURA__.aikariRules) return;
global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost.enabled =
newVal;
updateAikariPLSRulesToRemote(
"ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost.enabled",
newVal,
"ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost"
);
return true;
},
},
{
index: 1,
id: "freezeInfoReportFrozenDisks",
type: "checkbox",
name: "被冻结的磁盘",
description: "选中的磁盘会<b>被上报</b>为冻结 (不是实际行为)",
restart: false,
reload: false,
aikariRequired: true,
restartAikari: false,
warning: true,
warningContent:
"如果可选的磁盘盘符与下方预览不一致, 则多出的盘符可能为 DVD 驱动器 / 软盘 / 可移动磁盘, 忽略即可",
reactive: true,
reactiveVal: ["root.ruleSettings"],
associateVal: [
"ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost.enabled",
],
auraIf: () => true,
auraDisable: () => {
if (!global.__HUGO_AURA__.aikariRules) return { value: true };
if (
!global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared
.diskCaptions
)
return {
value: true,
tooltip: "发生错误, 请上报至 HugoAura GitHub Issues",
};
if (
!global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared
.diskCaptions.length === 0
)
return {
value: true,
tooltip: "发生错误, 请上报至 HugoAura GitHub Issues",
};
return {
value:
!global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies
.freezeManagement.freezeDiskInfoPost.enabled,
};
},
defaultValue: [],
templates: () => {
try {
if (
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared
.diskCaptions.length === 0
) {
return ["error"];
} else {
return global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared.diskCaptions.map(
(element) => {
return element.toLowerCase().replace(/:/g, "");
}
);
}
} catch (err) {
console.error(err);
return ["error"];
}
},
templateLabels: () => {
try {
if (
global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared
.diskCaptions.length === 0
) {
return ["获取盘符时发生错误, 请上报至 GitHub Issues"];
} else {
return global.__HUGO_AURA_UI_REACTIVES__.subConfig.behaviourCtrlShared.diskCaptions.map(
(element) => {
return element.replace(/:/g, " 盘");
}
);
}
} catch (err) {
console.error(err);
return ["发生未知错误"];
}
},
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariRules) return [];
return global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies
.freezeManagement.freezeDiskInfoPost.frozenDisks;
},
callbackFn: (affectedData, affectedEl) => {
const targetArr =
global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies
.freezeManagement.freezeDiskInfoPost.frozenDisks;
if (affectedEl.checked) {
targetArr.push(affectedData);
} else {
targetArr.splice(targetArr.indexOf(affectedData), 1);
}
updateAikariPLSRulesToRemote(
"ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost.frozenDisks",
targetArr,
"ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost"
);
return true;
},
},
{
index: 2,
id: "freezeInfoReportOverridePreview",
type: "preview",
loaderTarget:
"Aura.UI.Assistant.Config.BehaviourCtrl.DeviceSecurity.FreezeOverridePreview",
associateVal: [
"ssaFeatures.securityPolicies.freezeManagement.freezeDiskInfoPost.frozenDisks",
],
listenerType: "aikari",
},
],
},
{
id: 1,
categoryName: "软件信息",
child: [
{
index: 0,
id: "enableSoftwareReportPostOverride",
type: "switch",
name: "启用软件信息上报覆写",
description:
'覆写上报的软件信息, 可自定义集控端 "设备管控" - <设备名> - "软件列表" 下的信息显示',
reactive: true,
reactiveVal: ["root.ruleSettings"],
restart: false,
reload: false,
aikariRequired: true,
restartAikari: false,
warning: true,
warningContent: '此功能与 "弹窗拦截" 等无关',
associateVal: null,
auraIf: () => true,
defaultValue: false,
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariRules) return false;
return global.__HUGO_AURA__.aikariRules.deviceInfo.software
.softwareReportPost.enabled;
},
callbackFn: (newVal) => {
if (typeof newVal !== "boolean") return;
if (!global.__HUGO_AURA__.aikariRules) return;
global.__HUGO_AURA__.aikariRules.deviceInfo.software.softwareReportPost.enabled =
newVal;
updateAikariPLSRulesToRemote(
"deviceInfo.software.softwareReportPost.enabled",
newVal,
"deviceInfo.software.softwareReportPost"
);
return true;
},
},
{
index: 1,
id: "enableSoftwareReportPostSetAsEmpty",
type: "switch",
name: "清空软件上报列表",
description: "将上报列表置空, 集控端将无法看到任何已安装应用",
reactive: true,
reactiveVal: ["root.ruleSettings"],
restart: false,
reload: false,
aikariRequired: true,
restartAikari: false,
associateVal: ["deviceInfo.software.softwareReportPost.enabled"],
auraIf: () => true,
auraDisable: () => {
if (!global.__HUGO_AURA__.aikariRules) return { value: true };
return {
value:
!global.__HUGO_AURA__.aikariRules.deviceInfo.software
.softwareReportPost.enabled,
};
},
defaultValue: true,
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariRules) return true;
return global.__HUGO_AURA__.aikariRules.deviceInfo.software
.softwareReportPost.setAsEmpty;
},
callbackFn: (newVal) => {
if (typeof newVal !== "boolean") return;
if (!global.__HUGO_AURA__.aikariRules) return;
global.__HUGO_AURA__.aikariRules.deviceInfo.software.softwareReportPost.setAsEmpty =
newVal;
updateAikariPLSRulesToRemote(
"deviceInfo.software.softwareReportPost.setAsEmpty",
newVal,
"deviceInfo.software.softwareReportPost"
);
return true;
},
},
],
},
];
module.exports = { deviceInfoPostSettings };

View File

@@ -1,99 +0,0 @@
const REQUIRE_BASE = ".";
const {
updateAikariConfigToRemote,
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
const composables = {};
const deviceSecuritySettings = [
{
id: 0,
categoryName: "冰点管理",
child: [
{
index: 0,
id: "enableFreezeInfoReportOverride",
type: "switch",
name: "启用冰冻状态篡改",
description: "篡改上报的冰冻数据, 可自定义集控端显示的状态",
reactive: true,
reactiveVal: ["root.ruleSettings"],
restart: false,
reload: false,
AikariRequired: true,
restartAikari: false,
associateVal: null,
auraIf: () => true,
defaultValue: false,
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariRules) return "";
return global.__HUGO_AURA__.aikariRules.client.security.uploadFreezeInfo
.enable;
},
callbackFn: (newVal) => {
if (typeof newVal !== "boolean") return;
if (!global.__HUGO_AURA__.aikariRules) return;
global.__HUGO_AURA__.aikariRules.client.security.uploadFreezeInfo.enable =
newVal;
updateAikariConfigToRemote(
"ruleSettings.client.security.uploadFreezeInfo.enable",
newVal
);
return true;
},
},
{
index: 1,
id: "freezeInfoReportOverrideType",
type: "radio",
name: "篡改模式",
description:
"选择一种篡改模式, 选中的磁盘范围会<b>被上报</b>为冻结 (不是实际行为)",
restart: false,
reload: false,
AikariRequired: true,
restartAikari: false,
reactive: true,
reactiveVal: ["root.ruleSettings"],
associateVal: ["ruleSettings.client.security.uploadFreezeInfo.enable"],
auraIf: () => {
if (!global.__HUGO_AURA__.aikariRules) return true;
return global.__HUGO_AURA__.aikariRules.client.security.uploadFreezeInfo
.enable;
},
defaultValue: "allFreeze",
templates: ["allFreeze", "systemOnly", "exceptSecondDisk"],
templateLabels: ["全部冻结", "仅系统盘", "第二磁盘除外"],
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariRules) return;
return global.__HUGO_AURA__.aikariRules.client.security.uploadFreezeInfo
.rewriteMode;
},
callbackFn: (newVal) => {
global.__HUGO_AURA__.aikariRules.client.security.uploadFreezeInfo.rewriteMode =
newVal;
updateAikariConfigToRemote(
"ruleSettings.client.security.uploadFreezeInfo.rewriteMode",
newVal
);
return true;
},
},
{
index: 2,
id: "freezeInfoReportOverridePreview",
type: "preview",
loaderTarget:
"Aura.UI.Assistant.Config.BehaviourCtrl.DeviceSecurity.FreezeOverridePreview",
associateVal: ["ruleSettings.client.security.uploadFreezeInfo"],
listenerType: "pls",
},
],
},
];
module.exports = { deviceSecuritySettings };

View File

@@ -36,8 +36,8 @@
resolve({ resolve({
success: true, success: true,
data: null, data: null,
status: response.status status: response.status,
}) });
} }
const parsedData = await response.json(); const parsedData = await response.json();
@@ -84,7 +84,7 @@
const diskElTemplate = document.createElement("p"); const diskElTemplate = document.createElement("p");
diskElTemplate.classList.add("acs-bc-dsc-fop-disk-el"); diskElTemplate.classList.add("acs-bc-dsc-fop-disk-el");
if (!curConfig.enable) { if (!curConfig.enabled) {
for (const disk of curDisks) { for (const disk of curDisks) {
const curDiskEl = diskElTemplate.cloneNode(); const curDiskEl = diskElTemplate.cloneNode();
if (disk.status !== 0) { if (disk.status !== 0) {
@@ -95,44 +95,16 @@
diskContainerEl.appendChild(curDiskEl); diskContainerEl.appendChild(curDiskEl);
} }
} else { } else {
switch (curConfig.rewriteMode) { let idx = 0;
case "allFreeze": for (const disk of curDisks) {
{ const curDiskEl = diskElTemplate.cloneNode();
for (const disk of curDisks) { if (curConfig.frozenDisks.includes(disk.name.toLowerCase())) {
const curDiskEl = diskElTemplate.cloneNode(); // @ts-expect-error
// @ts-expect-error curDiskEl.classList.add("active");
curDiskEl.classList.add("active"); }
curDiskEl.textContent = `${disk.name.toUpperCase()}`; curDiskEl.textContent = `${disk.name.toUpperCase()}`;
diskContainerEl.appendChild(curDiskEl); diskContainerEl.appendChild(curDiskEl);
} idx += 1;
}
break;
case "systemOnly":
{
let idx = 0;
for (const disk of curDisks) {
const curDiskEl = diskElTemplate.cloneNode();
// @ts-expect-error
if (idx === 0) curDiskEl.classList.add("active");
curDiskEl.textContent = `${disk.name.toUpperCase()}`;
diskContainerEl.appendChild(curDiskEl);
idx += 1;
}
}
break;
case "exceptSecondDisk":
{
let idx = 0;
for (const disk of curDisks) {
const curDiskEl = diskElTemplate.cloneNode();
// @ts-expect-error
if (idx === 0) curDiskEl.classList.add("active");
curDiskEl.textContent = `${disk.name.toUpperCase()}`;
diskContainerEl.appendChild(curDiskEl);
idx += 1;
}
}
break;
} }
} }
@@ -148,10 +120,10 @@
)[0]; )[0];
const eventListener = (_event) => { const eventListener = (_event) => {
// if (!global.__HUGO_AURA__.plsRules) return; if (!global.__HUGO_AURA__.aikariRules) return;
composables.getAndUpdateDiskInfo( composables.getAndUpdateDiskInfo(
// global.__HUGO_AURA__.plsRules.client.security.uploadFreezeInfo global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies
{ enable: false } .freezeManagement.freezeDiskInfoPost
); );
}; };
rootEl.addEventListener("onAssociateValueUpdated", eventListener); rootEl.addEventListener("onAssociateValueUpdated", eventListener);