diff --git a/src/aura/init/main/ipcModules/aikariIpcHandler.js b/src/aura/init/main/ipcModules/aikariIpcHandler.js
index f8cf273..cb016b3 100644
--- a/src/aura/init/main/ipcModules/aikariIpcHandler.js
+++ b/src/aura/init/main/ipcModules/aikariIpcHandler.js
@@ -218,12 +218,17 @@ const applyAikariIpcHandler = (ipcMain) => {
const AIKARI_DEFAULT_INSTALL_DIR = path.join(
"C:\\Program Files",
- "HugoAura Aikari"
+ "HugoAura",
+ "Aikari"
);
const AIKARI_LAUNCHER_PATH = path.join(
AIKARI_DEFAULT_INSTALL_DIR,
"Aikari-Launcher.exe"
);
+ const AIKARI_UNINSTALLER_PATH = path.join(
+ AIKARI_DEFAULT_INSTALL_DIR,
+ "unins000.exe"
+ );
const AIKARI_SVC_NAME = "HugoAuraAikari";
const isAikariDetached = process.argv.includes("--aikari-detach");
@@ -502,27 +507,27 @@ const applyAikariIpcHandler = (ipcMain) => {
return await functions.execCommand(
logHeader,
AIKARI_LAUNCHER_PATH,
- "--startup auto install"
+ "--service install"
);
case "uninstSvc": {
const result = await functions.execCommand(
logHeader,
AIKARI_LAUNCHER_PATH,
- "remove"
+ "--service uninstall"
);
return result;
}
case "startSvc":
return await functions.execCommand(
logHeader,
- AIKARI_LAUNCHER_PATH,
- "start"
+ "sc.exe",
+ `start ${AIKARI_SVC_NAME}`
);
case "stopSvc": {
const result = await functions.execCommand(
logHeader,
- AIKARI_LAUNCHER_PATH,
- "stop"
+ "sc.exe",
+ `stop ${AIKARI_SVC_NAME}`
);
if (result.success && global.__HUGO_AURA__.aikariStats) {
global.__HUGO_AURA__.aikariStats.connected = false;
@@ -547,7 +552,11 @@ const applyAikariIpcHandler = (ipcMain) => {
case "inst":
// TODO: Impl Aikari INST
case "uninst":
- // same
+ return await functions.execCommand(
+ logHeader,
+ AIKARI_UNINSTALLER_PATH,
+ ""
+ );
default:
return { success: false, errorObj: new Error("Method not found") };
}
diff --git a/src/aura/ui/aikari/onConnectedSeq.js b/src/aura/ui/aikari/onConnectedSeq.js
index c4e287a..c8af9ea 100644
--- a/src/aura/ui/aikari/onConnectedSeq.js
+++ b/src/aura/ui/aikari/onConnectedSeq.js
@@ -54,6 +54,29 @@ const actions = {
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 }) => {
@@ -66,6 +89,7 @@ const onAikariConnectedMsgSeq = async ({ curAikariStates, wsObj }) => {
document.addEventListener("onAikariMessageRecv", onMsgRecvListener);
// Get Aikari Version
await actions.getAikariVersion(updatedAikariStates, wsObj);
+ // Get Aikari Launcher Config
const aikariLauncherConfig = await actions.getAikariLauncherConfig(wsObj);
if (aikariLauncherConfig) {
global.ipcRenderer.invoke(
@@ -73,6 +97,14 @@ const onAikariConnectedMsgSeq = async ({ curAikariStates, wsObj }) => {
aikariLauncherConfig
);
}
+ // Get Aikari PLS Rules
+ const aikariPLSRules = await actions.getAikariPLSRules(wsObj);
+ if (aikariPLSRules) {
+ global.ipcRenderer.invoke(
+ `${IPC_METHOD_BASE}.updateAikariRules`,
+ aikariPLSRules
+ );
+ }
return updatedAikariStates;
};
diff --git a/src/aura/ui/composables/aikariConfigManager.js b/src/aura/ui/composables/aikariConfigManager.js
index 51828b7..abd536a 100644
--- a/src/aura/ui/composables/aikariConfigManager.js
+++ b/src/aura/ui/composables/aikariConfigManager.js
@@ -35,7 +35,12 @@ const { genRandomHex } = require("../../utils/crypto");
* @param {string} configKey
* @param {any} configValue
*/
-const updateAikariConfigToRemote = async (configKey, configValue) => {
+const updateAikariConfigToRemote = async (
+ configKey,
+ configValue,
+ module = "launcher",
+ writeToDisk = true
+) => {
const configLevels = configKey.split(".");
const aikariConfigUpdateEvent = new CustomEvent("onAikariConfigUpdate", {
@@ -57,18 +62,65 @@ const updateAikariConfigToRemote = async (configKey, configValue) => {
/**
* @type {ClientAikariRequest}
*/
- /*
const data = {
- method: "config.action.updateConfig",
+ method: "config.actions.updateConfig",
data: {
key: configKey,
value: configValue,
+ write: writeToDisk,
},
eventId: genRandomHex(), // 不用 crypto, 因为会带来不必要的性能开销
- };*/
- // TODO: Impl this ↑
+ module: module,
+ };
- // 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`, {
basic: global.__HUGO_AURA__.aikariSettings,
rules: global.__HUGO_AURA__.aikariRules,
@@ -80,4 +132,5 @@ module.exports = {
updateAikariStatusFromLocal,
updateAikariSettingsFromLocal,
updateAikariConfigToRemote,
+ updateAikariPLSRulesToRemote,
};
diff --git a/src/aura/ui/composables/rawCmdExec/fs.js b/src/aura/ui/composables/rawCmdExec/fs.js
new file mode 100644
index 0000000..7cf3a80
--- /dev/null
+++ b/src/aura/ui/composables/rawCmdExec/fs.js
@@ -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;
diff --git a/src/aura/ui/composables/settingsRenderer.js b/src/aura/ui/composables/settingsRenderer.js
index c148407..946ab76 100755
--- a/src/aura/ui/composables/settingsRenderer.js
+++ b/src/aura/ui/composables/settingsRenderer.js
@@ -50,9 +50,9 @@ const setDisableStatus = (el, isDisable, hint = null) => {
tooltipIns.enable();
}
} else {
- el.setAttribute("data-bs-toggle", "tooltip");
- el.setAttribute("data-bs-placement", "top");
- el.setAttribute("data-bs-title", "None");
+ el.removeAttribute("data-bs-toggle");
+ el.removeAttribute("data-bs-placement");
+ el.removeAttribute("data-bs-title");
el.classList.remove("ase-operation-area-disabled");
const tooltipIns = bootstrap.Tooltip.getInstance(el);
if (tooltipIns) {
@@ -100,7 +100,18 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
case "radio": {
const elValue = entry.valueGetter();
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");
inlineContainerEl.classList.add("form-check", "form-check-inline");
const radioEl = document.createElement("input");
@@ -108,7 +119,7 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
radioEl.classList.add("form-check-input");
radioEl.type = "radio";
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.addEventListener("change", async (event) => {
if (event.target.checked) {
@@ -126,7 +137,53 @@ const renderInputArea = (entry, operationArea, descriptionArea) => {
labelEl.classList.add("form-check-label");
labelEl.setAttribute("for", radioEl.id);
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);
elArr.push(inlineContainerEl);
}
@@ -219,7 +276,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
powerIcon.setAttribute("data-bs-title", "需要重启 Electron 进程");
entryTitle.appendChild(powerIcon);
}
- if (entry.AikariRequired) {
+ if (entry.aikariRequired) {
const aikariIcon = document.createElement("i");
aikariIcon.classList.add(
"layui-icon",
@@ -302,14 +359,14 @@ const renderNormalSettingsItem = (entry, formEl) => {
insertOrRemoveEl(entryOperationArea, targetEl, true);
}
};
- const channel = entry.AikariRequired
+ const channel = entry.aikariRequired
? "onAikariConfigUpdate"
: "onHugoAuraConfigUpdate";
entryContainerEl.addEventListener(channel, evtListener);
// createOnLeaveEvtListener(channel, evtListener);
}
- if (entry.AikariRequired) {
+ if (entry.aikariRequired) {
if (!global.__HUGO_AURA__.aikariStats.connected) {
setDisableStatus(entryOperationArea, true, "连接至 Aikari 以继续");
}
@@ -332,7 +389,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
const isDisabledRet = entry.auraDisable();
setDisableStatus(
entryOperationArea,
- isDisabledRet.value,
+ global.__HUGO_AURA__.aikariStats.connected ? isDisabledRet.value : true,
isDisabledRet.tooltip
);
};
@@ -354,7 +411,7 @@ const renderNormalSettingsItem = (entry, formEl) => {
updateDisableStatus();
}
};
- const channel = entry.AikariRequired
+ const channel = entry.aikariRequired
? "onAikariConfigUpdate"
: "onHugoAuraConfigUpdate";
entryContainerEl.addEventListener(channel, evtListener);
@@ -397,7 +454,9 @@ const renderPreviewItem = (entry, formEl) => {
};
document.addEventListener(
- eventChannel === "pls" ? "onAikariConfigUpdate" : "onHugoAuraConfigUpdate",
+ eventChannel === "aikari"
+ ? "onAikariConfigUpdate"
+ : "onHugoAuraConfigUpdate",
eventListener
);
createOnLeaveEvtListener(eventListener); // Clean up
diff --git a/src/aura/ui/js/global.js b/src/aura/ui/js/global.js
index 4605597..124f32c 100755
--- a/src/aura/ui/js/global.js
+++ b/src/aura/ui/js/global.js
@@ -6,9 +6,11 @@
let tooltipTriggerCache = null;
const refreshBsTooltip = (selector = '[data-bs-toggle="tooltip"]') => {
if (tooltipTriggerCache) {
- [...tooltipTriggerCache].map((el) =>
- bootstrap.Tooltip.getInstance(el).disable()
- );
+ [...tooltipTriggerCache].map((el) => {
+ if (bootstrap.Tooltip.getInstance(el)) {
+ bootstrap.Tooltip.getInstance(el).disable();
+ }
+ });
}
const tooltipTriggerList = document.querySelectorAll(selector);
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.html b/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.html
index 99d736a..1b1cdf2 100644
--- a/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.html
+++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/aikariStatus.html
@@ -27,7 +27,7 @@
+
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js
index 23a8585..6df1c69 100755
--- a/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js
+++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/behaviourCtrl.js
@@ -7,29 +7,41 @@
} = require(`${REQUIRE_BASE}/../../../../composables/settingsRenderer`);
const { basicSettings } = require(`${REQUIRE_BASE}/basic`);
- const { deviceSecuritySettings } = require(`${REQUIRE_BASE}/deviceSecurity`);
+ const { deviceInfoPostSettings } = require(`${REQUIRE_BASE}/deviceInfoPost`);
const {
updateAikariSettingsFromLocal,
updateAikariRulesFromLocal,
} = require(`${REQUIRE_BASE}/../../../../composables/aikariConfigManager`);
+ const fileSystemRawCmds = require(`${REQUIRE_BASE}/../../../../composables/rawCmdExec/fs`);
+
const initStatusPage = () => {
global.__HUGO_AURA_LOADER__[
"Aura.UI.Assistant.Config.BehaviourCtrl.AikariStatus"
].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 basicSubPageEl = document.getElementById("basic-config-subpage");
settingsRenderer(basicSubPageEl, basicSettings);
};
- const initDeviceSecuritySettingsPage = () => {
- const deviceSecuritySubPageEl = document.getElementById(
- "security-config-subpage"
+ const initDeviceInfoPostSettingsPage = () => {
+ const deviceInfoPostSubPageEl = document.getElementById(
+ "device-info-post-config-subpage"
);
- settingsRenderer(deviceSecuritySubPageEl, deviceSecuritySettings);
+ settingsRenderer(deviceInfoPostSubPageEl, deviceInfoPostSettings);
};
const renderSubPages = async () => {
@@ -37,15 +49,16 @@
await updateAikariRulesFromLocal();
initBasicSettingsPage();
- initDeviceSecuritySettingsPage();
+ initDeviceInfoPostSettingsPage();
};
const onMounted = () => {
const rootEl = document.getElementById("acs-behaviour-control-el");
+ preInitUIReactives();
initStatusPage();
setTimeout(() => {
rootEl.classList.remove("acs-behaviour-control-hidden");
- renderSubPages(); // 如果立即渲染子页面, 此时 plsRules 还未初始化, 会导致子页面 auraIf 失效
+ renderSubPages();
}, 500);
};
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js
index 82006ab..22db8b9 100755
--- a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js
+++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/basic.js
@@ -4,28 +4,6 @@ const {
updateAikariConfigToRemote,
} = 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 = [
{
id: 0,
@@ -33,137 +11,70 @@ const basicSettings = [
child: [
{
index: 0,
- id: "plsListenPort",
+ id: "aikarWsPreferPort",
type: "input",
subType: "number",
- name: "PLS WS 默认监听端口",
- description: "PLS 的 WebSocket 服务器将默认监听指定的端口",
+ name: "Aikari WS 默认监听端口",
+ description: "Aikari WebSocket 服务器默认监听的端口",
reactive: true,
reactiveVal: ["root.settings"],
restart: false,
reload: false,
- AikariRequired: true,
+ aikariRequired: true,
restartAikari: false,
warning: true,
- warningContent: "PLS 仍会在默认端口被占用时, 自动随机端口重试",
+ warningContent: "Aikari 仍会在默认端口被占用时, 自动随机端口重试",
associateVal: null,
auraIf: () => true,
defaultValue: "",
placeHolder: "输入端口号 (10000 ~ 65535)",
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariSettings) return "";
- return global.__HUGO_AURA__.aikariSettings.wsPort;
+ return global.__HUGO_AURA__.aikariSettings.wsPreferPort;
},
callbackFn: (newVal) => {
if (newVal === "" || !newVal)
return { valid: false, hint: "请输入端口号" };
const numberNewVal = Number(newVal);
- if (numberNewVal === NaN || !(10000 <= numberNewVal) || !(newVal <= 65535)) {
+ if (
+ numberNewVal === NaN ||
+ !(10000 <= numberNewVal) ||
+ !(newVal <= 65535)
+ ) {
return { valid: false, hint: "请输入合法的端口号 (10000 ~ 65535)" };
}
- global.__HUGO_AURA__.aikariSettings.wsPort = numberNewVal;
- updateAikariConfigToRemote("wsPort", numberNewVal);
+ global.__HUGO_AURA__.aikariSettings.wsPreferPort = numberNewVal;
+ updateAikariConfigToRemote("wsPreferPort", numberNewVal);
return { valid: true };
},
},
{
index: 1,
- 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\\", 使用 "/" 作为路径符',
- 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",
+ id: "aikariForceRegenWsTlsCert",
type: "switch",
- name: "重新生成 TLS 证书",
- description: "PLS 将在下次启动时重新生成 TLS 证书",
+ name: "重新生成 WS TLS 证书",
+ description: "Aikari 将在下次启动时重新生成用于 WebSocket 的 TLS 证书",
reactive: true,
reactiveVal: ["root.settings"],
restart: false,
reload: false,
- AikariRequired: true,
+ aikariRequired: true,
restartAikari: true,
associateVal: null,
auraIf: () => true,
defaultValue: false,
valueGetter: () => {
if (!global.__HUGO_AURA__.aikariSettings) return "";
- return global.__HUGO_AURA__.aikariSettings.regenCert;
+ return global.__HUGO_AURA__.aikariSettings.tls.regenWsCertNextLaunch;
},
callbackFn: (newVal) => {
if (typeof newVal !== "boolean") return false;
- global.__HUGO_AURA__.aikariSettings.regenCert = newVal;
- updateAikariConfigToRemote("regenCert", newVal);
+ global.__HUGO_AURA__.aikariSettings.tls.regenWsCertNextLaunch =
+ newVal;
+ updateAikariConfigToRemote("tls.regenWsCertNextLaunch", newVal);
return true;
},
},
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/deviceInfoPost.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/deviceInfoPost.js
new file mode 100644
index 0000000..f774d2c
--- /dev/null
+++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/deviceInfoPost.js
@@ -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: "选中的磁盘会
被上报为冻结 (不是实际行为)",
+ 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 };
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/deviceSecurity.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/deviceSecurity.js
deleted file mode 100755
index e4b47ce..0000000
--- a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/deviceSecurity.js
+++ /dev/null
@@ -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:
- "选择一种篡改模式, 选中的磁盘范围会
被上报为冻结 (不是实际行为)",
- 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 };
diff --git a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/previews/freezeOverridePreview/freezeOverridePreview.js b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/previews/freezeOverridePreview/freezeOverridePreview.js
index ba6e765..5647bc8 100755
--- a/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/previews/freezeOverridePreview/freezeOverridePreview.js
+++ b/src/aura/ui/pages/configSubPages/behaviourCtrl/settings/previews/freezeOverridePreview/freezeOverridePreview.js
@@ -36,8 +36,8 @@
resolve({
success: true,
data: null,
- status: response.status
- })
+ status: response.status,
+ });
}
const parsedData = await response.json();
@@ -84,7 +84,7 @@
const diskElTemplate = document.createElement("p");
diskElTemplate.classList.add("acs-bc-dsc-fop-disk-el");
- if (!curConfig.enable) {
+ if (!curConfig.enabled) {
for (const disk of curDisks) {
const curDiskEl = diskElTemplate.cloneNode();
if (disk.status !== 0) {
@@ -95,44 +95,16 @@
diskContainerEl.appendChild(curDiskEl);
}
} else {
- switch (curConfig.rewriteMode) {
- case "allFreeze":
- {
- for (const disk of curDisks) {
- const curDiskEl = diskElTemplate.cloneNode();
- // @ts-expect-error
- curDiskEl.classList.add("active");
- curDiskEl.textContent = `${disk.name.toUpperCase()} 盘`;
- diskContainerEl.appendChild(curDiskEl);
- }
- }
- 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;
+ let idx = 0;
+ for (const disk of curDisks) {
+ const curDiskEl = diskElTemplate.cloneNode();
+ if (curConfig.frozenDisks.includes(disk.name.toLowerCase())) {
+ // @ts-expect-error
+ curDiskEl.classList.add("active");
+ }
+ curDiskEl.textContent = `${disk.name.toUpperCase()} 盘`;
+ diskContainerEl.appendChild(curDiskEl);
+ idx += 1;
}
}
@@ -148,10 +120,10 @@
)[0];
const eventListener = (_event) => {
- // if (!global.__HUGO_AURA__.plsRules) return;
+ if (!global.__HUGO_AURA__.aikariRules) return;
composables.getAndUpdateDiskInfo(
- // global.__HUGO_AURA__.plsRules.client.security.uploadFreezeInfo
- { enable: false }
+ global.__HUGO_AURA__.aikariRules.ssaFeatures.securityPolicies
+ .freezeManagement.freezeDiskInfoPost
);
};
rootEl.addEventListener("onAssociateValueUpdated", eventListener);