From 346a34260b5fba7de62717135f3e083cc4820853 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Wed, 4 Oct 2017 01:04:25 -0700 Subject: publish: Prompt for OTP when required and we have a TTY --- doc/cli/npm-publish.md | 8 +++++++- lib/publish.js | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/cli/npm-publish.md b/doc/cli/npm-publish.md index 892786b61..7e173ec00 100644 --- a/doc/cli/npm-publish.md +++ b/doc/cli/npm-publish.md @@ -4,7 +4,7 @@ npm-publish(1) -- Publish a package ## SYNOPSIS - npm publish [|] [--tag ] [--access ] + npm publish [|] [--tag ] [--access ] [--otp otpcode] Publishes '.' if no argument supplied Sets tag 'latest' if no --tag specified @@ -41,6 +41,11 @@ specifying a different default registry or using a `npm-scope(7)` in the name If you don't have a paid account, you must publish with `--access public` to publish scoped packages. +* `[--otp ]` + If you have two-factor authentication enabled in `auth-and-writes` mode + then you can provide a code from your authenticator with this. If you + don't include this and you're running from a TTY then you'll be prompted. + Fails if the package name and version combination already exists in the specified registry. @@ -65,3 +70,4 @@ packs them into a tarball to be uploaded to the registry. * npm-deprecate(1) * npm-dist-tag(1) * npm-pack(1) +* npm-profile(1) diff --git a/lib/publish.js b/lib/publish.js index 5d99bfd08..bf60e1d5a 100644 --- a/lib/publish.js +++ b/lib/publish.js @@ -21,6 +21,7 @@ const readJson = BB.promisify(require('read-package-json')) const semver = require('semver') const statAsync = BB.promisify(require('graceful-fs').stat) const writeStreamAtomic = require('fs-write-stream-atomic') +const readUserInfo = require('./utils/read-user-info.js') publish.usage = 'npm publish [|] [--tag ] [--access ]' + "\n\nPublishes '.' if no argument supplied" + @@ -199,5 +200,13 @@ function upload (arg, pkg, isRetry, cached) { throw err } }) + }).catch((err) => { + if (err.code !== 'EOTP' && !(err.code === 'E401' && /one-time pass/.test(err.message))) throw err + // we prompt on stdout and read answers from stdin, so they need to be ttys. + if (!process.stdin.isTTY || !process.stdout.isTTY) throw err + return readUserInfo.otp('Enter OTP: ').then((otp) => { + npm.config.set('otp', otp) + return upload(arg, pkg, isRetry, cached) + }) }) } -- cgit v1.2.3