-
Notifications
You must be signed in to change notification settings - Fork 0
fix(desktop): embedded UI auto-login against a joined brain + isolate the store in desktop tests #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(desktop): embedded UI auto-login against a joined brain + isolate the store in desktop tests #134
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| // Every desktop suite gets an isolated settings store. Without this, openStore() | ||
| // and the config loader resolve to the developer's real ~/.wavegrid and a test | ||
| // run can create projects there or flip the active one. | ||
| const { mkdtempSync } = require('node:fs'); | ||
| const { tmpdir } = require('node:os'); | ||
| const { join } = require('node:path'); | ||
|
|
||
| process.env.APPSTASH_BASE_DIR = mkdtempSync(join(tmpdir(), 'wavegrid-desktop-test-')); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ import fs from 'fs'; | |
| import { | ||
| projectConfigFile, | ||
| projectDir, | ||
| projectSecretsFile, | ||
| readJsonFile, | ||
| type StorePaths, | ||
| writeFileAtomic | ||
|
|
@@ -105,6 +106,7 @@ export function deleteProject(paths: StorePaths, name: string): boolean { | |
| writeRegistry(paths, reg); | ||
| try { | ||
| fs.rmSync(projectDir(paths, name), { recursive: true, force: true }); | ||
| fs.rmSync(projectSecretsFile(paths, name), { force: true }); | ||
| } catch { | ||
| /* best effort */ | ||
| } | ||
|
Comment on lines
+109
to
112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 security · medium Best-effort secret purge can silently leak keys The new Impact: a "deleted" project's 📋 Prompt for AI AgentsIn packages/settings/src/projects.ts deleteProject() (lines 101-115), the secrets file purge (line 109) is inside the same try/catch as the project-dir removal and runs after the registry write, so a failed or short-circuited removal is silently reported as success. Move the secrets removal out of the best-effort block and before |
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 security · medium
Non-revocable 12h admin operator token
In receiver mode
operatorTokenmints arole: admintoken with nosidagainst a joined brain (packages/desktop/src/main/operator-session.ts:46-50), and the brain's WebSocket upgrade accepts a sid-less JWT by signature alone with no live-session, role, or user-existence check (packages/server/src/server.ts:314-329).Revoking the operator's sessions or demoting/removing the account does not kill an already-distributed token, which stays valid for the full 12h
TTL_MS; a leaked token therefore grants admin show control that cannot be cut off server-side, unlike the session-bound local path.📋 Prompt for AI Agents
In packages/desktop/src/main/operator-session.ts lines 46-51, the receiver-mode branch mints a sid-less role:admin JWT valid for TTL_MS (12h) that the remote brain's WebSocket upgrade accepts by signature alone (server.ts:314-329) with no session/role/user check. Reduce the blast radius by shortening
ttlSecfor this branch (e.g. re-mint on each embedded page load) and add a comment recording that this token cannot be revoked from Access→Sessions nor invalidated by demoting/removing the operator, so it is bounded only by expiry.