Skip to content

Commit 65dabc3

Browse files
committed
Validate apiToken on input and threatfeed fixes
1 parent c176e82 commit 65dabc3

File tree

115 files changed

+1080
-735
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+1080
-735
lines changed

src/commands/analytics/cmd-analytics.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,42 @@ describe('socket analytics', async () => {
6060
cmdit(
6161
['analytics', '--dry-run', '--config', '{}'],
6262
'should require args with just dry-run',
63+
async cmd => {
64+
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
65+
expect(stdout).toMatchInlineSnapshot(`""`)
66+
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
67+
"
68+
_____ _ _ /---------------
69+
| __|___ ___| |_ ___| |_ | Socket.dev CLI ver <redacted>
70+
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
71+
|_____|___|___|_,_|___|_|.dev | Command: \`socket analytics\`, cwd: <redacted>
72+
73+
\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[1m\\x1b[37m Input error: \\x1b[39m\\x1b[22m\\x1b[49m \\x1b[1mPlease review the input requirements and try again\\x1b[22m:
74+
75+
- Scope must be "repo" or "org" (\\x1b[32mok\\x1b[39m)
76+
77+
- The time filter must either be 7, 30 or 90 (\\x1b[32mok\\x1b[39m)
78+
79+
- You need to be logged in to use this command. See \`socket login\`. (\\x1b[31mmissing API token\\x1b[39m)"
80+
`)
81+
82+
expect(code, 'dry-run should exit with code 2 if missing input').toBe(2)
83+
}
84+
)
85+
86+
cmdit(
87+
[
88+
'analytics',
89+
'boo',
90+
'--scope',
91+
'org',
92+
'--repo',
93+
'bar',
94+
'--dry-run',
95+
'--config',
96+
'{"apiToken":"anything"}'
97+
],
98+
'should require args with just dry-run',
6399
async cmd => {
64100
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
65101
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)

src/commands/analytics/cmd-analytics.ts

Lines changed: 61 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
import { stripIndents } from 'common-tags'
2-
import colors from 'yoctocolors-cjs'
1+
import assert from 'node:assert'
32

43
import { logger } from '@socketsecurity/registry/lib/logger'
54

65
import { displayAnalytics } from './display-analytics'
76
import constants from '../../constants'
87
import { commonFlags, outputFlags } from '../../flags'
8+
import { handleBadInput } from '../../utils/handle-bad-input'
99
import { meowOrExit } from '../../utils/meow-with-subcommands'
1010
import { getFlagListOutput } from '../../utils/output-formatting'
11+
import { getDefaultToken } from '../../utils/sdk'
1112

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

@@ -84,34 +85,54 @@ async function run(
8485

8586
const { file, json, markdown, repo, scope, time } = cli.flags
8687

87-
const badScope = scope !== 'org' && scope !== 'repo'
88-
const badTime = time !== 7 && time !== 30 && time !== 90
89-
const badRepo = scope === 'repo' && !repo
90-
const badFile = file !== '-' && !json && !markdown
91-
const badFlags = json && markdown
88+
const apiToken = getDefaultToken()
9289

93-
if (badScope || badTime || badRepo || badFile || badFlags) {
94-
// Use exit status of 2 to indicate incorrect usage, generally invalid
95-
// options or missing arguments.
96-
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
97-
process.exitCode = 2
98-
logger.fail(
99-
stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:
100-
101-
- Scope must be "repo" or "org" ${badScope ? colors.red('(bad!)') : colors.green('(ok)')}
102-
103-
- The time filter must either be 7, 30 or 90 ${badTime ? colors.red('(bad!)') : colors.green('(ok)')}
104-
105-
${scope === 'repo' ? `- Repository name using --repo when scope is "repo" ${badRepo ? colors.red('(bad!)') : colors.green('(ok)')}` : ''}
106-
107-
${badFlags ? `- The \`--json\` and \`--markdown\` flags can not be used at the same time ${badFlags ? colors.red('(bad!)') : colors.green('(ok)')}` : ''}
108-
109-
${badFile ? `- The \`--file\` flag is only valid when using \`--json\` or \`--markdown\` ${badFile ? colors.red('(bad!)') : colors.green('(ok)')}` : ''}
110-
`
111-
.split('\n')
112-
.filter(s => !!s.trim())
113-
.join('\n')
114-
)
90+
const wasBadInput = handleBadInput(
91+
{
92+
test: scope === 'org' || scope === 'repo',
93+
message: 'Scope must be "repo" or "org"',
94+
pass: 'ok',
95+
fail: 'bad'
96+
},
97+
{
98+
test: time === 7 || time === 30 || time === 90,
99+
message: 'The time filter must either be 7, 30 or 90',
100+
pass: 'ok',
101+
fail: 'bad'
102+
},
103+
{
104+
nook: true,
105+
test: scope === 'org' || repo,
106+
message: 'When scope=repo, repo name should be set through --repo',
107+
pass: 'ok',
108+
fail: 'missing'
109+
},
110+
{
111+
nook: true,
112+
test: file === '-' || json || markdown,
113+
message:
114+
'The `--file` flag is only valid when using `--json` or `--markdown`',
115+
pass: 'ok',
116+
fail: 'bad'
117+
},
118+
{
119+
nook: true,
120+
test: !json || !markdown,
121+
message:
122+
'The `--json` and `--markdown` flags can not be used at the same time',
123+
pass: 'ok',
124+
fail: 'bad'
125+
},
126+
{
127+
nook: true,
128+
test: apiToken,
129+
message:
130+
'You need to be logged in to use this command. See `socket login`.',
131+
pass: 'ok',
132+
fail: 'missing API token'
133+
}
134+
)
135+
if (wasBadInput) {
115136
return
116137
}
117138

@@ -120,6 +141,9 @@ async function run(
120141
return
121142
}
122143

144+
assert(assertScope(scope))
145+
assert(assertTime(time))
146+
123147
return await displayAnalytics({
124148
scope,
125149
time,
@@ -128,3 +152,11 @@ async function run(
128152
filePath: String(file || '')
129153
})
130154
}
155+
156+
function assertScope(scope: unknown): scope is 'org' | 'repo' {
157+
return scope === 'org' || scope === 'repo'
158+
}
159+
160+
function assertTime(time: unknown): time is 7 | 30 | 90 {
161+
return time === 7 || time === 30 || time === 90
162+
}

src/commands/audit-log/cmd-audit-log.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,23 @@ describe('socket audit-log', async () => {
6969
7070
\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[1m\\x1b[37m Input error: \\x1b[39m\\x1b[22m\\x1b[49m \\x1b[1mPlease review the input requirements and try again\\x1b[22m:
7171
72-
- Org name should be the first arg (\\x1b[31mmissing\\x1b[39m)"
72+
- Org name should be the first arg (\\x1b[31mmissing\\x1b[39m)
73+
74+
- You need to be logged in to use this command. See \`socket login\`. (\\x1b[31mmissing API token\\x1b[39m)"
7375
`)
7476

7577
expect(code, 'dry-run should exit with code 2 if missing input').toBe(2)
7678
}
7779
)
7880

7981
cmdit(
80-
['audit-log', 'fakeorg', '--dry-run', '--config', '{}'],
82+
[
83+
'audit-log',
84+
'fakeorg',
85+
'--dry-run',
86+
'--config',
87+
'{"apiToken":"anything"}'
88+
],
8189
'should require args with just dry-run',
8290
async cmd => {
8391
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)

src/commands/audit-log/cmd-audit-log.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { getConfigValue } from '../../utils/config'
77
import { handleBadInput } from '../../utils/handle-bad-input'
88
import { meowOrExit } from '../../utils/meow-with-subcommands'
99
import { getFlagListOutput } from '../../utils/output-formatting'
10+
import { getDefaultToken } from '../../utils/sdk'
1011

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

@@ -77,12 +78,32 @@ async function run(
7778
const defaultOrgSlug = getConfigValue('defaultOrg')
7879
const orgSlug = defaultOrgSlug || cli.input[0] || ''
7980

80-
const wasBadInput = handleBadInput({
81-
test: orgSlug,
82-
message: 'Org name should be the first arg',
83-
pass: 'ok',
84-
fail: 'missing'
85-
})
81+
const apiToken = getDefaultToken()
82+
83+
const wasBadInput = handleBadInput(
84+
{
85+
test: orgSlug,
86+
message: 'Org name should be the first arg',
87+
pass: 'ok',
88+
fail: 'missing'
89+
},
90+
{
91+
nook: true,
92+
test: apiToken,
93+
message:
94+
'You need to be logged in to use this command. See `socket login`.',
95+
pass: 'ok',
96+
fail: 'missing API token'
97+
},
98+
{
99+
nook: true,
100+
test: !json || !markdown,
101+
message:
102+
'The `--json` and `--markdown` flags can not be used at the same time',
103+
pass: 'ok',
104+
fail: 'bad'
105+
}
106+
)
86107
if (wasBadInput) {
87108
return
88109
}

src/commands/audit-log/fetch-audit-log.ts

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import constants from '../../constants'
22
import { handleApiCall, handleUnsuccessfulApiResponse } from '../../utils/api'
3-
import { AuthError } from '../../utils/errors'
4-
import { getDefaultToken, setupSdk } from '../../utils/sdk'
3+
import { setupSdk } from '../../utils/sdk'
54

65
import type { SocketSdkReturnType } from '@socketsecurity/sdk'
76

@@ -18,44 +17,13 @@ export async function fetchAuditLog({
1817
perPage: number
1918
logType: string
2019
}): Promise<SocketSdkReturnType<'getAuditLogEvents'>['data'] | void> {
21-
const apiToken = getDefaultToken()
22-
if (!apiToken) {
23-
throw new AuthError(
24-
'User must be authenticated to run this command. To log in, run the command `socket login` and enter your API key.'
25-
)
26-
}
27-
28-
return await fetchAuditLogWithToken(apiToken, {
29-
logType,
30-
orgSlug,
31-
outputKind,
32-
page,
33-
perPage
34-
})
35-
}
20+
const sockSdk = await setupSdk()
3621

37-
export async function fetchAuditLogWithToken(
38-
apiToken: string,
39-
{
40-
logType,
41-
orgSlug,
42-
outputKind,
43-
page,
44-
perPage
45-
}: {
46-
outputKind: 'json' | 'markdown' | 'print'
47-
orgSlug: string
48-
page: number
49-
perPage: number
50-
logType: string
51-
}
52-
): Promise<SocketSdkReturnType<'getAuditLogEvents'>['data'] | void> {
5322
// Lazily access constants.spinner.
5423
const { spinner } = constants
5524

5625
spinner.start(`Looking up audit log for ${orgSlug}`)
5726

58-
const sockSdk = await setupSdk(apiToken)
5927
const result = await handleApiCall(
6028
sockSdk.getAuditLogEvents(orgSlug, {
6129
// I'm not sure this is used at all.

src/commands/cdxgen/cmd-cdxgen.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ describe('socket cdxgen', async () => {
8686

8787
// cdxgen does not support --dry-run
8888
// cmdit(
89-
// ['cdxgen', '--help', '--config', '{}'],
89+
// ['cdxgen', '--help', '--config', '{"apiToken":"anything"}'],
9090
// 'should require args with just dry-run',
9191
// async cmd => {
9292
// const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)

src/commands/config/cmd-config-auto.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,22 @@ async function run(
6565
const { json, markdown } = cli.flags
6666
const [key = ''] = cli.input
6767

68-
const wasBadInput = handleBadInput({
69-
test: supportedConfigKeys.has(key as keyof LocalConfig) && key !== 'test',
70-
message: 'Config key should be the first arg',
71-
pass: 'ok',
72-
fail: key ? 'invalid config key' : 'missing'
73-
})
68+
const wasBadInput = handleBadInput(
69+
{
70+
test: supportedConfigKeys.has(key as keyof LocalConfig) && key !== 'test',
71+
message: 'Config key should be the first arg',
72+
pass: 'ok',
73+
fail: key ? 'invalid config key' : 'missing'
74+
},
75+
{
76+
nook: true,
77+
test: !json || !markdown,
78+
message:
79+
'The `--json` and `--markdown` flags can not be used at the same time',
80+
pass: 'ok',
81+
fail: 'bad'
82+
}
83+
)
7484
if (wasBadInput) {
7585
return
7686
}

src/commands/config/cmd-config-get.test.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,14 @@ describe('socket config get', async () => {
7979
)
8080

8181
cmdit(
82-
['config', 'test', 'test', '--dry-run', '--config', '{}'],
82+
[
83+
'config',
84+
'test',
85+
'test',
86+
'--dry-run',
87+
'--config',
88+
'{"apiToken":"anything"}'
89+
],
8390
'should require args with just dry-run',
8491
async cmd => {
8592
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)

src/commands/config/cmd-config-get.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,22 @@ async function run(
6060
const { json, markdown } = cli.flags
6161
const [key = ''] = cli.input
6262

63-
const wasBadInput = handleBadInput({
64-
test: supportedConfigKeys.has(key as keyof LocalConfig) || key === 'test',
65-
message: 'Config key should be the first arg',
66-
pass: 'ok',
67-
fail: key ? 'invalid config key' : 'missing'
68-
})
63+
const wasBadInput = handleBadInput(
64+
{
65+
test: supportedConfigKeys.has(key as keyof LocalConfig) || key === 'test',
66+
message: 'Config key should be the first arg',
67+
pass: 'ok',
68+
fail: key ? 'invalid config key' : 'missing'
69+
},
70+
{
71+
nook: true,
72+
test: !json || !markdown,
73+
message:
74+
'The `--json` and `--markdown` flags can not be used at the same time',
75+
pass: 'ok',
76+
fail: 'bad'
77+
}
78+
)
6979
if (wasBadInput) {
7080
return
7181
}

src/commands/config/cmd-config-list.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('socket config get', async () => {
5858
)
5959

6060
cmdit(
61-
['config', 'list', '--dry-run', '--config', '{}'],
61+
['config', 'list', '--dry-run', '--config', '{"apiToken":"anything"}'],
6262
'should require args with just dry-run',
6363
async cmd => {
6464
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)

0 commit comments

Comments
 (0)