From 763f52558045310d5e76f9cc08099501d775d8e8 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Fri, 10 Feb 2023 15:39:11 -0500 Subject: [PATCH] auth-type: gracefully fallback from web Originally `auth-type=web` would gracefully fallback to `auth-type=legacy` if a registry had not yet implemented web. This brings back that behavior. --- lib/utils/auth.js | 54 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/lib/utils/auth.js b/lib/utils/auth.js index 8b9125a1c3ef0..3d7e55e9f1c19 100644 --- a/lib/utils/auth.js +++ b/lib/utils/auth.js @@ -4,6 +4,26 @@ const openUrlPrompt = require('../utils/open-url-prompt.js') const read = require('../utils/read-user-info.js') const otplease = require('../utils/otplease.js') +async function loginCouch (npm, creds, opts) { + const username = await read.username('Username:', creds.username) + const password = await read.password('Password:', creds.password) + return await otplease(npm, opts, (reqOpts) => + profile.loginCouch(username, password, reqOpts) + ) +} + +async function addUserCouch (npm, creds, opts) { + const username = await read.username('Username:', creds.username) + const password = await read.password('Password:', creds.password) + const email = await read.email('Email: (this IS public) ', creds.email) + // npm registry quirk: If you "add" an existing user with their current + // password, it's effectively a login, and if that account has otp you'll + // be prompted for it. + return await otplease(npm, opts, (reqOpts) => + profile.adduserCouch(username, email, password, opts) + ) +} + const adduser = async (npm, { creds, ...opts }) => { const authType = npm.config.get('auth-type') let res @@ -16,17 +36,16 @@ const adduser = async (npm, { creds, ...opts }) => { 'Press ENTER to open in the browser...', emitter ) - }, opts) + }, opts).catch(er => { + if (er.message === 'Web login not supported' && er.code === 'ENYI') { + log.verbose('web add user not supported, trying couch') + return addUserCouch(npm, creds, opts) + } else { + throw er + } + }) } else { - const username = await read.username('Username:', creds.username) - const password = await read.password('Password:', creds.password) - const email = await read.email('Email: (this IS public) ', creds.email) - // npm registry quirk: If you "add" an existing user with their current - // password, it's effectively a login, and if that account has otp you'll - // be prompted for it. - res = await otplease(npm, opts, (reqOpts) => - profile.adduserCouch(username, email, password, opts) - ) + res = addUserCouch(npm, creds, opts) } // We don't know the username if it was a web login, all we can reliably log is scope and registry @@ -52,13 +71,16 @@ const login = async (npm, { creds, ...opts }) => { 'Press ENTER to open in the browser...', emitter ) - }, opts) + }, opts).catch(er => { + if (er.message === 'Web login not supported' && er.code === 'ENYI') { + log.verbose('web login not supported, trying couch') + return loginCouch(npm, creds, opts) + } else { + throw er + } + }) } else { - const username = await read.username('Username:', creds.username) - const password = await read.password('Password:', creds.password) - res = await otplease(npm, opts, (reqOpts) => - profile.loginCouch(username, password, reqOpts) - ) + res = loginCouch(npm, creds, opts) } // We don't know the username if it was a web login, all we can reliably log is scope and registry