feat: block unsafe npm package installs#3152
Conversation
- preserve socket firewall warnings across error paths - fall back to direct package installs when sfw has runtime failures - restore Windows shell execution for npm-style commands Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 490a6e7477
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| warningMessages.push(SOCKET_FIREWALL_FALLBACK_WARNING_MESSAGE); | ||
| ({ succeeded, installResults, lastError } = await runAddDependencyCommands( | ||
| buildAddDependencyCommands(packages, false), |
There was a problem hiding this comment.
Delay fallback warning until plain install actually succeeds
This branch pushes SOCKET_FIREWALL_FALLBACK_WARNING_MESSAGE before the unwrapped pnpm/npm retry runs, so when the fallback commands also fail the user still gets a warning that says Dyad installed the packages without firewall checks. In that failure scenario the warning is factually wrong and can send users debugging the wrong issue; only emit this warning after the fallback succeeds (or use a different message for fallback failure).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 89796cad72
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const packageManager = await detectPreferredPackageManager(); | ||
| let { succeeded, installResults, lastError } = await runAddDependencyCommand( | ||
| buildAddDependencyCommand(packages, packageManager, useSocketFirewall), | ||
| appPath, | ||
| ); |
There was a problem hiding this comment.
This change now selects a single package manager based only on whether pnpm exists and executes one install path, so when pnpm is present but pnpm add exits non-zero (for example, repo-specific pnpm failures), the function throws instead of retrying with npm. The previous behavior explicitly attempted npm after a pnpm failure, so this is a regression that can make dependency installs fail on environments that happen to have pnpm installed.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 10df01b0cd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
src/main.ts
Outdated
| // Cleanup old media files to reclaim disk space | ||
| cleanupOldMediaFiles(); | ||
|
|
||
| await applyRemoteSettingsDefaultsIfNeeded(); |
There was a problem hiding this comment.
Avoid blocking startup on remote settings fetch
onReady() now awaits applyRemoteSettingsDefaultsIfNeeded() before createWindow(), so app launch is gated on the remote desktop-config request. Because that fetch uses a 5,000 ms timeout, users on slow/offline networks can see a multi-second cold-start delay before any window appears; running this fetch asynchronously (or after first window creation) would avoid this startup regression while still applying defaults.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30c0c7296e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| }) { | ||
| const packageStr = packages.join(" "); | ||
| }): Promise<ExecuteAddDependencyResult> { | ||
| const settings = readEffectiveSettings(); |
There was a problem hiding this comment.
Read effective settings asynchronously for dependency installs
executeAddDependency uses the synchronous readEffectiveSettings() path, which only consults getCachedRemoteDesktopConfig() and then defaults blockUnsafeNpmPackages to true when the cache is missing/expired. With an unset local value and a remote default of false, this makes install behavior flip back to firewall-on after cache expiry (or before any async refresh), so package installs can unexpectedly start failing in the same session. Please use the async effective-settings read here (or otherwise persist/refresh the last remote default) so remote defaults stay consistent.
Useful? React with 👍 / 👎.
| remoteDesktopConfigCache = { | ||
| config: null, | ||
| expiresAt: Date.now() + FAILURE_CACHE_TTL_MS, |
There was a problem hiding this comment.
Preserve last known remote config on fetch failures
On fetch errors this branch overwrites the cache with config: null, which discards any previously successful remote defaults. For users without a local override, a transient network failure then changes effective behavior (via fallback to true) until the next successful fetch, causing settings-driven install policy to flap. Keeping the last good config while applying a shorter retry TTL would avoid these unintended flips.
Useful? React with 👍 / 👎.
🎭 Playwright Test Results❌ Some tests failed
Summary: 812 passed, 13 failed, 8 flaky, 262 skipped Failed Tests🍎 macOS
🪟 WindowsShow all 11 failures
📋 Re-run Failing Tests (macOS)Copy and paste to re-run all failing spec files locally: npm run e2e \
e2e-tests/queued_message.spec.ts
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 190ce65df6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| createTypedHandler(settingsContracts.setUserSettings, async (_, settings) => { | ||
| writeSettings(settings); | ||
| return readSettings(); | ||
| return readEffectiveSettings(); |
There was a problem hiding this comment.
Avoid awaiting remote config in settings write handler
setUserSettings now returns readEffectiveSettings(), which performs a remote desktop-config fetch (with a 5s timeout on cache miss) before resolving. In offline/slow-network scenarios this makes every settings toggle wait on that network call, so controlled switches can appear stuck and setting updates feel unresponsive even though local persistence is synchronous. Returning locally written settings (or using only cached remote defaults) would prevent this user-visible latency regression.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 75bbf0c7bd
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| export async function readEffectiveSettings(): Promise<UserSettings> { | ||
| const settings = readSettings(); | ||
| const remoteConfig = await getRemoteDesktopConfig(); | ||
| return resolveEffectiveSettings(settings, remoteConfig); |
There was a problem hiding this comment.
Short-circuit remote fetch when local setting is explicit
readEffectiveSettings() always awaits getRemoteDesktopConfig() even when settings.blockUnsafeNpmPackages is already explicitly set, so operations that call it (including dependency installs and settings reads/writes) are unnecessarily coupled to a network request with a 5s timeout. In offline/slow-network scenarios this adds avoidable latency despite the local value already taking precedence; returning early when the local boolean is present avoids these stalls without changing behavior.
Useful? React with 👍 / 👎.
Summary
Test plan
🤖 Generated with Claude Code