Security: major dependency upgrades clearing all npm advisories; show per-advisory fix paths

This commit is contained in:
Avi 2026-08-24 11:00:18 -05:00
commit c11ab9f735
8 changed files with 1834 additions and 4202 deletions

File diff suppressed because it is too large Load diff

View file

@ -32,17 +32,17 @@
"@types/node": "^26.1.2",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"electron": "^33.2.0",
"electron-builder": "^25.1.8",
"@vitejs/plugin-react": "^6.1.0",
"electron": "^43.4.1",
"electron-builder": "^26.15.3",
"eslint": "^9.15.0",
"eslint-plugin-react-hooks": "^5.0.0",
"jsdom": "^25.0.1",
"prettier": "^3.3.3",
"typescript": "^5.6.3",
"typescript-eslint": "^8.15.0",
"vite": "^5.4.11",
"vitest": "^2.1.8"
"vite": "^8.2.2",
"vitest": "^4.1.11"
},
"build": {
"appId": "dev.nostfeedmanager.desktop",

View file

@ -107,6 +107,8 @@ export interface SecurityAdvisory {
/** npm severity label: critical / high / moderate / low / info. */
severity: string;
title: string | null;
/** What is needed to clear it; null when a compatible fix exists. */
fix: string | null;
}
/** Result of scanning both dependency sets for updates. */

View file

@ -258,6 +258,7 @@ export function SettingsScreen() {
</Badge>{' '}
<code className="mono">{advisory.package}</code>
{advisory.title ? ` — ${advisory.title}` : ''}
{advisory.fix && <span className="hint"> {advisory.fix}</span>}
</li>
))}
</ul>

View file

@ -73,7 +73,13 @@ describe('SettingsScreen', () => {
await user.click(await screen.findByRole('button', { name: /Check for updates/i }));
expect(await screen.findByText('1 security issue(s) found')).toBeInTheDocument();
expect(await screen.findByText('2 security issue(s) found')).toBeInTheDocument();
expect(screen.getByText(/minimist/)).toBeInTheDocument();
// Advisories needing a major upgrade explain themselves instead of
// silently surviving an install.
expect(
screen.getByText('Needs electron@43.4.1, a major upgrade — not auto-installed.'),
).toBeInTheDocument();
expect(screen.getByText(/minimist/)).toBeInTheDocument();
expect(screen.getByText('JavaScript packages')).toBeInTheDocument();
expect(screen.getByText('Rust crates')).toBeInTheDocument();

View file

@ -152,6 +152,13 @@ export function createFakeBackend(initial?: AppState): FakeBackend {
package: 'minimist',
severity: 'high',
title: 'Prototype Pollution',
fix: null,
},
{
package: 'electron',
severity: 'critical',
title: 'ASAR Integrity Bypass',
fix: 'Needs electron@43.4.1, a major upgrade — not auto-installed.',
},
],
outdated_cargo: [{ name: 'serde', current: '1.0.200', available: '1.0.219' }],