mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
Post-review of Phase 2 (#8228). The reviewer flagged one real bug and several pieces of premature scaffolding. Real bug — finding #1: the sync form was still writing the sync folder path back into the renderer credential store. Phase 2 made the IPCs take a relative path and main own the canonical root, but the Formly button at sync-form.const.ts:200 had `key: 'syncFolderPath'`, which caused FormlyBtn.onClick to setValue(picker-return-string) on the form model. That flowed into privateCfg.syncFolderPath on save. The "renderer no longer holds the authoritative copy" claim was true in the IPC contract but untrue at runtime. A compromised renderer could keep mutating its own privateCfg.syncFolderPath; nothing on master reads it after Phase 2, but any future code path that does would re-open the hole. Fix: - drop `syncFolderPath` from PROVIDER_FIELD_DEFAULTS[LocalFile] so it is not in the LocalFile credential-store defaults at all - drop `key: 'syncFolderPath'` from the LocalFile picker button so the picker's return value is not bound to the form model KISS simplifications (a/b/d from review): - delete electron/sync-folder-store.ts and its test; inline the load/cache/persist helpers at the top of local-file-sync.ts as ~25 LOC. The dedicated module was carrying an init/get/set ceremony and a Promise singleton for a single string that is read at most a few times per second in the worst case. simple-store is the durable layer either way. - drop the `_resolveOrThrow` typeof precheck; resolveSyncPath already type-checks `relativePath` and throws the same opaque error - inline `resolveSyncPath(...).absolutePath` into each handler; the helper was the third layer doing the same thing Other findings addressed: - finding #2 (PICK_DIRECTORY silently undefined on persist failure): PICK_DIRECTORY now returns a safe Error via createSafeIpcError when realpath/persist fails, distinct from `undefined` for user-cancel. New tests cover both branches plus the "cache must not be poisoned with a non-existent path" invariant. - finding #4 (set-without-canonicalize): the inlined setSyncFolderPath now `realpathSync.native`s the picked path before persisting, so a relative or symlinked picker result is rejected early and the on-disk form matches what resolveSyncPath compares against on read. - finding #5 (fire-and-forget init that was also being awaited per handler): dropped the fire-and-forget; handlers just `await getSyncFolderPath()`, which lazy-loads from disk on first call and caches. All 52 electron security tests still pass; lint clean; tsc clean. |
||
|---|---|---|
| .. | ||
| 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.test.cjs | ||
| 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.test.cjs | ||
| ipc-handler-wrapper.ts | ||
| ipc-handler.ts | ||
| jira.ts | ||
| local-file-sync.test.cjs | ||
| local-file-sync.ts | ||
| local-rest-api.ts | ||
| lockscreen.ts | ||
| main-window.ts | ||
| main.ts | ||
| plugin-node-executor.test.cjs | ||
| 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 | ||
| sync-path-resolver.test.cjs | ||
| sync-path-resolver.ts | ||
| task-widget.test.cjs | ||
| tsconfig.electron.json | ||
| various-shared.ts | ||