1const read = require('read') 2const userValidate = require('npm-user-validate') 3const log = require('./log-shim.js') 4 5exports.otp = readOTP 6exports.password = readPassword 7exports.username = readUsername 8exports.email = readEmail 9 10const otpPrompt = `This command requires a one-time password (OTP) from your authenticator app. 11Enter one below. You can also pass one on the command line by appending --otp=123456. 12For more information, see: 13https://docs.npmjs.com/getting-started/using-two-factor-authentication 14Enter OTP: ` 15const passwordPrompt = 'npm password: ' 16const usernamePrompt = 'npm username: ' 17const emailPrompt = 'email (this IS public): ' 18 19function readWithProgress (opts) { 20 log.clearProgress() 21 return read(opts).finally(() => log.showProgress()) 22} 23 24function readOTP (msg = otpPrompt, otp, isRetry) { 25 if (isRetry && otp && /^[\d ]+$|^[A-Fa-f0-9]{64,64}$/.test(otp)) { 26 return otp.replace(/\s+/g, '') 27 } 28 29 return readWithProgress({ prompt: msg, default: otp || '' }) 30 .then((rOtp) => readOTP(msg, rOtp, true)) 31} 32 33function readPassword (msg = passwordPrompt, password, isRetry) { 34 if (isRetry && password) { 35 return password 36 } 37 38 return readWithProgress({ prompt: msg, silent: true, default: password || '' }) 39 .then((rPassword) => readPassword(msg, rPassword, true)) 40} 41 42function readUsername (msg = usernamePrompt, username, isRetry) { 43 if (isRetry && username) { 44 const error = userValidate.username(username) 45 if (error) { 46 log.warn(error.message) 47 } else { 48 return Promise.resolve(username.trim()) 49 } 50 } 51 52 return readWithProgress({ prompt: msg, default: username || '' }) 53 .then((rUsername) => readUsername(msg, rUsername, true)) 54} 55 56function readEmail (msg = emailPrompt, email, isRetry) { 57 if (isRetry && email) { 58 const error = userValidate.email(email) 59 if (error) { 60 log.warn(error.message) 61 } else { 62 return email.trim() 63 } 64 } 65 66 return readWithProgress({ prompt: msg, default: email || '' }) 67 .then((username) => readEmail(msg, username, true)) 68} 69