Commit 2976ce0
authored
fix(fix): validate target directory and detect misplaced IDs (#1227)
* fix(fix): validate target directory and detect misplaced IDs
Backport of v1.x #1199 to main. Two quality-of-life fixes for
\`socket fix\` that surface clear error messages instead of the
confusing API error the user hits today:
1. **Misplaced vulnerability ID**: if the first positional arg looks
like a GHSA, CVE, or PURL, we treat it as a directory path and
eventually fail with "Need at least one file to be uploaded" from
the API. Now we detect the pattern early, fail fast with a
"Did you mean: socket fix --id <that value>" hint.
2. **Nonexistent target directory**: previously the directory wasn't
validated upfront, so we'd happily resolve it, glob zero files,
upload nothing, and the API would reject with the same confusing
"Need at least one file to be uploaded" message. Now we
\`existsSync()\` the resolved path and fail with
"Target directory does not exist: <path>".
Tests:
* Reworked the existing "should support custom cwd argument" test
to pass \`process.cwd()\` (guaranteed to exist) now that we
validate the dir.
* Added "should fail fast when target directory does not exist".
* Added "should fail fast when a GHSA is passed as a positional arg".
* fix(fix): move input validation before org-slug resolution
Addresses both Cursor bugbot findings on #1227:
1. **[Medium] Misplaced-ID check was behind getDefaultOrgSlug()**.
If a user had no API token configured, `getDefaultOrgSlug()` would
fail first and the helpful "looks like a vulnerability identifier"
/ "Target directory does not exist" messages never reached them.
Moved both validation blocks ahead of the org-slug resolution —
they only depend on `cli.input[0]`, no token required.
2. **[Low] Case-insensitive detection with verbatim echo**. The regex
matched `ghsa-abcd-…` but `handle-fix.mts` matches the GHSA/CVE
prefix case-sensitively, so the suggested `socket fix --id ghsa-…`
would fail downstream with "Unsupported ID format". Now we
normalize GHSA/CVE to uppercase in the suggestion while keeping
PURLs unchanged (they're intentionally lowercase).
Added tests:
- uppercase normalization of a lowercase GHSA in the suggestion.
- validation short-circuits before `getDefaultOrgSlug` for both
the misplaced-ID path and the missing-target-dir path.
* fix(fix): preserve GHSA body case in uppercased suggestion
Cursor bugbot caught a second-order bug in my earlier case fix on
#1227. The previous commit uppercased the *entire* rawInput, but
handle-fix.mts's format validator is
GHSA_FORMAT_REGEXP = /^GHSA-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}$/
which requires the body segments to be lowercase. A user typing
`ghsa-abcd-efgh-ijkl` would have been told to run
`socket fix --id GHSA-ABCD-EFGH-IJKL`, and that command would fail
downstream with "Invalid GHSA format".
Fix: only uppercase the prefix.
* GHSA: `'GHSA-' + body.toLowerCase()`
* CVE: `'CVE-' + rest` (body is digits + dashes, case-free)
* PURL: leave verbatim.
Added tests covering all three branches.
* test(fix): tighten coverage of input-validation branches
Tightens the cmd-fix tests introduced with the input-validation work:
* Consolidates four separate ID-detection tests into an `it.each`
table that exercises the real case matrix against handle-fix.mts's
downstream format regexes:
- canonical / lowercase / mixed-case GHSA
- canonical / lowercase CVE
- PURL (unchanged)
Each row asserts both the "looks like a vulnerability identifier"
message and the exact downstream-valid `--id <suggestion>` form.
Previously a mixed-case GHSA and the canonical CVE/GHSA cases
weren't covered, so a future regression to the case-normalization
logic could slip by.
* Splits the directory-validation tests into a dedicated
`describe('target directory validation', ...)` block and adds a
happy-path assertion ("lets a real directory flow through to
handleFix") so we can tell the difference between "validation
passed" and "validation silently skipped".
* Folded the redundant "should support custom cwd argument" test
into the happy-path assertion — same setup, one test instead of
two with overlapping mocks.
* Order-of-operations assertions (that validation runs before
`getDefaultOrgSlug`) now live next to the related bail tests
instead of floating at the end of the outer describe.
Net: 6 cases in the ID-detection table (up from 3 hardcoded), plus
3 directory-validation tests including the happy path. 47 tests total.1 parent 9fae51f commit 2976ce0
File tree
2 files changed
+122
-12
lines changed- packages/cli
- src/commands/fix
- test/unit/commands/fix
2 files changed
+122
-12
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
1 | 2 | | |
2 | 3 | | |
3 | 4 | | |
| |||
408 | 409 | | |
409 | 410 | | |
410 | 411 | | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
411 | 460 | | |
412 | 461 | | |
413 | 462 | | |
| |||
419 | 468 | | |
420 | 469 | | |
421 | 470 | | |
422 | | - | |
423 | | - | |
424 | | - | |
425 | | - | |
426 | | - | |
427 | 471 | | |
428 | 472 | | |
429 | 473 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
331 | 331 | | |
332 | 332 | | |
333 | 333 | | |
334 | | - | |
335 | | - | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
336 | 378 | | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
342 | 408 | | |
343 | 409 | | |
344 | 410 | | |
| |||
0 commit comments