@@ -20,16 +20,15 @@ const UUID_PATTERN =
2020const CVE_PATTERN = / ^ C V E - \d { 4 } - \d + $ / i
2121const GHSA_PATTERN = / ^ G H S A - [ a - z 0 - 9 ] { 4 } - [ a - z 0 - 9 ] { 4 } - [ a - z 0 - 9 ] { 4 } $ / i
2222
23- type IdentifierType = 'uuid' | 'cve' | 'ghsa' | 'package'
23+ type IdentifierType = 'uuid' | 'cve' | 'ghsa'
2424
2525interface DownloadArgs {
2626 identifier : string
27- org : string
27+ org ? : string
2828 cwd : string
2929 id ?: boolean
3030 cve ?: boolean
3131 ghsa ?: boolean
32- pkg ?: boolean
3332 yes ?: boolean
3433 'api-url' ?: string
3534 'api-token' ?: string
@@ -38,7 +37,7 @@ interface DownloadArgs {
3837/**
3938 * Detect the type of identifier based on its format
4039 */
41- function detectIdentifierType ( identifier : string ) : IdentifierType {
40+ function detectIdentifierType ( identifier : string ) : IdentifierType | null {
4241 if ( UUID_PATTERN . test ( identifier ) ) {
4342 return 'uuid'
4443 }
@@ -48,8 +47,7 @@ function detectIdentifierType(identifier: string): IdentifierType {
4847 if ( GHSA_PATTERN . test ( identifier ) ) {
4948 return 'ghsa'
5049 }
51- // Default to package search for anything else
52- return 'package'
50+ return null
5351}
5452
5553/**
@@ -165,7 +163,6 @@ async function downloadPatches(args: DownloadArgs): Promise<boolean> {
165163 id : forceId ,
166164 cve : forceCve ,
167165 ghsa : forceGhsa ,
168- pkg : forcePackage ,
169166 yes : skipConfirmation ,
170167 'api-url' : apiUrl ,
171168 'api-token' : apiToken ,
@@ -179,8 +176,18 @@ async function downloadPatches(args: DownloadArgs): Promise<boolean> {
179176 process . env . SOCKET_API_TOKEN = apiToken
180177 }
181178
182- // Get API client
183- const apiClient = getAPIClientFromEnv ( )
179+ // Get API client (will use public proxy if no token is set)
180+ const { client : apiClient , usePublicProxy } = getAPIClientFromEnv ( )
181+
182+ // Validate that org is provided when using authenticated API
183+ if ( ! usePublicProxy && ! orgSlug ) {
184+ throw new Error (
185+ '--org is required when using SOCKET_API_TOKEN. Provide an organization slug.' ,
186+ )
187+ }
188+
189+ // The org slug to use (null when using public proxy)
190+ const effectiveOrgSlug = usePublicProxy ? null : orgSlug ?? null
184191
185192 // Determine identifier type
186193 let idType : IdentifierType
@@ -190,17 +197,21 @@ async function downloadPatches(args: DownloadArgs): Promise<boolean> {
190197 idType = 'cve'
191198 } else if ( forceGhsa ) {
192199 idType = 'ghsa'
193- } else if ( forcePackage ) {
194- idType = 'package'
195200 } else {
196- idType = detectIdentifierType ( identifier )
201+ const detectedType = detectIdentifierType ( identifier )
202+ if ( ! detectedType ) {
203+ throw new Error (
204+ `Unrecognized identifier format: ${ identifier } . Expected UUID, CVE ID (CVE-YYYY-NNNNN), or GHSA ID (GHSA-xxxx-xxxx-xxxx).` ,
205+ )
206+ }
207+ idType = detectedType
197208 console . log ( `Detected identifier type: ${ idType } ` )
198209 }
199210
200211 // For UUID, directly fetch and download the patch
201212 if ( idType === 'uuid' ) {
202213 console . log ( `Fetching patch by UUID: ${ identifier } ` )
203- const patch = await apiClient . fetchPatch ( orgSlug , identifier )
214+ const patch = await apiClient . fetchPatch ( effectiveOrgSlug , identifier )
204215 if ( ! patch ) {
205216 console . log ( `No patch found with UUID: ${ identifier } ` )
206217 return true
@@ -246,20 +257,12 @@ async function downloadPatches(args: DownloadArgs): Promise<boolean> {
246257 switch ( idType ) {
247258 case 'cve' : {
248259 console . log ( `Searching patches for CVE: ${ identifier } ` )
249- searchResponse = await apiClient . searchPatchesByCVE ( orgSlug , identifier )
260+ searchResponse = await apiClient . searchPatchesByCVE ( effectiveOrgSlug , identifier )
250261 break
251262 }
252263 case 'ghsa' : {
253264 console . log ( `Searching patches for GHSA: ${ identifier } ` )
254- searchResponse = await apiClient . searchPatchesByGHSA ( orgSlug , identifier )
255- break
256- }
257- case 'package' : {
258- console . log ( `Searching patches for package: ${ identifier } ` )
259- searchResponse = await apiClient . searchPatchesByPackage (
260- orgSlug ,
261- identifier ,
262- )
265+ searchResponse = await apiClient . searchPatchesByGHSA ( effectiveOrgSlug , identifier )
263266 break
264267 }
265268 default :
@@ -331,7 +334,7 @@ async function downloadPatches(args: DownloadArgs): Promise<boolean> {
331334
332335 for ( const searchResult of accessiblePatches ) {
333336 // Fetch full patch details with blob content
334- const patch = await apiClient . fetchPatch ( orgSlug , searchResult . uuid )
337+ const patch = await apiClient . fetchPatch ( effectiveOrgSlug , searchResult . uuid )
335338 if ( ! patch ) {
336339 console . log ( ` [fail] ${ searchResult . purl } (could not fetch details)` )
337340 patchesFailed ++
@@ -378,14 +381,14 @@ export const downloadCommand: CommandModule<{}, DownloadArgs> = {
378381 return yargs
379382 . positional ( 'identifier' , {
380383 describe :
381- 'Patch identifier (UUID, CVE ID, GHSA ID, or package name )' ,
384+ 'Patch identifier (UUID, CVE ID, or GHSA ID )' ,
382385 type : 'string' ,
383386 demandOption : true ,
384387 } )
385388 . option ( 'org' , {
386- describe : 'Organization slug' ,
389+ describe : 'Organization slug (required when using SOCKET_API_TOKEN, optional for public proxy) ' ,
387390 type : 'string' ,
388- demandOption : true ,
391+ demandOption : false ,
389392 } )
390393 . option ( 'id' , {
391394 describe : 'Force identifier to be treated as a patch UUID' ,
@@ -402,11 +405,6 @@ export const downloadCommand: CommandModule<{}, DownloadArgs> = {
402405 type : 'boolean' ,
403406 default : false ,
404407 } )
405- . option ( 'pkg' , {
406- describe : 'Force identifier to be treated as a package name' ,
407- type : 'boolean' ,
408- default : false ,
409- } )
410408 . option ( 'yes' , {
411409 alias : 'y' ,
412410 describe : 'Skip confirmation prompt for multiple patches' ,
@@ -427,33 +425,29 @@ export const downloadCommand: CommandModule<{}, DownloadArgs> = {
427425 type : 'string' ,
428426 } )
429427 . example (
430- '$0 download 12345678-1234-1234-1234-123456789abc --org myorg' ,
431- 'Download a patch by UUID' ,
432- )
433- . example (
434- '$0 download CVE-2021-44228 --org myorg' ,
435- 'Search and download patches for a CVE' ,
428+ '$0 download CVE-2021-44228' ,
429+ 'Download free patches for a CVE (no auth required)' ,
436430 )
437431 . example (
438- '$0 download GHSA-jfhm-5ghh-2f97 --org myorg ' ,
439- 'Search and download patches for a GHSA' ,
432+ '$0 download GHSA-jfhm-5ghh-2f97' ,
433+ 'Download free patches for a GHSA (no auth required) ' ,
440434 )
441435 . example (
442- '$0 download lodash --org myorg --pkg ' ,
443- 'Search and download patches for a package ' ,
436+ '$0 download 12345678-1234-1234-1234-123456789abc --org myorg' ,
437+ 'Download a patch by UUID (requires SOCKET_API_TOKEN) ' ,
444438 )
445439 . example (
446440 '$0 download CVE-2021-44228 --org myorg --yes' ,
447- 'Download all matching patches without confirmation' ,
441+ 'Download all matching patches without confirmation (with auth) ' ,
448442 )
449443 . check ( argv => {
450444 // Ensure only one type flag is set
451- const typeFlags = [ argv . id , argv . cve , argv . ghsa , argv . pkg ] . filter (
445+ const typeFlags = [ argv . id , argv . cve , argv . ghsa ] . filter (
452446 Boolean ,
453447 )
454448 if ( typeFlags . length > 1 ) {
455449 throw new Error (
456- 'Only one of --id, --cve, --ghsa, or --pkg can be specified' ,
450+ 'Only one of --id, --cve, or --ghsa can be specified' ,
457451 )
458452 }
459453 return true
0 commit comments