Skip to content
This repository has been archived by the owner on Nov 3, 2022. It is now read-only.

load non-scoped auth configs, scoped to default registry #16

Merged
merged 3 commits into from
Apr 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 53 additions & 39 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,6 @@ class Config {
throw new Error('call config.load() before setting values')
if (!confTypes.has(where))
throw new Error('invalid config location param: ' + where)
if (key === '_auth') {
const { email } = this.getCredentialsByURI(this.get('registry'))
if (!email)
throw new Error('Cannot set _auth without first setting email')
}
this[_checkDeprecated](key)
const { data } = this.data.get(where)
data[key] = val
Expand Down Expand Up @@ -282,6 +277,14 @@ class Config {
// symbols, as that module also does a bunch of get operations
this[_loaded] = true

process.emit('time', 'config:load:credentials')
const reg = this.get('registry')
const creds = this.getCredentialsByURI(reg)
// ignore this error because a failed set will strip out anything that
// might be a security hazard, which was the intention.
try { this.setCredentialsByURI(reg, creds) } catch (_) {}
process.emit('timeEnd', 'config:load:credentials')

// set proper globalPrefix now that everything is loaded
this.globalPrefix = this.get('prefix')

Expand Down Expand Up @@ -588,64 +591,71 @@ class Config {
const nerfed = nerfDart(uri)
const def = nerfDart(this.get('registry'))
if (def === nerfed) {
// do not delete email, that shouldn't be nerfed any more.
// just delete the nerfed copy, if one exists.
this.delete(`-authtoken`, 'user')
this.delete(`_authToken`, 'user')
this.delete(`_authtoken`, 'user')
this.delete(`_auth`, 'user')
this.delete(`_password`, 'user')
this.delete(`username`, 'user')
this.delete(`email`, 'user')
}
this.delete(`${nerfed}:-authtoken`, 'user')
this.delete(`${nerfed}:_authtoken`, 'user')
this.delete(`${nerfed}:_authToken`, 'user')
this.delete(`${nerfed}:_auth`, 'user')
this.delete(`${nerfed}:_password`, 'user')
this.delete(`${nerfed}:username`, 'user')
this.delete(`${nerfed}:email`, 'user')
}

setCredentialsByURI (uri, { token, username, password, email, alwaysAuth }) {
setCredentialsByURI (uri, { token, username, password, email }) {
const nerfed = nerfDart(uri)
const def = nerfDart(this.get('registry'))

if (def === nerfed) {
// remove old style auth info not limited to a single registry
this.delete('_password', 'user')
this.delete('username', 'user')
this.delete('email', 'user')
this.delete('_auth', 'user')
this.delete('_authtoken', 'user')
this.delete('-authtoken', 'user')
this.delete('_authToken', 'user')
}

this.delete(`${nerfed}:-authtoken`)
// email used to be nerfed always. if we're using the default
// registry, de-nerf it.
if (nerfed === def) {
email = email ||
this.get('email', 'user') ||
this.get(`${nerfed}:email`, 'user')
if (email)
this.set('email', email, 'user')
}

// field that hasn't been used as documented for a LONG time,
// and as of npm 7.10.0, isn't used at all. We just always
// send auth if we have it, only to the URIs under the nerf dart.
this.delete(`${nerfed}:always-auth`, 'user')

this.delete(`${nerfed}:-authtoken`, 'user')
this.delete(`${nerfed}:_authtoken`, 'user')
this.delete(`${nerfed}:email`, 'user')
if (token) {
this.set(`${nerfed}:_authToken`, token, 'user')
this.delete(`${nerfed}:_password`, 'user')
this.delete(`${nerfed}:username`, 'user')
this.delete(`${nerfed}:email`, 'user')
this.delete(`${nerfed}:always-auth`, 'user')
} else if (username || password || email) {
if (username || password) {
if (!username)
throw new Error('must include username')
if (!password)
throw new Error('must include password')
}
if (!email)
throw new Error('must include email')
} else if (username || password) {
if (!username)
throw new Error('must include username')
if (!password)
throw new Error('must include password')
this.delete(`${nerfed}:_authToken`, 'user')
if (username || password) {
this.set(`${nerfed}:username`, username, 'user')
// note: not encrypted, no idea why we bothered to do this, but oh well
// protects against shoulder-hacks if password is memorable, I guess?
const encoded = Buffer.from(password, 'utf8').toString('base64')
this.set(`${nerfed}:_password`, encoded, 'user')
}
this.set(`${nerfed}:email`, email, 'user')
if (alwaysAuth !== undefined)
this.set(`${nerfed}:always-auth`, alwaysAuth, 'user')
else
this.delete(`${nerfed}:always-auth`, 'user')
this.set(`${nerfed}:username`, username, 'user')
// note: not encrypted, no idea why we bothered to do this, but oh well
// protects against shoulder-hacks if password is memorable, I guess?
const encoded = Buffer.from(password, 'utf8').toString('base64')
this.set(`${nerfed}:_password`, encoded, 'user')
} else {
throw new Error('No credentials to set.')
}
Expand All @@ -656,18 +666,12 @@ class Config {
const nerfed = nerfDart(uri)
const creds = {}

// you can set always-auth for a single registry, or as a default
const alwaysAuthReg = this.get(`${nerfed}:always-auth`)
if (alwaysAuthReg !== undefined)
creds.alwaysAuth = !!alwaysAuthReg
else
creds.alwaysAuth = this.get('always-auth')

const email = this.get(`${nerfed}:email`) || this.get('email')
if (email)
creds.email = email

const tokenReg = this.get(`${nerfed}:_authToken`) ||
this.get(`${nerfed}:_authtoken`) ||
this.get(`${nerfed}:-authtoken`) ||
nerfed === nerfDart(this.get('registry')) && this.get('_authToken')

Expand All @@ -686,6 +690,16 @@ class Config {
return creds
}

const authReg = this.get(`${nerfed}:_auth`)
if (authReg) {
const authDecode = Buffer.from(authReg, 'base64').toString('utf8')
const authSplit = authDecode.split(':')
creds.username = authSplit.shift()
creds.password = authSplit.join(':')
creds.auth = authReg
return creds
}

// at this point, we can only use the values if the URI is the
// default registry.
const defaultNerf = nerfDart(this.get('registry'))
Expand Down
Loading