mirror of
https://github.com/hanzoai/desktop.git
synced 2026-10-30 14:58:42 +00:00
Confirmed red-team findings in apps/hanzo-desktop:
1. HIGH — IAM login tokens never persisted during registration. The
useInitialRegistration onSuccess closure read tokens from useHanzoLogin(),
but the hook (a) was destructured AFTER useInitialRegistration and (b) had
regressed to a `{ login }`-only API that no longer exposed `tokens` (4 latent
TS2339 errors in terms-conditions.tsx). Restore the stateful hook API
(login/startLogin/tokens/tokensRef/isLoading/error/resetState) and call it
BEFORE useInitialRegistration. onSuccess now reads `tokensRef.current` — a
closure-safe mirror of the reactive tokens — so a token obtained mid-flow is
actually written into setAuth. Removed the duplicate useHanzoLogin() call and
a stale, conflicting "spawn node when tokens arrive" effect that would have
wrongly spawned a local node in cloud mode (isCloudMode).
2. MED — resetState exported but unused. Wired error/resetState into the login
UI: a failed IAM login now shows an inline error with a Retry control
(resetState() + retry), instead of only console.error.
3. MED — CSP disabled (app.security.csp: null). Set a real CSP: strict
script-src 'self' (+ 'wasm-unsafe-eval' and jsdelivr for pyodide/sql.js),
object-src 'none', base-uri/form-action 'self'. connect-src allows the local
node (http + ws on 127.0.0.1/localhost), Tauri IPC, and is conservatively
widened to https:/wss: because model-provider and web3 RPC endpoints are
user-configurable and unbounded. Verified Tauri parses the config (tauri
info reports the CSP). Shared security block covers all windows; preserved by
the brand-build deep-merge (no overlay sets app.security).
4. MED — download_logs wrote to an arbitrary save_path via fs::copy. Added
validate_save_path: canonicalize the destination's parent (resolving
../symlinks) and reject anything outside the user's home dir, then copy to
the validated path. Keeps the legit dialog-chosen path working.
Deferred (out of scope, noted in PR): WalletData plaintext zeroization — a
cross-cutting refactor of the node API contract.
Verified: tsc -b apps/hanzo-desktop/tsconfig.json --noEmit drops from 31 to 27
unique errors (the 4 terms-conditions.tsx errors resolved, 0 new); cargo check
on src-tauri finishes with 0 errors.
124 lines
3.7 KiB
JSON
124 lines
3.7 KiB
JSON
{
|
|
"build": {
|
|
"beforeDevCommand": "npm run dev",
|
|
"beforeBuildCommand": "npm run build:ci",
|
|
"frontendDist": "../dist",
|
|
"devUrl": "http://localhost:1420"
|
|
},
|
|
"bundle": {
|
|
"active": true,
|
|
"targets": ["app", "appimage", "nsis", "dmg"],
|
|
"externalBin": [
|
|
"external-binaries/hanzo-node/hanzo-node",
|
|
"external-binaries/hanzo-node/hanzo-tools-runner-resources/deno",
|
|
"external-binaries/hanzo-node/hanzo-tools-runner-resources/uv"
|
|
],
|
|
"icon": [
|
|
"icons/32x32.png",
|
|
"icons/128x128.png",
|
|
"icons/[email protected]",
|
|
"icons/icon.icns",
|
|
"icons/icon.ico"
|
|
],
|
|
"resources": ["llm-models/"],
|
|
"macOS": {
|
|
"minimumSystemVersion": "12.0"
|
|
},
|
|
"createUpdaterArtifacts": "v1Compatible"
|
|
},
|
|
"productName": "Hanzo",
|
|
"version": "../../../package.json",
|
|
"identifier": "ai.hanzo.desktop",
|
|
"plugins": {
|
|
"updater": {
|
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDE4OURBNzhCM0Q2RTMwMzIKUldReU1HNDlpNmVkR01uQXpJaS9Dd2gvRlpsbDVYQmg0MlJSUnNib2tSOW5qRG5zSVdsMW0zZm8K",
|
|
"endpoints": [
|
|
"https://github.com/hanzoai/desktop/releases/latest/download/latest.json"
|
|
],
|
|
"windows": {
|
|
"installMode": "basicUi"
|
|
}
|
|
},
|
|
"deep-link": {
|
|
"desktop": {
|
|
"schemes": ["hanzo"]
|
|
}
|
|
}
|
|
},
|
|
"app": {
|
|
"withGlobalTauri": false,
|
|
"security": {
|
|
"csp": "default-src 'self'; script-src 'self' 'wasm-unsafe-eval' https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; img-src 'self' data: blob: https:; font-src 'self' data: https://cdn.jsdelivr.net; media-src 'self' data: blob: https:; worker-src 'self' blob:; frame-src 'self' blob: http://127.0.0.1:* http://localhost:*; connect-src 'self' ipc: http://ipc.localhost http://127.0.0.1:* http://localhost:* ws://127.0.0.1:* ws://localhost:* https: wss:; object-src 'none'; base-uri 'self'; form-action 'self'"
|
|
},
|
|
"windows": [
|
|
{
|
|
"transparent": true,
|
|
"title": "Hanzo",
|
|
"width": 1280,
|
|
"height": 840,
|
|
"resizable": true,
|
|
"dragDropEnabled": false,
|
|
"titleBarStyle": "Overlay",
|
|
"hiddenTitle": true,
|
|
"create": false
|
|
},
|
|
{
|
|
"fullscreen": false,
|
|
"label": "spotlight",
|
|
"transparent": true,
|
|
"title": "Spotlight",
|
|
"width": 800,
|
|
"height": 490,
|
|
"resizable": true,
|
|
"dragDropEnabled": false,
|
|
"titleBarStyle": "Overlay",
|
|
"hiddenTitle": true,
|
|
"url": "src/windows/spotlight/index.html",
|
|
"center": true,
|
|
"skipTaskbar": true,
|
|
"shadow": true,
|
|
"decorations": false,
|
|
"visible": false,
|
|
"closable": false,
|
|
"parent": null,
|
|
"create": false
|
|
},
|
|
{
|
|
"fullscreen": false,
|
|
"label": "coordinator",
|
|
"transparent": true,
|
|
"title": "Coordinator",
|
|
"width": 720,
|
|
"height": 470,
|
|
"resizable": false,
|
|
"dragDropEnabled": false,
|
|
"titleBarStyle": "Overlay",
|
|
"hiddenTitle": true,
|
|
"url": "src/windows/coordinator/index.html",
|
|
"center": true,
|
|
"skipTaskbar": false,
|
|
"shadow": false,
|
|
"decorations": false,
|
|
"visible": false,
|
|
"closable": false,
|
|
"parent": null,
|
|
"create": false
|
|
},
|
|
{
|
|
"label": "hanzo-node-manager",
|
|
"url": "src/windows/hanzo-node-manager/index.html",
|
|
"transparent": true,
|
|
"title": "Hanzo Node Manager",
|
|
"width": 1280,
|
|
"height": 840,
|
|
"resizable": true,
|
|
"dragDropEnabled": false,
|
|
"titleBarStyle": "Overlay",
|
|
"hiddenTitle": true,
|
|
"create": false
|
|
}
|
|
],
|
|
"macOSPrivateApi": true
|
|
}
|
|
}
|