mirror of
https://github.com/HugoAura/Seewo-HugoAura.git
synced 2026-06-21 23:54:26 +08:00
[Feat] New settings passwd UX & Config enc support
This commit is contained in:
@@ -6,6 +6,9 @@ const os = require("os");
|
||||
const crypto = require("crypto");
|
||||
const childProc = require("child_process");
|
||||
|
||||
const RegistryManagerClass = require("./registryManager");
|
||||
const registryManager = new RegistryManagerClass();
|
||||
|
||||
// Constants
|
||||
|
||||
const CRYPTO_SETTINGS_AES = {
|
||||
@@ -18,6 +21,7 @@ const CRYPTO_SETTINGS_AES = {
|
||||
obfuscateStr: "eCybsseK",
|
||||
hash: "sha256",
|
||||
};
|
||||
const LMAK_SETTINGS_BASE = "EncSettings\\LMAK";
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -70,14 +74,35 @@ class ConfigManager {
|
||||
this.encConfigPath = path.join(this.configDir, ".cache_2eafc8d0.dat"); // (雾
|
||||
/* ↑ 不使用 .tmp 扩展名, 不然容易真被清理了 */
|
||||
this.defaultConfigPath = path.join(__dirname, "default.json");
|
||||
this.useEncConfig = false;
|
||||
this.isConfigReadFailed = false;
|
||||
this.side = "unknown";
|
||||
|
||||
if (fs.existsSync(this.configPath)) {
|
||||
this.useEncConfig = false;
|
||||
} else {
|
||||
this.useEncConfig = true;
|
||||
}
|
||||
|
||||
if (global.__HUGO_AURA_EVENT_BUS__) {
|
||||
// Expect always true
|
||||
global.__HUGO_AURA_EVENT_BUS__.on(
|
||||
"$aura.config.updateConfigEncSettings",
|
||||
(/** @type {boolean} */ newVal) => {
|
||||
this.useEncConfig = newVal;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getHugoAuraConfigPath() {
|
||||
return path.dirname(this.configPath);
|
||||
return path.dirname(
|
||||
this.useEncConfig ? this.encConfigPath : this.configPath
|
||||
);
|
||||
}
|
||||
|
||||
getConfigPath() {
|
||||
return this.configPath;
|
||||
return this.useEncConfig ? this.encConfigPath : this.configPath;
|
||||
}
|
||||
|
||||
getDefaultConfig() {
|
||||
@@ -99,7 +124,7 @@ class ConfigManager {
|
||||
fs.mkdirSync(hugoAuraPath, { recursive: true });
|
||||
}
|
||||
|
||||
if (!fs.existsSync(this.configPath)) {
|
||||
if (!fs.existsSync(this.configPath) && !fs.existsSync(this.encConfigPath)) {
|
||||
console.log("[HugoAura / Config] Creating default config file");
|
||||
const defaultConfig = this.getDefaultConfig();
|
||||
this.writeConfig(defaultConfig);
|
||||
@@ -108,11 +133,30 @@ class ConfigManager {
|
||||
|
||||
readConfig() {
|
||||
try {
|
||||
const config = JSON.parse(fs.readFileSync(this.configPath, "utf8"));
|
||||
console.log("[HugoAura / Config] Successfully loaded config:", config);
|
||||
let config = {};
|
||||
if (this.useEncConfig) {
|
||||
const hashedPasswdResultObj = this.retrieveEncPassword();
|
||||
if (hashedPasswdResultObj.success && hashedPasswdResultObj.data) {
|
||||
config = this.decryptConfig(hashedPasswdResultObj.data).data;
|
||||
|
||||
if (!config) {
|
||||
this.isConfigReadFailed = true;
|
||||
return this.getDefaultConfig(); // should be changed, too
|
||||
}
|
||||
} else {
|
||||
console.error("[HugoAura / Config / ERROR] Failed to decrypt config");
|
||||
this.isConfigReadFailed = true;
|
||||
return this.getDefaultConfig(); // This behaviour should be changed later
|
||||
}
|
||||
} else {
|
||||
config = JSON.parse(fs.readFileSync(this.configPath, "utf8"));
|
||||
}
|
||||
// console.log("[HugoAura / Config] Successfully loaded config:", config);
|
||||
if (this.isConfigReadFailed) this.isConfigReadFailed = false;
|
||||
return config;
|
||||
} catch (err) {
|
||||
console.error("[HugoAura / Config] Failed to read config:", err);
|
||||
this.isConfigReadFailed = true;
|
||||
return this.getDefaultConfig();
|
||||
}
|
||||
}
|
||||
@@ -120,15 +164,32 @@ class ConfigManager {
|
||||
/**
|
||||
*
|
||||
* @param {Record<any, any>} config
|
||||
* @returns
|
||||
* @returns {boolean}
|
||||
*/
|
||||
writeConfig(config) {
|
||||
try {
|
||||
fs.writeFileSync(
|
||||
this.configPath,
|
||||
JSON.stringify(config, null, 2),
|
||||
"utf8"
|
||||
);
|
||||
if (this.useEncConfig) {
|
||||
const hashedPasswdResultObj = this.retrieveEncPassword();
|
||||
if (hashedPasswdResultObj.success && hashedPasswdResultObj.data) {
|
||||
this.encryptConfig(config, hashedPasswdResultObj.data);
|
||||
} else {
|
||||
console.error(
|
||||
"[HugoAura / Config / Write / ERROR] Failed to write config: Retrieve enc password failed"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
fs.writeFileSync(
|
||||
this.configPath,
|
||||
JSON.stringify(config, null, 2),
|
||||
"utf8"
|
||||
);
|
||||
}
|
||||
|
||||
if (this.side === "renderer") {
|
||||
global.ipcRenderer.send("$aura.config.refreshMainConfig");
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error("[HugoAura / Config] Failed to write config:", err);
|
||||
@@ -140,8 +201,8 @@ class ConfigManager {
|
||||
let defaultConfig = this.getDefaultConfig();
|
||||
let config = {};
|
||||
try {
|
||||
if (fs.existsSync(this.configPath)) {
|
||||
const userConfig = JSON.parse(fs.readFileSync(this.configPath, "utf8"));
|
||||
if (fs.existsSync(this.configPath) || fs.existsSync(this.encConfigPath)) {
|
||||
const userConfig = this.readConfig();
|
||||
if (global.__HUGO_AURA__.configInit) {
|
||||
config = userConfig;
|
||||
return userConfig;
|
||||
@@ -153,18 +214,236 @@ class ConfigManager {
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[HugoAura / Config] Failed to load user config:", err);
|
||||
this.isConfigReadFailed = true;
|
||||
config = defaultConfig;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
priv_getMacAddr() {
|
||||
const netInf = os.networkInterfaces();
|
||||
const realInfs = Object.keys(netInf).filter(
|
||||
(key) =>
|
||||
!key.includes("Pseudo") &&
|
||||
!key.includes("Loopback") &&
|
||||
!key.includes("Virtual") &&
|
||||
!key.includes("Tunnel") &&
|
||||
!key.includes("Cisco") &&
|
||||
!key.includes("VPN")
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string[]} infNames
|
||||
* @param {Record<string, any>} infObj
|
||||
* @returns
|
||||
*/
|
||||
const getValidInfMac = (infNames, infObj) => {
|
||||
for (const name of infNames) {
|
||||
const target = infObj[name][0];
|
||||
const isValid = !target.internal && target.mac !== "00:00:00:00:00:00";
|
||||
if (isValid) {
|
||||
return target.mac;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const rawInfMac = getValidInfMac(realInfs, netInf);
|
||||
const macAddr = rawInfMac
|
||||
? rawInfMac.replace(/:/g, "").toUpperCase()
|
||||
: null;
|
||||
return macAddr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {SHA256EncryptedPassword} password
|
||||
*/
|
||||
saveEncPassword(password) {
|
||||
let macAddr = this.priv_getMacAddr();
|
||||
let fallbackToStaticKey = false;
|
||||
|
||||
if (!macAddr) {
|
||||
console.warn(
|
||||
"[HugoAura / Config / LMK] No valid network inf found, fallback to static key."
|
||||
);
|
||||
macAddr = Buffer.from(crypto.randomBytes(6))
|
||||
.toString("hex")
|
||||
.toUpperCase();
|
||||
}
|
||||
|
||||
const randomSalt = crypto.randomBytes(CRYPTO_SETTINGS_AES.saltLength);
|
||||
const key = crypto.scryptSync(macAddr, randomSalt, 32);
|
||||
const iv = crypto.randomBytes(CRYPTO_SETTINGS_AES.ivLength);
|
||||
|
||||
const cipherIns = crypto.createCipheriv(CRYPTO_SETTINGS_AES.mode, key, iv, {
|
||||
// @ts-expect-error
|
||||
authTagLength: CRYPTO_SETTINGS_AES.tagLength,
|
||||
});
|
||||
|
||||
let encryptedPassword = cipherIns.update(password, "utf-8", "hex");
|
||||
encryptedPassword += cipherIns.final("hex");
|
||||
|
||||
const authTagHex = cipherIns.getAuthTag().toString("hex");
|
||||
const ivHex = iv.toString("hex");
|
||||
const saltHex = randomSalt.toString("hex");
|
||||
|
||||
registryManager.createOrUpdateRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_Value",
|
||||
encryptedPassword,
|
||||
true
|
||||
);
|
||||
registryManager.createOrUpdateRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_IV",
|
||||
ivHex,
|
||||
true
|
||||
);
|
||||
registryManager.createOrUpdateRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_Salt",
|
||||
saltHex,
|
||||
true
|
||||
);
|
||||
registryManager.createOrUpdateRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_AuthTag",
|
||||
authTagHex,
|
||||
true
|
||||
);
|
||||
|
||||
if (fallbackToStaticKey) {
|
||||
registryManager.createOrUpdateRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_FakeMac",
|
||||
macAddr,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
retrieveEncPassword() {
|
||||
try {
|
||||
const authTagHex = registryManager.readRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_AuthTag",
|
||||
true
|
||||
)?.data;
|
||||
const ivHex = registryManager.readRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_IV",
|
||||
true
|
||||
)?.data;
|
||||
const saltHex = registryManager.readRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_Salt",
|
||||
true
|
||||
)?.data;
|
||||
const encPasswdHex = registryManager.readRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_Value",
|
||||
true
|
||||
)?.data;
|
||||
let isStaticKey = false;
|
||||
let macAddr = null;
|
||||
|
||||
try {
|
||||
macAddr = registryManager.readRegKey(
|
||||
LMAK_SETTINGS_BASE,
|
||||
"LMAK_FakeMac",
|
||||
true
|
||||
)?.data;
|
||||
if (!macAddr) {
|
||||
isStaticKey = false;
|
||||
} else {
|
||||
isStaticKey = true;
|
||||
}
|
||||
} catch {
|
||||
isStaticKey = false;
|
||||
}
|
||||
|
||||
if (!isStaticKey) {
|
||||
macAddr = this.priv_getMacAddr();
|
||||
|
||||
if (!macAddr) {
|
||||
console.error(
|
||||
"[HugoAura / Config / ERROR] Failed to retrieve password from reg: MAC Address invalid."
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
error: new Error("Mac is null or undefined"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (!saltHex || !ivHex || !authTagHex || !encPasswdHex) {
|
||||
console.error(
|
||||
"[HugoAura / Config / ERROR] Failed to retrieve password from reg: Reg keys invalid."
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
error: new Error("Reg key invalid"),
|
||||
};
|
||||
}
|
||||
const salt = Buffer.from(saltHex, "hex");
|
||||
const iv = Buffer.from(ivHex, "hex");
|
||||
const authTag = Buffer.from(authTagHex, "hex");
|
||||
const encPasswd = Buffer.from(encPasswdHex, "utf-8").toString();
|
||||
|
||||
const key = crypto.scryptSync(macAddr, salt, 32);
|
||||
const decipherIns = crypto.createDecipheriv(
|
||||
CRYPTO_SETTINGS_AES.mode,
|
||||
key,
|
||||
iv,
|
||||
{
|
||||
// @ts-expect-error
|
||||
authTagLength: CRYPTO_SETTINGS_AES.tagLength,
|
||||
}
|
||||
);
|
||||
|
||||
decipherIns.setAuthTag(authTag);
|
||||
|
||||
const result = Buffer.concat([
|
||||
decipherIns.update(encPasswd, "hex"),
|
||||
decipherIns.final(),
|
||||
]).toString();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: result,
|
||||
error: null,
|
||||
};
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"[HugoAura / Config / ERROR] Unexpected error occurred while retrieving password from reg, error:",
|
||||
e
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
error: e,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
clearEncPasswdRegKey() {
|
||||
registryManager.delRegKey(LMAK_SETTINGS_BASE, null);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Record<any, any>} configData
|
||||
* @param {string} passwd
|
||||
* @param {SHA256EncryptedPassword} passwd
|
||||
*/
|
||||
encryptConfig(configData, passwd) {
|
||||
registryManager.initRegistry();
|
||||
const salt = crypto.randomBytes(CRYPTO_SETTINGS_AES.saltLength);
|
||||
const key = crypto.pbkdf2Sync(
|
||||
passwd,
|
||||
@@ -198,15 +477,13 @@ class ConfigManager {
|
||||
|
||||
try {
|
||||
fs.writeFileSync(this.encConfigPath, base64EncConfig, "utf-8");
|
||||
// fs.rmSync(this.configPath);
|
||||
try {
|
||||
fs.unlinkSync(this.configPath);
|
||||
} catch {
|
||||
console.debug("[HugoAura / Config] Dec config not exists, skipping...");
|
||||
}
|
||||
|
||||
const _hideFileProc = childProc.spawnSync(
|
||||
"cmd.exe",
|
||||
["/c", "attrib", "+h", this.encConfigPath],
|
||||
{
|
||||
stdio: "inherit",
|
||||
}
|
||||
);
|
||||
if (!this.useEncConfig) this.useEncConfig = true;
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error(
|
||||
@@ -223,95 +500,169 @@ class ConfigManager {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} passwd
|
||||
* @returns
|
||||
* @param {SHA256EncryptedPassword} passwd
|
||||
* @returns {{success: boolean, data: AuraConfig}}
|
||||
*/
|
||||
decryptConfig(passwd) {
|
||||
const FAILED_RET = {
|
||||
success: false,
|
||||
data: {},
|
||||
};
|
||||
|
||||
let base64EncConfig = null;
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(this.encConfigPath)) {
|
||||
return FAILED_RET;
|
||||
}
|
||||
base64EncConfig = fs.readFileSync(this.encConfigPath, "utf-8");
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Failed to read encrypted config:",
|
||||
err
|
||||
);
|
||||
return FAILED_RET;
|
||||
}
|
||||
const FAILED_RET = {
|
||||
success: false,
|
||||
data: {},
|
||||
};
|
||||
|
||||
let base64EncConfig = null;
|
||||
|
||||
if (base64EncConfig) {
|
||||
const strip64EncCfg = base64EncConfig.split(
|
||||
CRYPTO_SETTINGS_AES.obfuscateStr
|
||||
)[1];
|
||||
const encryptCfg = Buffer.from(strip64EncCfg, "base64").toString("utf-8");
|
||||
/** @type {null | EncryptedConfig} */
|
||||
let parsedEncCfg = null;
|
||||
try {
|
||||
parsedEncCfg = JSON.parse(encryptCfg);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Failed to parse encrypted config:",
|
||||
err
|
||||
);
|
||||
console.error("[HugoAura / Config] Pending data:", encryptCfg);
|
||||
}
|
||||
if (parsedEncCfg === null) return FAILED_RET;
|
||||
|
||||
const salt = Buffer.from(parsedEncCfg.salt, "base64");
|
||||
const iv = Buffer.from(parsedEncCfg.iv, "base64");
|
||||
|
||||
const authTag = Buffer.from(parsedEncCfg.authTag, "base64");
|
||||
|
||||
const key = crypto.pbkdf2Sync(
|
||||
passwd,
|
||||
salt,
|
||||
CRYPTO_SETTINGS_AES.keyIter,
|
||||
CRYPTO_SETTINGS_AES.keyLength,
|
||||
CRYPTO_SETTINGS_AES.hash
|
||||
);
|
||||
|
||||
const decipherIns = crypto.createDecipheriv(
|
||||
CRYPTO_SETTINGS_AES.mode,
|
||||
key,
|
||||
iv,
|
||||
{
|
||||
// @ts-expect-error
|
||||
authTagLength: CRYPTO_SETTINGS_AES.tagLength,
|
||||
if (!fs.existsSync(this.encConfigPath)) {
|
||||
return FAILED_RET;
|
||||
}
|
||||
);
|
||||
|
||||
decipherIns.setAuthTag(authTag);
|
||||
|
||||
let stringifyDecCfg = Buffer.concat([
|
||||
decipherIns.update(parsedEncCfg.content, "hex"),
|
||||
decipherIns.final(),
|
||||
]).toString();
|
||||
|
||||
/** @type {null | Record<any, any>} */
|
||||
let decConfig = null;
|
||||
try {
|
||||
decConfig = JSON.parse(stringifyDecCfg);
|
||||
base64EncConfig = fs.readFileSync(this.encConfigPath, "utf-8");
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Failed to parse decrypted config:",
|
||||
"[HugoAura / Config] Failed to read encrypted config:",
|
||||
err
|
||||
);
|
||||
console.error("[HugoAura / Config] Pending data:", decConfig);
|
||||
return FAILED_RET;
|
||||
}
|
||||
if (decConfig === null) return FAILED_RET;
|
||||
|
||||
console.debug(decConfig);
|
||||
if (base64EncConfig) {
|
||||
const strip64EncCfg = base64EncConfig.split(
|
||||
CRYPTO_SETTINGS_AES.obfuscateStr
|
||||
)[1];
|
||||
const encryptCfg = Buffer.from(strip64EncCfg, "base64").toString(
|
||||
"utf-8"
|
||||
);
|
||||
/** @type {null | EncryptedConfig} */
|
||||
let parsedEncCfg = null;
|
||||
try {
|
||||
parsedEncCfg = JSON.parse(encryptCfg);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Failed to parse encrypted config:",
|
||||
err
|
||||
);
|
||||
console.error("[HugoAura / Config] Pending data:", encryptCfg);
|
||||
}
|
||||
if (parsedEncCfg === null) return FAILED_RET;
|
||||
|
||||
const salt = Buffer.from(parsedEncCfg.salt, "base64");
|
||||
const iv = Buffer.from(parsedEncCfg.iv, "base64");
|
||||
|
||||
const authTag = Buffer.from(parsedEncCfg.authTag, "base64");
|
||||
|
||||
const key = crypto.pbkdf2Sync(
|
||||
passwd,
|
||||
salt,
|
||||
CRYPTO_SETTINGS_AES.keyIter,
|
||||
CRYPTO_SETTINGS_AES.keyLength,
|
||||
CRYPTO_SETTINGS_AES.hash
|
||||
);
|
||||
|
||||
const decipherIns = crypto.createDecipheriv(
|
||||
CRYPTO_SETTINGS_AES.mode,
|
||||
key,
|
||||
iv,
|
||||
{
|
||||
// @ts-expect-error
|
||||
authTagLength: CRYPTO_SETTINGS_AES.tagLength,
|
||||
}
|
||||
);
|
||||
|
||||
decipherIns.setAuthTag(authTag);
|
||||
|
||||
const stringifyDecCfg = Buffer.concat([
|
||||
decipherIns.update(parsedEncCfg.content, "hex"),
|
||||
decipherIns.final(),
|
||||
]).toString();
|
||||
|
||||
/** @type {null | Record<any, any>} */
|
||||
let decConfig = null;
|
||||
try {
|
||||
decConfig = JSON.parse(stringifyDecCfg);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Failed to parse decrypted config:",
|
||||
err
|
||||
);
|
||||
console.error("[HugoAura / Config] Pending data:", decConfig);
|
||||
return FAILED_RET;
|
||||
}
|
||||
if (decConfig === null) return FAILED_RET;
|
||||
|
||||
// console.debug(decConfig);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: decConfig,
|
||||
};
|
||||
} else {
|
||||
console.error(
|
||||
"[HugoAura / Config] Unexpected error occurred while decrypting config: base64EncConfig is undefined"
|
||||
);
|
||||
return FAILED_RET;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Unexpected error occurred while decrypting config:",
|
||||
e
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
data: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Record<any, any> | null} curConfig
|
||||
* @param {SHA256EncryptedPassword | undefined | null} passwd
|
||||
* @returns {{success: boolean}}
|
||||
*/
|
||||
switchToDecConfig(curConfig, passwd = null) {
|
||||
let decConfig = null;
|
||||
if (!curConfig && passwd) {
|
||||
const getDecConfigResult = this.decryptConfig(passwd);
|
||||
if (
|
||||
!getDecConfigResult?.success ||
|
||||
!getDecConfigResult.data ||
|
||||
Object.keys(getDecConfigResult.data).length === 0
|
||||
) {
|
||||
console.error(
|
||||
"[HugoAura / Config] Failed to switch to decrypted config: Error decrypting config"
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
};
|
||||
}
|
||||
decConfig = getDecConfigResult.data;
|
||||
}
|
||||
|
||||
this.useEncConfig = false;
|
||||
this.clearEncPasswdRegKey();
|
||||
// @ts-expect-error
|
||||
this.writeConfig(curConfig ? curConfig : decConfig);
|
||||
try {
|
||||
fs.unlinkSync(this.encConfigPath);
|
||||
} catch {
|
||||
console.debug("[HugoAura / Config] Enc config not exists, skipping...");
|
||||
}
|
||||
global.__HUGO_AURA_EVENT_BUS__.emit(
|
||||
"$aura.config.updateConfigEncSettings",
|
||||
false
|
||||
);
|
||||
if (this.side === "renderer") {
|
||||
global.ipcRenderer.invoke("$aura.config.setConfigEncSettings", {
|
||||
target: false,
|
||||
});
|
||||
global.ipcRenderer.invoke("$aura.config.dispatchConfigFromRenderer", {
|
||||
data: JSON.stringify(curConfig),
|
||||
});
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new ConfigManager();
|
||||
module.exports = ConfigManager;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"passwordWithSalt": "89f6c4d57d0202a05c32d37cc6a2c6a0",
|
||||
"salt": "aura"
|
||||
},
|
||||
"authModeRewrite": "none"
|
||||
"authModeRewrite": "default"
|
||||
},
|
||||
"vendor/screenLock": {
|
||||
"enabled": true,
|
||||
@@ -30,9 +30,8 @@
|
||||
"auraSettings": {
|
||||
"settingsPasswordEnabled": false,
|
||||
"settingsPasswordWithSalt": "32703D292460CC9A3B867494D6AD9A8E4A3ADF0FAA4D6867BC4D412CC3927D02E47C6D0B1763BB53E57B2241C6193433561CDA09D7C48CA03983072B876F0965",
|
||||
"appearance": {
|
||||
"enablePasswdDialogBlur": true
|
||||
}
|
||||
"encryptConfig": false,
|
||||
"appearance": {}
|
||||
},
|
||||
"devTools": false
|
||||
}
|
||||
|
||||
224
src/aura/init/shared/registryManager.js
Executable file
224
src/aura/init/shared/registryManager.js
Executable file
@@ -0,0 +1,224 @@
|
||||
// @ts-check
|
||||
|
||||
const childProc = require("child_process");
|
||||
|
||||
// Constants
|
||||
|
||||
const LOG_PREFIX = "[HugoAura / Init / Reg";
|
||||
const LOG_PREFIX_FUNC = "[HugoAura / Reg";
|
||||
const AURA_REGISTRY_PATH = ["HKCU", "SOFTWARE", "HugoAura"].join("\\");
|
||||
|
||||
class RegistryManager {
|
||||
/**
|
||||
* @param {string} [path]
|
||||
*/
|
||||
handleCreateReg(path) {
|
||||
try {
|
||||
const createResult = childProc.execSync(["reg", "add", path].join(" "), {
|
||||
encoding: "utf8",
|
||||
});
|
||||
|
||||
if (createResult) {
|
||||
console.log(
|
||||
`${LOG_PREFIX} / SUCCESS] Registry path ${path} successfully created.`
|
||||
);
|
||||
console.debug(
|
||||
`${LOG_PREFIX} / DEBUG] Reg add command stdout:`,
|
||||
createResult
|
||||
);
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`${LOG_PREFIX} / ERROR] Failed creating registry path, error:`,
|
||||
e
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
initRegistry() {
|
||||
try {
|
||||
const queryResult = childProc.execSync(
|
||||
["reg", "query", AURA_REGISTRY_PATH].join(" "),
|
||||
{ encoding: "utf8" }
|
||||
);
|
||||
|
||||
if (queryResult) {
|
||||
console.log(`${LOG_PREFIX}] Registry check up success.`);
|
||||
console.debug(`${LOG_PREFIX}] Command stdout:`, queryResult);
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(`${LOG_PREFIX} / WARN] Failed to query registry, error:`, e);
|
||||
return this.handleCreateReg(AURA_REGISTRY_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} relativePath
|
||||
* @param {string} keyName
|
||||
* @param {string} keyVal
|
||||
* @param {boolean | undefined} silent
|
||||
*/
|
||||
createOrUpdateRegKey(relativePath, keyName, keyVal, silent = false) {
|
||||
try {
|
||||
const result = childProc.execSync(
|
||||
[
|
||||
"reg",
|
||||
"add",
|
||||
[AURA_REGISTRY_PATH, relativePath].join("\\"),
|
||||
"/v",
|
||||
keyName,
|
||||
"/t",
|
||||
"REG_SZ",
|
||||
"/d",
|
||||
`\"${keyVal}\"`,
|
||||
"/f",
|
||||
].join(" "),
|
||||
{ encoding: "utf8" }
|
||||
);
|
||||
|
||||
if (result) {
|
||||
if (!silent) {
|
||||
console.debug(
|
||||
`${LOG_PREFIX_FUNC} / SUCCESS] Successfully created / updated reg key ${relativePath}/${keyName} with data: ${keyVal}`
|
||||
);
|
||||
console.debug(
|
||||
`${LOG_PREFIX_FUNC} / SUCCESS] Add key command stdout:`,
|
||||
result
|
||||
);
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`${LOG_PREFIX_FUNC} / ERROR] Failed to create / update reg key, error:`,
|
||||
silent ? "<Hidden>" : e
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error: e,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*>>> BUC <<<
|
||||
keyName === null --> delete the whole entry
|
||||
>>> EUC <<<*/
|
||||
/**
|
||||
*
|
||||
* @param {string} relativePath
|
||||
* @param {string | null} keyName
|
||||
* @param {boolean | undefined} silent
|
||||
*/
|
||||
delRegKey(relativePath, keyName, silent = false) {
|
||||
if (keyName === undefined) {
|
||||
throw new Error(
|
||||
`${LOG_PREFIX_FUNC} / CRITICAL] Arg \"keyName\" for function \"delRegKey\" cannot be undefined. Only null or string accepted.`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const result = childProc.execSync(
|
||||
[
|
||||
"reg",
|
||||
"delete",
|
||||
[AURA_REGISTRY_PATH, relativePath].join("\\"),
|
||||
keyName ? "/v" : "",
|
||||
keyName ? keyName : "",
|
||||
"/f",
|
||||
].join(" "),
|
||||
{ encoding: "utf8" }
|
||||
);
|
||||
|
||||
if (result) {
|
||||
if (!silent) {
|
||||
console.debug(
|
||||
`${LOG_PREFIX_FUNC} / SUCCESS] Successfully deleted reg key ${relativePath}/${keyName}`
|
||||
);
|
||||
console.debug(
|
||||
`${LOG_PREFIX_FUNC} / SUCCESS] Delete key command stdout:`,
|
||||
result
|
||||
);
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`${LOG_PREFIX_FUNC} / ERROR] Failed to delete reg key, error:`,
|
||||
silent ? "<Hidden>" : e
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
error: e,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} relativePath
|
||||
* @param {string} keyName
|
||||
* @param {boolean | undefined} silent
|
||||
*/
|
||||
readRegKey(relativePath, keyName, silent = false) {
|
||||
try {
|
||||
const readResult = childProc.execSync(
|
||||
[
|
||||
"reg",
|
||||
"query",
|
||||
[AURA_REGISTRY_PATH, relativePath].join("\\"),
|
||||
"/v",
|
||||
`\"${keyName}\"`,
|
||||
].join(" "),
|
||||
{ encoding: "utf8" }
|
||||
);
|
||||
|
||||
if (readResult) {
|
||||
if (!silent) {
|
||||
console.debug(
|
||||
`${LOG_PREFIX}] Successfully read reg key ${relativePath}/${keyName}, stdout:`,
|
||||
readResult
|
||||
);
|
||||
}
|
||||
const match = readResult.match(/REG_SZ\s+(.+)/);
|
||||
|
||||
if (!match) {
|
||||
console.warn(`${LOG_PREFIX_FUNC} / WARN] Data not found in stdout`);
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
error: new Error("Data not found"),
|
||||
};
|
||||
}
|
||||
|
||||
const data = match[1].trim();
|
||||
return {
|
||||
success: true,
|
||||
data,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`${LOG_PREFIX_FUNC} / ERROR] Failed to read reg key, error:`,
|
||||
silent ? "<Hidden>" : e
|
||||
);
|
||||
return {
|
||||
success: false,
|
||||
data: null,
|
||||
error: e,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RegistryManager;
|
||||
Reference in New Issue
Block a user