Skip to content

Commit

Permalink
feat: updated the way we handle identity fetching
Browse files Browse the repository at this point in the history
- added get-identity.js file; to do the actual fetching
- updated commands that required whoami.js
- lib/stars.js: small refactoring of promise chain
- lib/star.js: fixed missing comma
  • Loading branch information
Michael Perrotte committed Mar 5, 2020
1 parent 5a36ee2 commit 924d85b
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 61 deletions.
8 changes: 3 additions & 5 deletions lib/access.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const { prefix } = npm
const { promisify } = require('util')
const readPackageJson = promisify(require('read-package-json'))
const usage = require('./utils/usage.js')
const whoami = require('./whoami.js')
const getIdentity = require('./utils/get-identity')

module.exports = access

Expand Down Expand Up @@ -139,11 +139,9 @@ access['2fa-not-required'] = access.tfaNotRequired = ([pkg], opts) => {
access['ls-packages'] = access.lsPackages = ([owner], opts) => {
const getOwnerPromise = (owner)
? Promise.resolve(owner)
: new Promise((resolve, reject) => {
whoami([], true, (err) => err ? reject(err) : resolve())
})
: getIdentity(opts)

return getOwnerPromise.then(owner => {
return getOwnerPromise(owner).then(owner => {
return libaccess.lsPackages(owner, opts)
}).then(pkgs => {
// TODO - print these out nicely (breaking change)
Expand Down
4 changes: 2 additions & 2 deletions lib/deprecate.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const fetch = require('npm-registry-fetch')
const otplease = require('./utils/otplease.js')
const npa = require('npm-package-arg')
const semver = require('semver')
const whoami = require('./whoami.js')
const getItentity = require('./utils/get-identity')

module.exports = deprecate

Expand All @@ -14,7 +14,7 @@ deprecate.usage = 'npm deprecate <pkg>[@<version>] <message>'
deprecate.completion = function (opts, cb) {
return Promise.resolve().then(() => {
if (opts.conf.argv.remain.length > 2) { return }
return whoami([], true, () => {}).then(username => {
return getItentity(npm.flatOptions).then(username => {
if (username) {
// first, get a list of remote packages this user owns.
// once we have a user account, then don't complete anything.
Expand Down
4 changes: 2 additions & 2 deletions lib/owner.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const { promisify } = require('util')
const { packument } = require('pacote')
const readLocalPkg = promisify(require('./utils/read-local-package.js'))
const usage = require('./utils/usage')
const whoami = promisify(require('./whoami.js'))
const getIdentity = require('./utils/get-identity')

owner.usage = usage(
'owner',
Expand All @@ -30,7 +30,7 @@ owner.completion = function (opts, cb) {
}
Promise.resolve().then(() => {
const opts = npm.flatOptions
return whoami([], true).then(username => {
return getIdentity(opts).then(username => {
const un = encodeURIComponent(username)
let byUser, theUser
switch (argv[2]) {
Expand Down
6 changes: 3 additions & 3 deletions lib/star.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const npa = require('npm-package-arg')
const npm = require('./npm.js')
const output = require('./utils/output.js')
const usage = require('./utils/usage.js')
const whoami = require('./whoami.js')
const getItentity = require('./utils/get-identity')

star.usage = usage(
'star',
Expand All @@ -31,7 +31,7 @@ function star (args, cb) {
if (!using) s = u
return Promise.all(args.map(npa).map(pkg => {
return Promise.all([
whoami([pkg], true, () => {}),
getItentity(opts),
fetch.json(pkg.escapedName, {
...opts,
spec: pkg,
Expand All @@ -56,7 +56,7 @@ function star (args, cb) {
log.verbose('star', 'unstarring', body)
}
return fetch.json(pkg.escapedName, {
...opts
...opts,
spec: pkg,
method: 'PUT',
body
Expand Down
31 changes: 15 additions & 16 deletions lib/stars.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,29 @@ const npm = require('./npm.js')
const fetch = require('npm-registry-fetch')
const log = require('npmlog')
const output = require('./utils/output.js')
const whoami = require('./whoami.js')
const getItentity = require('./utils/get-identity')

stars.usage = 'npm stars [<user>]'

const getUser = user => user ? Promise.resolve(user)
: whoami([], true, () => {})
const getUser = (opts, user) => user
? Promise.resolve(user)
: getItentity(opts)

module.exports = stars
function stars ([user], cb) {
const opts = npm.flatOptions
return Promise.resolve().then(() => {
return getUser(user).then(usr => {
return fetch.json('/-/_view/starredByUser', {
...opts,
// Note: key has to be JSON, for CouchDB legacy reasons, hence quoted
query: {key: `"${usr}"`}
})
}).then(data => data.rows).then(stars => {
if (stars.length === 0) {
log.warn('stars', 'user has not starred any packages.')
} else {
stars.forEach(s => output(s.value))
}
return getUser(opts, user).then(usr => {
return fetch.json('/-/_view/starredByUser', {
...opts,
// Note: key has to be JSON, for CouchDB legacy reasons, hence quoted
query: {key: `"${usr}"`}
})
}).then(data => data.rows).then(stars => {
if (stars.length === 0) {
log.warn('stars', 'user has not starred any packages.')
} else {
stars.forEach(s => output(s.value))
}
}).catch(err => {
if (err.code === 'ENEEDAUTH') {
throw Object.assign(new Error("'npm stars' on your own user account requires auth"), {
Expand Down
43 changes: 43 additions & 0 deletions lib/utils/get-identity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict'

const npmFetch = require('npm-registry-fetch')
const npm = require('../npm')

const needsAuthError = (msg) =>
Object.assign(new Error(msg, { code: 'ENEEDAUTH' }))

module.exports = async (opts = {}, spec = null) => {
const { registry } = opts
if (!registry) {
throw new Error('no default registry set')
}

// First, check if we have a user/pass-based auth
const creds = npm.config.getCredentialsByURI(registry)
const { username: usernameFromURI, token } = creds

if (usernameFromURI) {
// Found username; return it
return Promise.resolve(usernameFromURI)
} else if (token) {
// No username, but we have a token; fetch the username from registry
const registryData = await npmFetch.json('/-/whoami', {
...opts,
spec
})
const { username: usernameFromRegistry } = registryData
// Retrieved username from registry; return it
if (usernameFromRegistry) {
return Promise.resolve(usernameFromRegistry)
} else {
// Didn't get username from registry; bad token
throw needsAuthError(
'Your auth token is no longer valid. Please login again.'
)
}
} else {
// At this point, if they have a credentials object, it doesn't have a
// token or auth in it. Probably just the default registry.
throw needsAuthError('This command requires you to be logged in.')
}
}
36 changes: 3 additions & 33 deletions lib/whoami.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict'

const fetch = require('npm-registry-fetch')
const npm = require('./npm.js')
const output = require('./utils/output.js')
const getIdentity = require('./utils/get-identity')

module.exports = whoami

Expand All @@ -15,41 +15,11 @@ function whoami ([spec], silent, cb) {
silent = false
}
const opts = npm.flatOptions
return Promise.resolve().then(() => {
// First, check if we have a user/pass-based auth
const registry = opts.registry
if (!registry) throw new Error('no default registry set')
return npm.config.getCredentialsByURI(registry)
}).then(({username, token}) => {
if (username) {
return username
} else if (token) {
return fetch.json('/-/whoami', {
...opts,
spec
}).then(({username}) => {
if (username) {
return username
} else {
throw Object.assign(new Error(
'Your auth token is no longer valid. Please log in again.'
), {code: 'ENEEDAUTH'})
}
})
} else {
// At this point, if they have a credentials object, it doesn't have a
// token or auth in it. Probably just the default registry.
throw Object.assign(new Error(
'This command requires you to be logged in.'
), {code: 'ENEEDAUTH'})
}
}).then(username => {
if (silent) {
} else if (opts.json) {
getIdentity(opts, spec).then(username => {
if (silent) {} else if (opts.json) {
output(JSON.stringify(username))
} else {
output(username)
}
return username
}).then(() => cb(), cb)
}

0 comments on commit 924d85b

Please sign in to comment.