Skip to content

Commit 87faa04

Browse files
committed
improvements
1 parent d6ca55a commit 87faa04

File tree

6 files changed

+194
-77
lines changed

6 files changed

+194
-77
lines changed

lib/commands/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from './npm/index.js'
44
export * from './npx/index.js'
55
export * from './login/index.js'
66
export * from './logout/index.js'
7+
export * from './wrapper/index.js'

lib/commands/wrapper/index.js

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/* eslint-disable no-console */
2+
import { exec } from 'child_process'
3+
import fs from 'fs'
4+
import homedir from 'os'
5+
import readline from 'readline'
6+
7+
import meow from 'meow'
8+
9+
import { commandFlags } from '../../flags/index.js'
10+
import { printFlagList } from '../../utils/formatting.js'
11+
12+
const BASH_FILE = `${homedir.homedir()}/.bashrc`
13+
const ZSH_BASH_FILE = `${homedir.homedir()}/.zshrc`
14+
15+
/** @type {import('../../utils/meow-with-subcommands').CliSubcommand} */
16+
export const wrapper = {
17+
description: 'Enable or disable the Socket npm/npx wrapper',
18+
async run (argv, importMeta, { parentName }) {
19+
const name = parentName + ' wrapper'
20+
21+
setupCommand(name, wrapper.description, argv, importMeta)
22+
}
23+
}
24+
25+
/**
26+
* @param {string} name
27+
* @param {string} description
28+
* @param {readonly string[]} argv
29+
* @param {ImportMeta} importMeta
30+
* @returns {void}
31+
*/
32+
function setupCommand (name, description, argv, importMeta) {
33+
const flags = commandFlags
34+
35+
const cli = meow(`
36+
Usage
37+
$ ${name} <flag>
38+
39+
Options
40+
${printFlagList(flags, 6)}
41+
42+
Examples
43+
$ ${name} --enable
44+
$ ${name} --disable
45+
`, {
46+
argv,
47+
description,
48+
importMeta,
49+
flags
50+
})
51+
52+
const { enable, disable } = cli.flags
53+
54+
if (argv[0] === '--postinstall') {
55+
installSafeNpm(`The Socket CLI is now successfully installed! 🎉
56+
57+
To better protect yourself against supply-chain attacks, our "safe npm" wrapper can warn you about malicious packages whenever you run 'npm install'.
58+
59+
Do you want to install "safe npm" (this will create an alias to the socket-npm command)? (y/n)`)
60+
61+
return
62+
}
63+
64+
if (!enable && !disable) {
65+
cli.showHelp()
66+
return
67+
}
68+
69+
if (enable) {
70+
if (fs.existsSync(BASH_FILE)) {
71+
addAlias(BASH_FILE)
72+
} else if (fs.existsSync(ZSH_BASH_FILE)) {
73+
addAlias(ZSH_BASH_FILE)
74+
} else {
75+
console.error('There was an issue setting up the alias in your bash profile')
76+
}
77+
} else if (disable) {
78+
if (fs.existsSync(BASH_FILE)) {
79+
removeAlias(BASH_FILE)
80+
} else if (fs.existsSync(ZSH_BASH_FILE)) {
81+
removeAlias(ZSH_BASH_FILE)
82+
} else {
83+
console.error('There was an issue setting up the alias in your bash profile')
84+
}
85+
}
86+
87+
return
88+
}
89+
90+
/**
91+
* @param {string} query
92+
* @returns {void}
93+
*/
94+
const installSafeNpm = (query) => {
95+
console.log(`
96+
_____ _ _
97+
| __|___ ___| |_ ___| |_
98+
|__ | . | _| '_| -_| _|
99+
|_____|___|___|_,_|___|_|
100+
101+
`)
102+
103+
const rl = readline.createInterface({
104+
input: process.stdin,
105+
output: process.stdout,
106+
})
107+
return askQuestion(rl, query)
108+
}
109+
110+
/**
111+
* @param {any} rl
112+
* @param {string} query
113+
* @returns {void}
114+
*/
115+
const askQuestion = (rl, query) => {
116+
rl.question(query, (/** @type {string} */ ans) => {
117+
if (ans.toLowerCase() === 'y') {
118+
try {
119+
if (fs.existsSync(BASH_FILE)) {
120+
addAlias(BASH_FILE)
121+
} else if (fs.existsSync(ZSH_BASH_FILE)) {
122+
addAlias(ZSH_BASH_FILE)
123+
}
124+
} catch (e) {
125+
throw new Error(`There was an issue setting up the alias: ${e}`)
126+
}
127+
rl.close()
128+
} else if (ans.toLowerCase() !== 'n') {
129+
askQuestion(rl, 'Incorrect input: please enter either y (yes) or n (no): ')
130+
} else {
131+
rl.close()
132+
}
133+
})
134+
}
135+
136+
/**
137+
* @param {string} file
138+
* @returns {void}
139+
*/
140+
const addAlias = (file) => {
141+
exec(`echo "alias npm='socket npm'\nalias npx='socket npx'" >> ${file}`, (err, _, stderr) => {
142+
if (err) {
143+
return new Error(`There was an error setting up the alias: ${stderr}`)
144+
}
145+
console.log(`
146+
The alias was added to ${file}. Running 'npm install' will now be wrapped in Socket's "safe npm" 🎉
147+
If you want to disable it at any time, run \`socket wrapper --disable\`
148+
`)
149+
})
150+
}
151+
152+
/**
153+
* @param {string} file
154+
* @returns {void}
155+
*/
156+
const removeAlias = (file) => {
157+
return fs.readFile(file, 'utf8', function (err, data) {
158+
if (err) {
159+
console.error(`There was an error removing the alias: ${err}`)
160+
return
161+
}
162+
const linesWithoutSocketAlias = data.split('\n').filter(l => l !== "alias npm='socket npm'" && l !== "alias npx='socket npx'")
163+
164+
const updatedFileContent = linesWithoutSocketAlias.join('\n')
165+
166+
fs.writeFile(file, updatedFileContent, function (err) {
167+
if (err) {
168+
console.log(err)
169+
return
170+
} else {
171+
console.log(`
172+
The alias was removed from ${file}. Running 'npm install' will now run the standard npm command.
173+
`)
174+
}
175+
})
176+
})
177+
}

lib/flags/command.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { prepareFlags } from '../utils/flags.js'
2+
3+
export const commandFlags = prepareFlags({
4+
enable: {
5+
type: 'boolean',
6+
default: false,
7+
description: 'Enables the Socket npm/npx wrapper',
8+
},
9+
disable: {
10+
type: 'boolean',
11+
default: false,
12+
description: 'Disables the Socket npm/npx wrapper',
13+
}
14+
})

lib/flags/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { outputFlags } from './output.js'
22
export { validationFlags } from './validation.js'
3+
export { commandFlags } from './command.js'

lib/utils/safe-npm.js

Lines changed: 0 additions & 76 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"test:unit": "c8 --reporter=lcov --reporter text node --test",
4242
"test-ci": "run-s test:*",
4343
"test": "run-s check test:*",
44-
"postinstall": "node lib/utils/safe-npm.js"
44+
"postinstall": "node ./cli.js wrapper --postinstall"
4545
},
4646
"devDependencies": {
4747
"@socketsecurity/eslint-config": "^3.0.1",

0 commit comments

Comments
 (0)