Skip to content

Commit cdc4acb

Browse files
authoredAug 2, 2022
fix: cancel opener promise if web login fails (#57)
1 parent d2076fb commit cdc4acb

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed
 

‎lib/index.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const webAuth = (opener, opts, body) => {
5656
const { hostname } = opts
5757
body.hostname = hostname || os.hostname()
5858
const target = '/-/v1/login'
59+
const doneEmitter = new EventEmitter()
5960
return fetch(target, {
6061
...opts,
6162
method: 'POST',
@@ -75,8 +76,6 @@ const webAuth = (opener, opts, body) => {
7576
}).then(({ doneUrl, loginUrl }) => {
7677
log.verbose('web auth', 'opening url pair')
7778

78-
const doneEmitter = new EventEmitter()
79-
8079
const openPromise = opener(loginUrl, doneEmitter)
8180
const webAuthCheckPromise = webAuthCheckLogin(doneUrl, { ...opts, cache: false })
8281
.then(authResult => {
@@ -93,6 +92,9 @@ const webAuth = (opener, opts, body) => {
9392
([, authResult]) => authResult
9493
)
9594
}).catch(er => {
95+
// cancel open prompt if it's present
96+
doneEmitter.emit('abort')
97+
9698
if ((er.statusCode >= 400 && er.statusCode <= 499) || er.statusCode === 500) {
9799
throw new WebLoginNotSupported('POST', {
98100
status: er.statusCode,

‎test/index.js

+43-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ test('get', t => {
1616
return [auth ? 200 : 401, '', {}]
1717
})
1818
return profile.get().then(result => {
19-
t.fail('GET w/o auth should fail')
19+
return t.fail('GET w/o auth should fail')
2020
}, err => {
2121
t.equal(err.code, 'E401', 'auth errors are passed through')
2222
}).then(() => {
@@ -27,7 +27,7 @@ test('get', t => {
2727
})
2828
return profile.get({ '//registry.npmjs.org/:_authToken': 'deadbeef' })
2929
}).then(result => {
30-
t.match(result, { auth: 'bearer' })
30+
return t.match(result, { auth: 'bearer' })
3131
}).then(() => {
3232
srv.get(getUrl).reply(function () {
3333
const auth = this.req.headers.authorization
@@ -46,7 +46,7 @@ test('get', t => {
4646
'//registry.npmjs.org/:_password': Buffer.from('123', 'utf8').toString('base64'),
4747
})
4848
}).then(result => {
49-
t.match(result, { auth: 'basic' })
49+
return t.match(result, { auth: 'basic' })
5050
}).then(() => {
5151
srv.get(getUrl).reply(function () {
5252
const auth = this.req.headers.authorization
@@ -60,7 +60,7 @@ test('get', t => {
6060
'//registry.npmjs.org/:_authToken': 'deadbeef',
6161
})
6262
}).then(result => {
63-
t.match(result, { auth: 'bearer', otp: true })
63+
return t.match(result, { auth: 'bearer', otp: true })
6464
})
6565
// with otp, with token, with basic
6666
// prob should make w/o token 401
@@ -76,7 +76,7 @@ test('set', t => {
7676
github: 'zkat',
7777
email: '',
7878
}).then(json => {
79-
t.same(json, prof, 'got the profile data in return')
79+
return t.same(json, prof, 'got the profile data in return')
8080
})
8181
})
8282

@@ -125,6 +125,42 @@ test('login fallback to couch', t => {
125125
})
126126
})
127127

128+
test('login fallback to couch when web login fails cancels opener promise', t => {
129+
const loginUrl = 'https://www.npmjs.com/login?next=/login/cli/123'
130+
tnock(t, registry)
131+
.put('/-/user/org.couchdb.user:blerp')
132+
.reply(201, {
133+
ok: true,
134+
})
135+
.post('/-/v1/login')
136+
.reply(200, {
137+
loginUrl,
138+
doneUrl: 'https://registry.npmjs.org:443/-/v1/done?sessionId=123',
139+
})
140+
.get('/-/v1/done?sessionId=123')
141+
.reply(404, { error: 'Not found' })
142+
143+
let cancelled = false
144+
const opener = (url, doneEmitter) => {
145+
t.equal(url, loginUrl)
146+
doneEmitter.on('abort', () => {
147+
cancelled = true
148+
})
149+
}
150+
151+
const prompter = creds => Promise.resolve({
152+
username: 'blerp',
153+
password: 'prelb',
154+
email: 'blerp@blerp.blerp',
155+
})
156+
return t.resolveMatch(profile.login(opener, prompter), {
157+
ok: true,
158+
username: 'blerp',
159+
}).then(() => {
160+
return t.equal(cancelled, true)
161+
})
162+
})
163+
128164
test('adduserCouch happy path', t => {
129165
tnock(t, registry)
130166
.put('/-/user/org.couchdb.user:blerp')
@@ -222,7 +258,7 @@ test('listTokens multipage', t => {
222258
urls: {},
223259
})
224260
return profile.listTokens().then(tok => {
225-
t.same(
261+
return t.same(
226262
tok,
227263
tokens1.concat(tokens2).concat(tokens3),
228264
'supports multi-URL token requests and concats them'
@@ -233,7 +269,7 @@ test('listTokens multipage', t => {
233269
test('removeToken', t => {
234270
tnock(t, registry).delete('/-/npm/v1/tokens/token/deadbeef').reply(200)
235271
return profile.removeToken('deadbeef').then(ret => {
236-
t.equal(ret, null, 'null return value on success')
272+
return t.equal(ret, null, 'null return value on success')
237273
})
238274
})
239275

0 commit comments

Comments
 (0)
Please sign in to comment.