Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { rawNpmCommand } from './commands/raw-npm'
import { rawNpxCommand } from './commands/raw-npx'
import { reportCommand } from './commands/report'
import { reposCommand } from './commands/repos'
import { scanCommand } from './commands/scan'
import { cmdScan } from './commands/scan/cmd-scan.ts'
import { threatFeedCommand } from './commands/threat-feed'
import { wrapperCommand } from './commands/wrapper'
import constants from './constants'
Expand Down Expand Up @@ -61,7 +61,7 @@ void (async () => {
'raw-npx': rawNpxCommand,
report: reportCommand,
wrapper: wrapperCommand,
scan: scanCommand,
scan: cmdScan,
'audit-log': auditLogCommand,
repos: reposCommand,
dependencies: dependenciesCommand,
Expand Down
166 changes: 166 additions & 0 deletions src/commands/scan/cmd-create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import process from 'node:process'

import meowOrDie from 'meow'
import colors from 'yoctocolors-cjs'

import { Spinner } from '@socketsecurity/registry/lib/spinner'

import { createFullScan } from './create-full-scan.ts'
import { handleUnsuccessfulApiResponse } from '../../utils/api'
import { AuthError } from '../../utils/errors'
import { getFlagListOutput } from '../../utils/output-formatting'
import { getPackageFilesFullScans } from '../../utils/path-resolve'
import { getDefaultToken, setupSdk } from '../../utils/sdk'

import type { CliCommandConfig } from '../../utils/meow-with-subcommands'

const config: CliCommandConfig = {
commandName: 'create',
description: 'Create a scan',
hidden: false,
flags: {
repo: {
type: 'string',
shortFlag: 'r',
default: '',
description: 'Repository name'
},
branch: {
type: 'string',
shortFlag: 'b',
default: '',
description: 'Branch name'
},
commitMessage: {
type: 'string',
shortFlag: 'm',
default: '',
description: 'Commit message'
},
commitHash: {
type: 'string',
shortFlag: 'ch',
default: '',
description: 'Commit hash'
},
pullRequest: {
type: 'number',
shortFlag: 'pr',
description: 'Commit hash'
},
committers: {
type: 'string',
shortFlag: 'c',
default: '',
description: 'Committers'
},
defaultBranch: {
type: 'boolean',
shortFlag: 'db',
default: false,
description: 'Make default branch'
},
pendingHead: {
type: 'boolean',
shortFlag: 'ph',
default: false,
description: 'Set as pending head'
},
tmp: {
type: 'boolean',
shortFlag: 't',
default: false,
description:
'Set the visibility (true/false) of the scan in your dashboard'
}
},
help: (parentName, config) => `
Usage
$ ${parentName} ${config.commandName} [...options] <org>

Options
${getFlagListOutput(config.flags, 6)}

Examples
$ ${parentName} ${config.commandName} --org=FakeOrg --repo=test-repo --branch=main ./package.json
`
}

export const cmdScanCreate = {
description: config.description,
hidden: config.hidden,
run
}

async function run(
argv: readonly string[],
importMeta: ImportMeta,
{ parentName }: { parentName: string }
): Promise<void> {
const cli = meowOrDie(config.help(parentName, config), {
argv,
description: config.description,
importMeta,
flags: config.flags
})

const orgSlug = cli.input[0] ?? '' // TODO: if nobody uses this then get rid of it in favor of --org
const cwd = process.cwd()

const socketSdk = await setupSdk()
const supportedFiles = await socketSdk
.getReportSupportedFiles()
.then(res => {
if (!res.success)
handleUnsuccessfulApiResponse(
'getReportSupportedFiles',
res,
new Spinner()
)
// TODO: verify type at runtime? Consider it trusted data and assume type?
return (res as any).data
})
.catch((cause: Error) => {
throw new Error('Failed getting supported files for report', { cause })
})

const packagePaths = await getPackageFilesFullScans(
cwd,
cli.input,
supportedFiles
)

const { branch: branchName, repo: repoName } = cli.flags

if (!orgSlug || !repoName || !branchName || !packagePaths.length) {
console.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
- Org name as the argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n
- Repository name using --repo ${!repoName ? colors.red('(missing!)') : colors.green('(ok)')}\n
- Branch name using --branch ${!branchName ? colors.red('(missing!)') : colors.green('(ok)')}\n
- At least one file path (e.g. ./package.json) ${!packagePaths.length ? colors.red('(missing or no matching/supported files found!)') : colors.green('(ok)')}`)
config.help(parentName, config)
return
}

const apiToken = getDefaultToken()
if (!apiToken) {
throw new AuthError(
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
)
}

await createFullScan({
apiToken,
orgSlug,
repoName: repoName as string,
branchName: branchName as string,
commitMessage: (cli.flags['commitMessage'] as string) ?? '',
defaultBranch: Boolean(cli.flags['defaultBranch']),
pendingHead: Boolean(cli.flags['pendingHead']),
tmp: Boolean(cli.flags['tmp']),
packagePaths,
commitHash: (cli.flags['commitHash'] as string) ?? '',
committers: (cli.flags['committers'] as string) ?? '',
pullRequest: (cli.flags['pullRequest'] as number) ?? undefined
})
}
71 changes: 71 additions & 0 deletions src/commands/scan/cmd-delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import meow from 'meow'
import colors from 'yoctocolors-cjs'

import { deleteOrgFullScan } from './delete-full-scan.ts'
import { commonFlags, outputFlags } from '../../flags'
import { AuthError } from '../../utils/errors'
import { getFlagListOutput } from '../../utils/output-formatting'
import { getDefaultToken } from '../../utils/sdk'

import type { CliCommandConfig } from '../../utils/meow-with-subcommands'

const config: CliCommandConfig = {
commandName: 'del',
description: 'Delete a scan',
hidden: false,
flags: {
...commonFlags,
...outputFlags
},
help: (parentName, config) => `
Usage
$ ${parentName} ${config.commandName} <org slug> <scan ID>

Options
${getFlagListOutput(config.flags, 6)}

Examples
$ ${parentName} ${config.commandName} FakeOrg 000aaaa1-0000-0a0a-00a0-00a0000000a0
`
}

export const cmdScanDelete = {
description: config.description,
hidden: config.hidden,
run
}

async function run(
argv: readonly string[],
importMeta: ImportMeta,
{ parentName }: { parentName: string }
): Promise<void> {
const cli = meow(config.help(parentName, config), {
argv,
description: config.description,
importMeta,
flags: config.flags
})

const [orgSlug = '', fullScanId = ''] = cli.input

if (!orgSlug || !fullScanId) {
console.error(
`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}\n
- Full Scan ID to delete as second argument ${!fullScanId ? colors.red('(missing!)') : colors.green('(ok)')}
`
)
config.help(parentName, config)
return
}

const apiToken = getDefaultToken()
if (!apiToken) {
throw new AuthError(
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
)
}

await deleteOrgFullScan(orgSlug, fullScanId, apiToken)
}
136 changes: 136 additions & 0 deletions src/commands/scan/cmd-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import meow from 'meow'
import colors from 'yoctocolors-cjs'

import { Spinner } from '@socketsecurity/registry/lib/spinner'

import { listFullScans } from './list-full-scans.ts'
import { commonFlags, outputFlags } from '../../flags'
import { AuthError } from '../../utils/errors'
import { getFlagListOutput } from '../../utils/output-formatting'
import { getDefaultToken } from '../../utils/sdk'

import type {
CliCommandConfig,
CliSubcommand
} from '../../utils/meow-with-subcommands'

const config: CliCommandConfig = {
commandName: 'list',
description: 'List the full scans for an organization',
hidden: false,
flags: {
...commonFlags,
...outputFlags,
sort: {
type: 'string',
shortFlag: 's',
default: 'created_at',
description:
'Sorting option (`name` or `created_at`) - default is `created_at`'
},
direction: {
type: 'string',
shortFlag: 'd',
default: 'desc',
description: 'Direction option (`desc` or `asc`) - Default is `desc`'
},
perPage: {
type: 'number',
shortFlag: 'pp',
default: 30,
description: 'Results per page - Default is 30'
},
page: {
type: 'number',
shortFlag: 'p',
default: 1,
description: 'Page number - Default is 1'
},
fromTime: {
type: 'string',
shortFlag: 'f',
default: '',
description: 'From time - as a unix timestamp'
},
untilTime: {
type: 'string',
shortFlag: 'u',
default: '',
description: 'Until time - as a unix timestamp'
}
},
help: (parentName, config) => `
Usage
$ ${parentName} ${config.commandName} <org slug>

Options
${getFlagListOutput(config.flags, 6)}

Examples
$ ${parentName} ${config.commandName} FakeOrg
`
}

export const cmdScanList: CliSubcommand = {
description: config.description,
hidden: config.hidden,
run
}

async function run(
argv: readonly string[],
importMeta: ImportMeta,
{ parentName }: { parentName: string }
) {
const cli = meow(config.help(parentName, config), {
argv,
description: config.description,
importMeta,
flags: config.flags
})

const orgSlug = cli.input[0]

if (!orgSlug) {
console.error(`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
- Org name as the argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}`)
config.help(parentName, config)
return
}

const apiToken = getDefaultToken()
if (!apiToken) {
throw new AuthError(
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
)
}
const spinnerText = 'Listing scans... \n'
const spinner = new Spinner({ text: spinnerText }).start()
await listFullScans(
orgSlug,
// TODO: refine this object to what we need
{
outputJson: cli.flags['json'],
outputMarkdown: cli.flags['markdown'],
orgSlug,
sort: cli.flags['sort'],
direction: cli.flags['direction'],
per_page: cli.flags['perPage'],
page: cli.flags['page'],
from_time: cli.flags['fromTime'],
until_time: cli.flags['untilTime']
} as {
outputJson: boolean
outputMarkdown: boolean
orgSlug: string
sort: string
direction: string
per_page: number
page: number
from_time: string
until_time: string
},
spinner,
apiToken
)
}
Loading
Loading