Skip to content

Commit

Permalink
fix: gracefully fallback from auth-type=web (#6158)
Browse files Browse the repository at this point in the history
Originally `auth-type=web` would gracefully fallback to
`auth-type=legacy` if a registry had not yet implemented
web. This brings back that behavior.
  • Loading branch information
MylesBorins authored Feb 14, 2023
1 parent 8800138 commit 53f75a4
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 20 deletions.
62 changes: 42 additions & 20 deletions lib/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,27 @@ const adduser = async (npm, { creds, ...opts }) => {
const authType = npm.config.get('auth-type')
let res
if (authType === 'web') {
res = await profile.adduserWeb((url, emitter) => {
openUrlPrompt(
npm,
url,
'Create your account at',
'Press ENTER to open in the browser...',
emitter
)
}, opts)
} else {
try {
res = await profile.adduserWeb((url, emitter) => {
openUrlPrompt(
npm,
url,
'Create your account at',
'Press ENTER to open in the browser...',
emitter
)
}, opts)
} catch (err) {
if (err.code === 'ENYI') {
log.verbose('web add user not supported, trying couch')
} else {
throw err
}
}
}

// auth type !== web or ENYI error w/ web adduser
if (!res) {
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)
Expand All @@ -44,16 +55,27 @@ const login = async (npm, { creds, ...opts }) => {
const authType = npm.config.get('auth-type')
let res
if (authType === 'web') {
res = await profile.loginWeb((url, emitter) => {
openUrlPrompt(
npm,
url,
'Login at',
'Press ENTER to open in the browser...',
emitter
)
}, opts)
} else {
try {
res = await profile.loginWeb((url, emitter) => {
openUrlPrompt(
npm,
url,
'Login at',
'Press ENTER to open in the browser...',
emitter
)
}, opts)
} catch (err) {
if (err.code === 'ENYI') {
log.verbose('web login not supported, trying couch')
} else {
throw err
}
}
}

// auth type !== web or ENYI error w/ web login
if (!res) {
const username = await read.username('Username:', creds.username)
const password = await read.password('Password:', creds.password)
res = await otplease(npm, opts, (reqOpts) =>
Expand Down
44 changes: 44 additions & 0 deletions test/lib/commands/adduser.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,49 @@ t.test('web', t => {
'//registry.npmjs.org/:_authToken': 'npm_test-token',
})
})

t.test('server error', async t => {
const { npm } = await loadMockNpm(t, {
config: { 'auth-type': 'web' },
})
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.nock.post(registry.fullPath('/-/v1/login'))
.reply(503, {})
await t.rejects(
npm.exec('adduser', []),
{ message: /503/ }
)
})

t.test('fallback', async t => {
const stdin = new stream.PassThrough()
stdin.write('test-user\n')
stdin.write('test-password\n')
stdin.write('test-email@npmjs.org\n')
mockGlobals(t, {
'process.stdin': stdin,
'process.stdout': new stream.PassThrough(), // to quiet readline
}, { replace: true })
const { npm } = await loadMockNpm(t, {
config: { 'auth-type': 'web' },
})
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.nock.post(registry.fullPath('/-/v1/login'))
.reply(404, {})
registry.couchadduser({
username: 'test-user',
password: 'test-password',
email: 'test-email@npmjs.org',
token: 'npm_test-token',
})
await npm.exec('adduser', [])
t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token')
})
t.end()
})
40 changes: 40 additions & 0 deletions test/lib/commands/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,45 @@ t.test('web', t => {
'//registry.npmjs.org/:_authToken': 'npm_test-token',
})
})
t.test('server error', async t => {
const { npm } = await loadMockNpm(t, {
config: { 'auth-type': 'web' },
})
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.nock.post(registry.fullPath('/-/v1/login'))
.reply(503, {})
await t.rejects(
npm.exec('login', []),
{ message: /503/ }
)
})
t.test('fallback', async t => {
const stdin = new stream.PassThrough()
stdin.write('test-user\n')
stdin.write('test-password\n')
mockGlobals(t, {
'process.stdin': stdin,
'process.stdout': new stream.PassThrough(), // to quiet readline
}, { replace: true })
const { npm } = await loadMockNpm(t, {
config: { 'auth-type': 'web' },
})
const registry = new MockRegistry({
tap: t,
registry: npm.config.get('registry'),
})
registry.nock.post(registry.fullPath('/-/v1/login'))
.reply(404, {})
registry.couchlogin({
username: 'test-user',
password: 'test-password',
token: 'npm_test-token',
})
await npm.exec('login', [])
t.same(npm.config.get('//registry.npmjs.org/:_authToken'), 'npm_test-token')
})
t.end()
})

0 comments on commit 53f75a4

Please sign in to comment.