fix: complete source from ZIP + add hvigor configs + local debug signing
@ -4,7 +4,7 @@
|
||||
"projectType": "hvigor",
|
||||
"uri": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap"
|
||||
},
|
||||
"buildTask": "",
|
||||
"extendConfigs": {
|
||||
@ -13,12 +13,12 @@
|
||||
},
|
||||
"subProjects": [
|
||||
{
|
||||
"name": "electron",
|
||||
"name": "web_engine",
|
||||
"description": "",
|
||||
"projectType": "hvigor",
|
||||
"uri": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/electron"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/web_engine"
|
||||
},
|
||||
"buildTask": "",
|
||||
"extendConfigs": {
|
||||
@ -38,12 +38,12 @@
|
||||
"dependencyProjects": []
|
||||
},
|
||||
{
|
||||
"name": "web_engine",
|
||||
"name": "electron",
|
||||
"description": "",
|
||||
"projectType": "hvigor",
|
||||
"uri": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/web_engine"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/electron"
|
||||
},
|
||||
"buildTask": "",
|
||||
"extendConfigs": {
|
||||
@ -69,25 +69,25 @@
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/electron/src/main/ets"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/web_engine/src/main/ets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/electron/src/ohosTest/ets"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/web_engine/src/ohosTest/ets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/web_engine/src/main/ets"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/electron/src/main/ets"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/web_engine/src/ohosTest/ets"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/electron/src/ohosTest/ets"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -98,55 +98,55 @@
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/oh_modules"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/oh_modules"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/.hvigor"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/.hvigor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/build"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/electron/.test"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/web_engine/.test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/electron/oh_modules"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/web_engine/oh_modules"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/electron/build"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/web_engine/build"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/web_engine/.test"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/electron/.test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/web_engine/oh_modules"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/electron/oh_modules"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": {
|
||||
"$type": 1,
|
||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap/web_engine/build"
|
||||
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap/electron/build"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
0
AppScope/resources/base/media/app_icon.png
Executable file → Normal file
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
0
AppScope/resources/base/media/icon.png
Executable file → Normal file
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
AppScope/resources/base/media/product_logo_32.png
Executable file → Normal file
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
0
AppScope/resources/base/media/startIcon.png
Executable file → Normal file
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
@ -22,21 +22,7 @@
|
||||
"name": "release"
|
||||
}
|
||||
],
|
||||
"signingConfigs": [
|
||||
{
|
||||
"name": "default",
|
||||
"material": {
|
||||
"storePassword": "00000020B042E2E9E6BBBB331A5D9B84B52B19468492B675BB26884B09AEB4EE1560934B2270ADBA486243A0BE443394",
|
||||
"certpath": "/storage/Users/currentUser/appdata/el2/base/com.huawei.devecostudio/files/ohos/config/default_ohos_electron_hap4PU0PdQzlYYcUxXSOoQfdhrl0YhWODdaXilxiORE6vk.cer",
|
||||
"keyAlias": "debugKey",
|
||||
"keyPassword": "00000020B042E2E9E6BBBB331A5D9B84B52B19468492B675BB26884B09AEB4EE1560934B2270ADBA486243A0BE443394",
|
||||
"profile": "/storage/Users/currentUser/appdata/el2/base/com.huawei.devecostudio/files/ohos/config/default_ohos_electron_hap4PU0PdQzlYYcUxXSOoQfdhrl0YhWODdaXilxiORE6vk.p7b",
|
||||
"signAlg": "SHA256withECDSA",
|
||||
"storeFile": "/storage/Users/currentUser/appdata/el2/base/com.huawei.devecostudio/files/ohos/config/default_ohos_electron_hap4PU0PdQzlYYcUxXSOoQfdhrl0YhWODdaXilxiORE6vk.p12"
|
||||
},
|
||||
"type": "HarmonyOS"
|
||||
}
|
||||
]
|
||||
"signingConfigs": []
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
@ -56,4 +42,4 @@
|
||||
"srcPath": "./web_engine"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
0
chromium/build-profile.json5
Executable file → Normal file
0
chromium/hvigorfile.ts
Executable file → Normal file
0
chromium/obfuscation-rules.txt
Executable file → Normal file
0
chromium/oh-package.json5
Executable file → Normal file
0
chromium/src/main/ets/Application/AbilityStage.ets
Executable file → Normal file
0
chromium/src/main/ets/entryability/BrowserAbility.ets
Executable file → Normal file
0
chromium/src/main/ets/entryability/EntryAbility.ets
Executable file → Normal file
0
chromium/src/main/ets/extensionAbility/BrowserEmbeddedAbility.ets
Executable file → Normal file
0
chromium/src/main/ets/pages/EmbeddedWindow.ets
Executable file → Normal file
0
chromium/src/main/ets/pages/Index.ets
Executable file → Normal file
0
chromium/src/main/ets/pages/SubWindow.ets
Executable file → Normal file
0
chromium/src/main/ets/pages/WindowNode.ets
Executable file → Normal file
0
chromium/src/main/ets/process/CustomChildProcess.ets
Executable file → Normal file
0
chromium/src/main/module.json5
Executable file → Normal file
0
chromium/src/main/resources/base/element/color.json
Executable file → Normal file
0
chromium/src/main/resources/base/element/string.json
Executable file → Normal file
0
chromium/src/main/resources/base/profile/main_pages.json
Executable file → Normal file
0
chromium/src/main/resources/en_US/element/string.json
Executable file → Normal file
0
chromium/src/main/resources/zh_CN/element/string.json
Executable file → Normal file
0
chromium/src/ohosTest/ets/test/Ability.test.ets
Executable file → Normal file
0
chromium/src/ohosTest/ets/test/List.test.ets
Executable file → Normal file
0
chromium/src/ohosTest/ets/testability/TestAbility.ets
Executable file → Normal file
0
chromium/src/ohosTest/ets/testability/pages/Index.ets
Executable file → Normal file
0
chromium/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets
Executable file → Normal file
0
chromium/src/ohosTest/module.json5
Executable file → Normal file
0
chromium/src/ohosTest/resources/base/element/color.json
Executable file → Normal file
0
chromium/src/ohosTest/resources/base/element/string.json
Executable file → Normal file
0
chromium/src/ohosTest/resources/base/profile/test_pages.json
Executable file → Normal file
0
chromium/src/test/List.test.ets
Executable file → Normal file
0
chromium/src/test/LocalUnit.test.ets
Executable file → Normal file
0
electron/build-profile.json5
Executable file → Normal file
7
electron/hvigor/hvigor-config.json5
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"modelVersion": "5.0.0",
|
||||
"dependencies": {
|
||||
},
|
||||
"execution": {
|
||||
}
|
||||
}
|
||||
0
electron/hvigorfile.ts
Executable file → Normal file
0
electron/libs/arm64-v8a/libadapter.so
Executable file → Normal file
0
electron/libs/arm64-v8a/libffmpeg.so
Executable file → Normal file
0
electron/obfuscation-rules.txt
Executable file → Normal file
0
electron/oh-package.json5
Executable file → Normal file
0
electron/src/main/ets/Application/AbilityStage.ets
Executable file → Normal file
0
electron/src/main/ets/entryability/BrowserAbility.ets
Executable file → Normal file
0
electron/src/main/ets/entryability/EntryAbility.ets
Executable file → Normal file
0
electron/src/main/ets/entryability/StatusBarEntryAbility.ets
Executable file → Normal file
0
electron/src/main/ets/extensionAbility/BrowserEmbeddedAbility.ets
Executable file → Normal file
0
electron/src/main/ets/pages/EmbeddedWindow.ets
Executable file → Normal file
0
electron/src/main/ets/pages/Index.ets
Executable file → Normal file
0
electron/src/main/ets/pages/StatusBarPage.ets
Executable file → Normal file
0
electron/src/main/ets/pages/SubWindow.ets
Executable file → Normal file
0
electron/src/main/ets/pages/WindowNode.ets
Executable file → Normal file
0
electron/src/main/ets/process/CustomChildProcess.ets
Executable file → Normal file
0
electron/src/main/module.json5
Executable file → Normal file
0
electron/src/main/resources/base/element/color.json
Executable file → Normal file
0
electron/src/main/resources/base/element/string.json
Executable file → Normal file
0
electron/src/main/resources/base/profile/main_pages.json
Executable file → Normal file
0
electron/src/ohosTest/ets/test/Ability.test.ets
Executable file → Normal file
0
electron/src/ohosTest/ets/test/List.test.ets
Executable file → Normal file
0
electron/src/ohosTest/ets/testability/TestAbility.ets
Executable file → Normal file
0
electron/src/ohosTest/ets/testability/pages/Index.ets
Executable file → Normal file
0
electron/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ets
Executable file → Normal file
0
electron/src/ohosTest/module.json5
Executable file → Normal file
0
electron/src/ohosTest/resources/base/element/color.json
Executable file → Normal file
0
electron/src/ohosTest/resources/base/element/string.json
Executable file → Normal file
0
electron/src/ohosTest/resources/base/profile/test_pages.json
Executable file → Normal file
0
electron/src/test/List.test.ets
Executable file → Normal file
0
electron/src/test/LocalUnit.test.ets
Executable file → Normal file
0
hvigor/hvigor-config.json5
Executable file → Normal file
@ -2,8 +2,8 @@
|
||||
* Use these variables when you tailor your ArkTS code. They must be of the const type.
|
||||
*/
|
||||
export const HAR_VERSION = '1.0.0';
|
||||
export const BUILD_MODE_NAME = 'debug';
|
||||
export const DEBUG = true;
|
||||
export const BUILD_MODE_NAME = 'release';
|
||||
export const DEBUG = false;
|
||||
export const TARGET_NAME = 'default';
|
||||
|
||||
/**
|
||||
|
||||
0
web_engine/childProcess.ets
Executable file → Normal file
7
web_engine/hvigor/hvigor-config.json5
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"modelVersion": "5.0.0",
|
||||
"dependencies": {
|
||||
},
|
||||
"execution": {
|
||||
}
|
||||
}
|
||||
0
web_engine/src/main/ets/adapter/DialogAdapter.ets
Executable file → Normal file
0
web_engine/src/main/ets/adapter/ElectronAppAdapter.ets
Executable file → Normal file
0
web_engine/src/main/ets/adapter/StatusBarManager.ets
Executable file → Normal file
0
web_engine/src/main/ets/common/WindowStyle.ets
Executable file → Normal file
0
web_engine/src/main/ets/components/MessageBox.ets
Executable file → Normal file
0
web_engine/src/main/ets/jsbindings/DialogAdapterBind.ets
Executable file → Normal file
0
web_engine/src/main/ets/jsbindings/ElectronAppAdapterBind.ets
Executable file → Normal file
0
web_engine/src/main/ets/jsbindings/StatusBarManagerAdapterBind.ets
Executable file → Normal file
0
web_engine/src/main/resources/resfile/electron
Executable file → Normal file
@ -81,6 +81,15 @@ async function listWindowsHiddenBasenames(dirPath) {
|
||||
}
|
||||
}
|
||||
|
||||
let _homeDirOverride = null;
|
||||
|
||||
/**
|
||||
* Set a custom home directory (e.g., for HarmonyOS sandbox workaround)
|
||||
*/
|
||||
function init(deps) {
|
||||
if (deps?.homeDir) _homeDirOverride = deps.homeDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* List files in a local directory
|
||||
* Properly handles symlinks by resolving their target type
|
||||
@ -299,7 +308,7 @@ async function listLocalTree(event, payload) {
|
||||
* Get the home directory
|
||||
*/
|
||||
async function getHomeDir() {
|
||||
return os.homedir();
|
||||
return _homeDirOverride || os.homedir();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,7 +325,7 @@ async function getSystemInfo() {
|
||||
* Read system known_hosts file
|
||||
*/
|
||||
async function readKnownHosts() {
|
||||
const homeDir = os.homedir();
|
||||
const homeDir = _homeDirOverride || os.homedir();
|
||||
const knownHostsPaths = [];
|
||||
|
||||
if (process.platform === "win32") {
|
||||
@ -366,6 +375,7 @@ function registerHandlers(ipcMain) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init,
|
||||
registerHandlers,
|
||||
listLocalDir,
|
||||
readLocalFile,
|
||||
|
||||
0
web_engine/src/main/resources/resfile/resources/app/electron/cli/netcatty-tool-cli
Executable file → Normal file
@ -16,12 +16,306 @@
|
||||
// HarmonyOS: the full main.cjs startup (80+ bridge requires, GPU switches,
|
||||
// protocol registration, etc.) causes SIGSEGV in V8. Use minimal init.
|
||||
if (process.platform === 'ohos' || process.platform === 'openharmony') {
|
||||
const { app, BrowserWindow } = require("electron");
|
||||
|
||||
const { app, BrowserWindow, protocol, dialog } = require("electron");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
// HarmonyOS sandbox blocks os.homedir(). Use saved or picked path.
|
||||
(() => {
|
||||
const saveFile = path.join(app.getPath("userData"), "local_home.txt");
|
||||
try {
|
||||
const saved = fs.readFileSync(saveFile, "utf8").trim();
|
||||
if (saved && fs.existsSync(saved)) {
|
||||
process.env.HOME = saved;
|
||||
console.log("OHOS: loaded saved HOME:", saved);
|
||||
return;
|
||||
}
|
||||
} catch {}
|
||||
// First run — use desktop path (may or may not work)
|
||||
process.env.HOME = app.getPath("desktop");
|
||||
console.log("OHOS: default HOME:", process.env.HOME);
|
||||
})();
|
||||
|
||||
// Register ncapp:// protocol with CORS headers (needed for SPA routing)
|
||||
const APP_HEADERS = {
|
||||
"Cross-Origin-Opener-Policy": "same-origin",
|
||||
"Cross-Origin-Embedder-Policy": "credentialless",
|
||||
};
|
||||
const MIME = {
|
||||
".html": "text/html", ".js": "text/javascript", ".mjs": "text/javascript",
|
||||
".css": "text/css", ".json": "application/json", ".png": "image/png",
|
||||
".svg": "image/svg+xml", ".ico": "image/x-icon", ".woff2": "font/woff2",
|
||||
".wasm": "application/wasm",
|
||||
};
|
||||
const distPath = path.join(__dirname, "..", "dist");
|
||||
|
||||
try {
|
||||
protocol.handle("ncapp", async (req) => {
|
||||
const u = new URL(req.url);
|
||||
let p = u.pathname.replace(/^\/+/, "") || "index.html";
|
||||
const full = path.join(distPath, p);
|
||||
if (!full.startsWith(distPath)) return new Response("Forbidden", { status: 403 });
|
||||
try {
|
||||
const data = await fs.promises.readFile(full);
|
||||
const ext = path.extname(full).toLowerCase();
|
||||
return new Response(data, {
|
||||
status: 200,
|
||||
headers: { ...APP_HEADERS, "Content-Type": MIME[ext] || "application/octet-stream" },
|
||||
});
|
||||
} catch { return new Response("Not Found", { status: 404 }); }
|
||||
});
|
||||
} catch(e) { console.log("protocol.handle failed:", e.message); }
|
||||
|
||||
// === Bridge loading (same order as working version) ===
|
||||
|
||||
// Step 1: terminalBridge
|
||||
console.log("OHOS: loading terminalBridge...");
|
||||
try { require("./bridges/terminalBridge.cjs"); } catch(e) { console.log("terminalBridge FAILED:", e.message); }
|
||||
console.log("OHOS: terminalBridge OK");
|
||||
|
||||
// Step 2: sshBridge
|
||||
console.log("OHOS: loading sshBridge...");
|
||||
try { require("./bridges/sshBridge.cjs"); } catch(e) { console.log("sshBridge FAILED:", e.message); }
|
||||
console.log("OHOS: sshBridge OK");
|
||||
|
||||
// Step 3: sftpBridge
|
||||
console.log("OHOS: loading sftpBridge...");
|
||||
try { require("./bridges/sftpBridge.cjs"); } catch(e) { console.log("sftpBridge FAILED:", e.message); }
|
||||
console.log("OHOS: sftpBridge OK");
|
||||
|
||||
// Step 4: localFsBridge
|
||||
console.log("OHOS: loading localFsBridge...");
|
||||
try { require("./bridges/localFsBridge.cjs"); } catch(e) { console.log("localFsBridge FAILED:", e.message); }
|
||||
console.log("OHOS: localFsBridge OK");
|
||||
|
||||
// Step 5: transferBridge
|
||||
console.log("OHOS: loading transferBridge...");
|
||||
try { require("./bridges/transferBridge.cjs"); } catch(e) { console.log("transferBridge FAILED:", e.message); }
|
||||
console.log("OHOS: transferBridge OK");
|
||||
|
||||
// Step 6: portForwardingBridge
|
||||
console.log("OHOS: loading portForwardingBridge...");
|
||||
try { require("./bridges/portForwardingBridge.cjs"); } catch(e) { console.log("portForwardingBridge FAILED:", e.message); }
|
||||
console.log("OHOS: portForwardingBridge OK");
|
||||
|
||||
// Step 7: sessionLogStreamManager
|
||||
console.log("OHOS: loading sessionLogStreamManager...");
|
||||
try { require("./bridges/sessionLogStreamManager.cjs"); } catch(e) { console.log("sessionLogStreamManager FAILED:", e.message); }
|
||||
console.log("OHOS: sessionLogStreamManager OK");
|
||||
|
||||
// Step 8: crashLogBridge
|
||||
console.log("OHOS: loading crashLogBridge...");
|
||||
try { require("./bridges/crashLogBridge.cjs"); } catch(e) { console.log("crashLogBridge FAILED:", e.message); }
|
||||
console.log("OHOS: crashLogBridge OK");
|
||||
|
||||
// Step 9: ptyProcessTree
|
||||
console.log("OHOS: loading ptyProcessTree...");
|
||||
try { require("./bridges/ptyProcessTree.cjs"); } catch(e) { console.log("ptyProcessTree FAILED:", e.message); }
|
||||
console.log("OHOS: ptyProcessTree OK");
|
||||
|
||||
// Step 10-24: remaining lazy bridges
|
||||
const lazyBridges = [
|
||||
"oauthBridge", "githubAuthBridge", "googleAuthBridge", "onedriveAuthBridge",
|
||||
"cloudSyncBridge", "fileWatcherBridge", "tempDirBridge", "sessionLogsBridge",
|
||||
"compressUploadBridge", "globalShortcutBridge", "credentialBridge",
|
||||
"autoUpdateBridge", "aiBridge", "windowManager", "vaultBackupBridge",
|
||||
];
|
||||
for (const name of lazyBridges) {
|
||||
console.log("OHOS: loading " + name + "...");
|
||||
try { require("./bridges/" + name + ".cjs"); } catch(e) { console.log(name + " FAILED:", e.message); }
|
||||
console.log("OHOS: " + name + " OK");
|
||||
}
|
||||
|
||||
// === Bridge init + registerHandlers ===
|
||||
|
||||
const { ipcMain } = require("electron");
|
||||
const { getCliDiscoveryFilePath } = require("./cli/discoveryPath.cjs");
|
||||
const sessions = new Map();
|
||||
const sftpClients = new Map();
|
||||
const deps = {
|
||||
sessions, sftpClients,
|
||||
electronModule: require("electron"),
|
||||
cliDiscoveryFilePath: getCliDiscoveryFilePath({ userDataDir: app.getPath("userData") }),
|
||||
};
|
||||
|
||||
// sshBridge
|
||||
const sshBridge = require("./bridges/sshBridge.cjs");
|
||||
console.log("OHOS: sshBridge.init...");
|
||||
try {
|
||||
sshBridge.init(deps);
|
||||
console.log("OHOS: sshBridge.init OK");
|
||||
sshBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: sshBridge.registerHandlers OK");
|
||||
} catch(e) { console.log("sshBridge init/register FAILED:", e.message); }
|
||||
|
||||
// sftpBridge
|
||||
const sftpBridge = require("./bridges/sftpBridge.cjs");
|
||||
console.log("OHOS: sftpBridge.init...");
|
||||
try {
|
||||
sftpBridge.init(deps);
|
||||
console.log("OHOS: sftpBridge.init OK");
|
||||
sftpBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: sftpBridge.registerHandlers OK");
|
||||
} catch(e) { console.log("sftpBridge init/register FAILED:", e.message); }
|
||||
|
||||
// terminalBridge
|
||||
const terminalBridge = require("./bridges/terminalBridge.cjs");
|
||||
console.log("OHOS: terminalBridge.init...");
|
||||
try {
|
||||
terminalBridge.init(deps);
|
||||
console.log("OHOS: terminalBridge.init OK");
|
||||
terminalBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: terminalBridge.registerHandlers OK");
|
||||
} catch(e) { console.log("terminalBridge init/register FAILED:", e.message); }
|
||||
|
||||
// transferBridge
|
||||
const transferBridge = require("./bridges/transferBridge.cjs");
|
||||
console.log("OHOS: transferBridge.init...");
|
||||
try {
|
||||
transferBridge.init(deps);
|
||||
console.log("OHOS: transferBridge.init OK");
|
||||
transferBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: transferBridge.registerHandlers OK");
|
||||
} catch(e) { console.log("transferBridge init/register FAILED:", e.message); }
|
||||
|
||||
// localFsBridge — init with homeDir to work around OHOS sandbox
|
||||
const localFsBridge = require("./bridges/localFsBridge.cjs");
|
||||
console.log("OHOS: localFsBridge.init (homeDir)...");
|
||||
try {
|
||||
const homeDir = app.getPath("desktop");
|
||||
console.log("OHOS: homeDir =", homeDir);
|
||||
localFsBridge.init({ homeDir });
|
||||
console.log("OHOS: localFsBridge.init OK");
|
||||
} catch(e) { console.log("localFsBridge.init FAILED:", e.message); }
|
||||
|
||||
console.log("OHOS: localFsBridge.registerHandlers...");
|
||||
try {
|
||||
localFsBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: localFsBridge OK");
|
||||
} catch(e) { console.log("localFsBridge FAILED:", e.message); }
|
||||
|
||||
// portForwardingBridge
|
||||
const portForwardingBridge = require("./bridges/portForwardingBridge.cjs");
|
||||
console.log("OHOS: portForwardingBridge.registerHandlers...");
|
||||
try {
|
||||
portForwardingBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: portForwardingBridge OK");
|
||||
} catch(e) { console.log("portForwardingBridge FAILED:", e.message); }
|
||||
|
||||
// crashLogBridge
|
||||
const crashLogBridge = require("./bridges/crashLogBridge.cjs");
|
||||
console.log("OHOS: crashLogBridge.init...");
|
||||
try {
|
||||
crashLogBridge.init(deps);
|
||||
console.log("OHOS: crashLogBridge.init OK");
|
||||
crashLogBridge.registerHandlers(ipcMain);
|
||||
console.log("OHOS: crashLogBridge.registerHandlers OK");
|
||||
} catch(e) { console.log("crashLogBridge FAILED:", e.message); }
|
||||
|
||||
// Remaining bridges — registerHandlers only (matching working version)
|
||||
const rem = [
|
||||
["oauthBridge", (b) => b.setupOAuthBridge(ipcMain)],
|
||||
["githubAuthBridge", (b) => b.registerHandlers(ipcMain)],
|
||||
["googleAuthBridge", (b) => b.registerHandlers(ipcMain, { app, BrowserWindow })],
|
||||
["onedriveAuthBridge",(b) => b.registerHandlers(ipcMain, { app, BrowserWindow })],
|
||||
["cloudSyncBridge", (b) => b.registerHandlers(ipcMain)],
|
||||
["fileWatcherBridge", (b) => b.registerHandlers(ipcMain)],
|
||||
["tempDirBridge", (b) => b.registerHandlers(ipcMain, require("electron").shell)],
|
||||
["sessionLogsBridge", (b) => b.registerHandlers(ipcMain)],
|
||||
["compressUploadBridge", (b) => { b.init({...deps, transferBridge}); b.registerHandlers(ipcMain); }],
|
||||
["globalShortcutBridge",(b) => b.registerHandlers(ipcMain)],
|
||||
["credentialBridge", (b) => b.registerHandlers(ipcMain, { app, BrowserWindow })],
|
||||
["autoUpdateBridge", (b) => { b.init(deps); b.registerHandlers(ipcMain); }],
|
||||
["aiBridge", (b) => b.registerHandlers(ipcMain)],
|
||||
["vaultBackupBridge", (b) => b.registerHandlers(ipcMain, { app, BrowserWindow })],
|
||||
];
|
||||
for (const [name, fn] of rem) {
|
||||
console.log("OHOS: " + name + "...");
|
||||
try {
|
||||
const b = require("./bridges/" + name + ".cjs");
|
||||
fn(b);
|
||||
console.log("OHOS: " + name + " OK");
|
||||
} catch(e) { console.log(name + " FAILED:", e.message); }
|
||||
}
|
||||
|
||||
// windowManager handlers (theme, window controls)
|
||||
const windowManager = require("./bridges/windowManager.cjs");
|
||||
const { nativeTheme } = require("electron");
|
||||
console.log("OHOS: windowManager.registerWindowHandlers...");
|
||||
try {
|
||||
windowManager.registerWindowHandlers(ipcMain, nativeTheme);
|
||||
console.log("OHOS: windowManager OK");
|
||||
} catch(e) { console.log("windowManager FAILED:", e.message); }
|
||||
|
||||
// app:getInfo — needed by frontend
|
||||
ipcMain.handle("netcatty:app:getInfo", async () => ({
|
||||
name: app.getName(),
|
||||
version: app.getVersion(),
|
||||
platform: process.platform,
|
||||
}));
|
||||
console.log("OHOS: app:getInfo registered");
|
||||
|
||||
// One-time home directory picker (triggers when local FS gets EPERM)
|
||||
ipcMain.handle("netcatty:local:select-home", async () => {
|
||||
const win = BrowserWindow.getAllWindows()[0];
|
||||
if (!win) return { path: process.env.HOME };
|
||||
const result = await dialog.showOpenDialog(win, {
|
||||
properties: ["openDirectory"],
|
||||
title: "选择本地文件根目录(选一次,以后记住)",
|
||||
});
|
||||
if (!result.canceled && result.filePaths.length > 0) {
|
||||
const picked = result.filePaths[0];
|
||||
process.env.HOME = picked;
|
||||
try {
|
||||
fs.writeFileSync(path.join(app.getPath("userData"), "local_home.txt"), picked);
|
||||
} catch {}
|
||||
console.log("OHOS: HOME updated to", picked);
|
||||
return { path: picked };
|
||||
}
|
||||
return { path: process.env.HOME };
|
||||
});
|
||||
console.log("OHOS: local:select-home registered");
|
||||
|
||||
app.whenReady().then(() => {
|
||||
const distIndex = path.join(__dirname, "..", "dist", "index.html");
|
||||
const win = new BrowserWindow({ width: 1280, height: 800, show: true });
|
||||
const preload = path.join(__dirname, "preload.cjs");
|
||||
const win = new BrowserWindow({
|
||||
width: 1280, height: 800, show: true,
|
||||
frame: false,
|
||||
webPreferences: {
|
||||
preload: preload,
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true,
|
||||
sandbox: false,
|
||||
},
|
||||
});
|
||||
win.webContents.openDevTools();
|
||||
win.loadURL("file://" + distIndex);
|
||||
|
||||
// Auto-detect: if HOME is not accessible, show one-time file picker
|
||||
win.webContents.on("did-finish-load", async () => {
|
||||
try {
|
||||
await fs.promises.readdir(process.env.HOME);
|
||||
console.log("OHOS: HOME accessible:", process.env.HOME);
|
||||
} catch (e) {
|
||||
if (e.code === "EPERM" || e.code === "ENOENT") {
|
||||
console.log("OHOS: HOME blocked, showing picker...");
|
||||
const result = await dialog.showOpenDialog(win, {
|
||||
properties: ["openDirectory"],
|
||||
title: "选择本地文件根目录(选一次,以后记住)",
|
||||
});
|
||||
if (!result.canceled && result.filePaths.length > 0) {
|
||||
process.env.HOME = result.filePaths[0];
|
||||
try {
|
||||
fs.writeFileSync(path.join(app.getPath("userData"), "local_home.txt"), result.filePaths[0]);
|
||||
} catch {}
|
||||
console.log("OHOS: HOME updated to", process.env.HOME);
|
||||
win.webContents.reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1514,7 +1514,7 @@ const figSpecApi = {
|
||||
const existing = (typeof window !== "undefined" && window.netcatty) ? window.netcatty : {};
|
||||
|
||||
function getAllowedRendererOrigins() {
|
||||
const origins = new Set(["app://netcatty"]);
|
||||
const origins = new Set(["app://netcatty", "file://", "null"]);
|
||||
const devServerUrl = process.env.VITE_DEV_SERVER_URL;
|
||||
if (typeof devServerUrl === "string" && devServerUrl.length > 0) {
|
||||
try {
|
||||
|
||||