mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
* test(e2e): retry supersync time-estimate dialog until input binds
The fill('10m') could fire its `input` event before the duration input's
value-accessor (an `input` HostListener) was wired, so the typed value
never reached the model and submit() saved an empty time — the panel
stayed "-/-" and toContainText('10m') timed out (scheduled run
27197862391, SuperSync 1/6). Retry the whole open→fill→submit cycle so a
fill that didn't stick is re-applied once the control binds.
* fix(electron): restrict loadBackupData IPC to the backup directory
The BACKUP_LOAD_DATA handler passed the renderer-supplied path straight
to readFileSync with no validation. Because plugin background scripts run
via `new Function` in the renderer, any installed plugin (or an XSS
payload in task content) could read arbitrary files through
window.ea.loadBackupData('/etc/shadow').
Constrain the path to BACKUP_DIR / BACKUP_DIR_WINSTORE via a new
isPathInsideDir guard. It uses path.relative (not a startsWith string
compare) so `..` traversal is collapsed and a name-prefixed sibling
directory (backups vs backups-evil) is not mistaken for a child. The only
legitimate caller already passes paths built from BACKUP_DIR, and
getBackupPath() is display-only, so backup restore is unaffected.
Adds electron/file-path-guard.test.cjs (node --test) covering traversal
escape, prefix-sibling, absolute-outside, and normalize-stays-inside.
Refs GHSA-x937-wf3j-88q3
* docs(electron): note lexical-only containment in file-path-guard
Clarify that isPathInsideDir does string-based containment (no fs.realpath),
so a symlink planted inside the dir is out of scope — it requires local
filesystem write access, outside this guard's renderer-input threat model.
Surfaced during multi-agent review of the GHSA-x937-wf3j-88q3 fix.
* test(electron): load guard via computed path for asar require check
The electron-smoke job runs tools/verify-electron-requires.js over the
packaged app.asar, which flags literal relative require() calls that can't
resolve in the package. The new guard test had require('./file-path-guard.ts'),
but .ts source is excluded from app.asar, so the check failed. Load the module
via a computed path (require(path.resolve(__dirname, ...))) — the same pattern
the other electron *.test.cjs files use; the scanner skips computed requires.
Also reworded the comment, which had reintroduced the literal pattern (the
scanner matches raw text, comments included).
|
||
|---|---|---|
| .. | ||
| assets/icons | ||
| ipc-handlers | ||
| scripts | ||
| shared-with-frontend | ||
| task-widget | ||
| wayland-idle-helper | ||
| app-control.test.cjs | ||
| backup.ts | ||
| clear-stale-idb-locks.ts | ||
| clipboard-image-handler.ts | ||
| common.const.ts | ||
| CONFIG.ts | ||
| debug.ts | ||
| electronAPI.d.ts | ||
| error-handler-with-frontend-inform.ts | ||
| file-path-guard.test.cjs | ||
| file-path-guard.ts | ||
| full-screen-blocker.ts | ||
| gpu-startup-guard.ts | ||
| idle-time-handler.ts | ||
| indicator.test.cjs | ||
| indicator.ts | ||
| ipc-handler-wrapper.ts | ||
| ipc-handler.ts | ||
| jira.ts | ||
| local-file-sync.ts | ||
| local-rest-api.ts | ||
| lockscreen.ts | ||
| main-window.ts | ||
| main.ts | ||
| plugin-node-executor.ts | ||
| plugin-oauth.ts | ||
| preload.ts | ||
| protocol-handler.ts | ||
| proxy-agent.test.cjs | ||
| proxy-agent.ts | ||
| shared-state.ts | ||
| simple-store.test.cjs | ||
| simple-store.ts | ||
| start-app.ts | ||
| tsconfig.electron.json | ||
| various-shared.ts | ||