diff --git a/README.md b/README.md index 18bcf88e9..647340709 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,13 @@ same major line. Should you need to upgrade to a new major, use an explicit not to lookup on the remote registry for the latest version of the selected package manager. +- `COREPACK_ENABLE_EXPLICIT_VALIDATION_BEFORE_DOWNLOAD` can be set to `0` to + prevent Corepack from asking for validation before downloading software from + the network, or on the contrary set to `1` to force Corepack to ask for + explicit consent. By default, Corepack will ask for explicit consent only when + Corepack is used implicitly (i.e. `corepack pnpm …` won't ask for explicit + consent, `pnpm …` would). + - `COREPACK_ENABLE_NETWORK` can be set to `0` to prevent Corepack from accessing the network (in which case you'll be responsible for hydrating the package manager versions that will be required for the projects you'll run, using diff --git a/mkshims.ts b/mkshims.ts index fde6dacac..dec096ddc 100644 --- a/mkshims.ts +++ b/mkshims.ts @@ -21,6 +21,7 @@ async function main() { const corepackPath = path.join(distDir, `corepack.js`); fs.writeFileSync(corepackPath, [ `#!/usr/bin/env node`, + `process.env.COREPACK_ENABLE_EXPLICIT_VALIDATION_BEFORE_DOWNLOAD??='0'`, `require('./lib/corepack.cjs').runMain(process.argv.slice(2));`, ].join(`\n`)); fs.chmodSync(corepackPath, 0o755); @@ -32,6 +33,7 @@ async function main() { const entryPath = path.join(distDir, `${binaryName}.js`); const entryScript = [ `#!/usr/bin/env node`, + `process.env.COREPACK_ENABLE_EXPLICIT_VALIDATION_BEFORE_DOWNLOAD??='1'`, `require('./lib/corepack.cjs').runMain(['${binaryName}', ...process.argv.slice(2)]);`, ].join(`\n`); diff --git a/sources/httpUtils.ts b/sources/httpUtils.ts index 48d89ed46..a2935c762 100644 --- a/sources/httpUtils.ts +++ b/sources/httpUtils.ts @@ -1,6 +1,8 @@ -import {UsageError} from 'clipanion'; -import {RequestOptions} from 'https'; -import {IncomingMessage, ClientRequest} from 'http'; +import {UsageError} from 'clipanion'; +import {once} from 'events'; +import type {RequestOptions} from 'https'; +import type {IncomingMessage, ClientRequest} from 'http'; +import {stderr, stdin} from 'process'; export async function fetchUrlStream(url: string, options: RequestOptions = {}) { if (process.env.COREPACK_ENABLE_NETWORK === `0`) @@ -12,7 +14,19 @@ export async function fetchUrlStream(url: string, options: RequestOptions = {}) const proxyAgent = new ProxyAgent(); - console.log(`Corepack: Fetching ${url}...`); + if (process.env.COREPACK_ENABLE_EXPLICIT_VALIDATION_BEFORE_DOWNLOAD !== `0`) { + console.error(`Corepack is about to download ${url}.`); + stderr.write(`\nDo you want to continue? [Y/n] `); + stdin.resume(); + const chars = await once(stdin, `data`); + stdin.pause(); + if ( + chars[0][0] === 0x6e || // n + chars[0][0] === 0x4e // N + ) { + throw new UsageError(`Aborted by the user`); + } + } return new Promise((resolve, reject) => { const createRequest = (url: string) => {