fix: complete source from ZIP + add hvigor configs + local debug signing
@ -4,7 +4,7 @@
|
|||||||
"projectType": "hvigor",
|
"projectType": "hvigor",
|
||||||
"uri": {
|
"uri": {
|
||||||
"$type": 1,
|
"$type": 1,
|
||||||
"data": "file:///storage/Users/currentUser/Desktop/projects/ohos_electron_hap"
|
"data": "file:///storage/Users/currentUser/Desktop/project/ohos_electron_hap"
|
||||||
},
|
},
|
||||||
"buildTask": "",
|
"buildTask": "",
|
||||||
"extendConfigs": {
|
"extendConfigs": {
|
||||||
@ -13,12 +13,12 @@
|
|||||||
},
|
},
|
||||||
"subProjects": [
|
"subProjects": [
|
||||||
{
|
{
|
||||||
"name": "electron",
|
"name": "web_engine",
|
||||||
"description": "",
|
"description": "",
|
||||||
"projectType": "hvigor",
|
"projectType": "hvigor",
|
||||||
"uri": {
|
"uri": {
|
||||||
"$type": 1,
|
"$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": "",
|
"buildTask": "",
|
||||||
"extendConfigs": {
|
"extendConfigs": {
|
||||||
@ -38,12 +38,12 @@
|
|||||||
"dependencyProjects": []
|
"dependencyProjects": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "web_engine",
|
"name": "electron",
|
||||||
"description": "",
|
"description": "",
|
||||||
"projectType": "hvigor",
|
"projectType": "hvigor",
|
||||||
"uri": {
|
"uri": {
|
||||||
"$type": 1,
|
"$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": "",
|
"buildTask": "",
|
||||||
"extendConfigs": {
|
"extendConfigs": {
|
||||||
@ -69,25 +69,25 @@
|
|||||||
{
|
{
|
||||||
"url": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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": {
|
"url": {
|
||||||
"$type": 1,
|
"$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"
|
"name": "release"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"signingConfigs": [
|
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
|
|||||||
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.
|
* 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 HAR_VERSION = '1.0.0';
|
||||||
export const BUILD_MODE_NAME = 'debug';
|
export const BUILD_MODE_NAME = 'release';
|
||||||
export const DEBUG = true;
|
export const DEBUG = false;
|
||||||
export const TARGET_NAME = 'default';
|
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
|
* List files in a local directory
|
||||||
* Properly handles symlinks by resolving their target type
|
* Properly handles symlinks by resolving their target type
|
||||||
@ -299,7 +308,7 @@ async function listLocalTree(event, payload) {
|
|||||||
* Get the home directory
|
* Get the home directory
|
||||||
*/
|
*/
|
||||||
async function getHomeDir() {
|
async function getHomeDir() {
|
||||||
return os.homedir();
|
return _homeDirOverride || os.homedir();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,7 +325,7 @@ async function getSystemInfo() {
|
|||||||
* Read system known_hosts file
|
* Read system known_hosts file
|
||||||
*/
|
*/
|
||||||
async function readKnownHosts() {
|
async function readKnownHosts() {
|
||||||
const homeDir = os.homedir();
|
const homeDir = _homeDirOverride || os.homedir();
|
||||||
const knownHostsPaths = [];
|
const knownHostsPaths = [];
|
||||||
|
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
@ -366,6 +375,7 @@ function registerHandlers(ipcMain) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
init,
|
||||||
registerHandlers,
|
registerHandlers,
|
||||||
listLocalDir,
|
listLocalDir,
|
||||||
readLocalFile,
|
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,
|
// HarmonyOS: the full main.cjs startup (80+ bridge requires, GPU switches,
|
||||||
// protocol registration, etc.) causes SIGSEGV in V8. Use minimal init.
|
// protocol registration, etc.) causes SIGSEGV in V8. Use minimal init.
|
||||||
if (process.platform === 'ohos' || process.platform === 'openharmony') {
|
if (process.platform === 'ohos' || process.platform === 'openharmony') {
|
||||||
const { app, BrowserWindow } = require("electron");
|
|
||||||
|
const { app, BrowserWindow, protocol, dialog } = require("electron");
|
||||||
const path = require("path");
|
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(() => {
|
app.whenReady().then(() => {
|
||||||
const distIndex = path.join(__dirname, "..", "dist", "index.html");
|
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);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1514,7 +1514,7 @@ const figSpecApi = {
|
|||||||
const existing = (typeof window !== "undefined" && window.netcatty) ? window.netcatty : {};
|
const existing = (typeof window !== "undefined" && window.netcatty) ? window.netcatty : {};
|
||||||
|
|
||||||
function getAllowedRendererOrigins() {
|
function getAllowedRendererOrigins() {
|
||||||
const origins = new Set(["app://netcatty"]);
|
const origins = new Set(["app://netcatty", "file://", "null"]);
|
||||||
const devServerUrl = process.env.VITE_DEV_SERVER_URL;
|
const devServerUrl = process.env.VITE_DEV_SERVER_URL;
|
||||||
if (typeof devServerUrl === "string" && devServerUrl.length > 0) {
|
if (typeof devServerUrl === "string" && devServerUrl.length > 0) {
|
||||||
try {
|
try {
|
||||||
|
|||||||